@rizom/brain 0.2.0-alpha.125 → 0.2.0-alpha.127
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/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/site.js +4 -4
- package/dist/site.js.map +1 -1
- package/package.json +1 -1
package/dist/brain.js
CHANGED
|
@@ -509,7 +509,7 @@ Some entity actions are gated by policy beyond simple tool availability. Two cas
|
|
|
509
509
|
- Use markdown sparingly for simple responses.
|
|
510
510
|
- If you don't know something, say so concisely.
|
|
511
511
|
- Do not add unsolicited closing offers unless the user asked for next steps.`}function pZA(A,Q,B,w){return async($)=>{if(w){let f={toolName:A,args:$,conversationId:B.conversationId,interfaceType:B.interfaceType,...B.channelId!==void 0&&{channelId:B.channelId},...B.channelName!==void 0&&{channelName:B.channelName}};await w.emit("tool:invoking",f)}try{let f=await Q($);if(w){let I={toolName:A,conversationId:B.conversationId,interfaceType:B.interfaceType,...B.channelId!==void 0&&{channelId:B.channelId},...B.channelName!==void 0&&{channelName:B.channelName}};await w.emit("tool:completed",I)}return f}catch(f){if(w){let I={toolName:A,error:y0(f),conversationId:B.conversationId,interfaceType:B.interfaceType,...B.channelId!==void 0&&{channelId:B.channelId},...B.channelName!==void 0&&{channelName:B.channelName}};await w.emit("tool:failed",I)}throw f}}}function iZA(A,Q="brain-agent"){return{emit:async(B,w)=>{await A.send({type:B,payload:w,sender:Q,broadcast:!0}).catch(()=>{return})}}}var Ot=p(()=>{WA()});function I52(A,Q={}){return Object.fromEntries(Object.entries(A).filter(([B])=>{if(w52.has(B))return!1;if(Q.toolName!=="system_create")return!0;if(!$52.has(B))return!0;if(B==="upload")return Q.enableCreateUpload===!0;if(B==="transform")return Q.enableCreateTransform===!0;return Q.enableCreateSourceAttachment===!0}))}function D52(A){let Q=f52.safeParse(A);if(!Q.success)return{type:"json",value:nY0(A)};let{attachment:B}=Q.data.data,w={mediaType:B.mediaType,...B.filename!==void 0?{filename:B.filename}:{},...B.sizeBytes!==void 0?{sizeBytes:B.sizeBytes}:{},...B.source!==void 0?{source:B.source}:{}};return{type:"json",value:nY0({...Q.data,data:{...Q.data.data,attachment:w,artifactCard:{rendered:!0,message:"The UI has rendered this artifact as an attachment card with Open and Download controls. Do not print raw attachment URLs in the assistant response."}}})}}function nY0(A){if(A===void 0)return null;return rZA.parse(JSON.parse(JSON.stringify(A)))}function dZA(A,Q,B){let w={};for(let $ of A){let f=pZA($.name,async(I)=>{let D={interfaceType:Q.interfaceType,userId:"agent-user",conversationId:Q.conversationId,channelId:Q.channelId??Q.conversationId,...Q.channelName&&{channelName:Q.channelName},...Q.userPermissionLevel&&{userPermissionLevel:Q.userPermissionLevel}};return $.handler(I,D)},Q,B);w[$.name]=QKA({description:$.description,inputSchema:H.object(I52($.inputSchema,{toolName:$.name,...Q.enableCreateUpload!==void 0&&{enableCreateUpload:Q.enableCreateUpload},...Q.enableCreateTransform!==void 0&&{enableCreateTransform:Q.enableCreateTransform},...Q.enableCreateSourceAttachment!==void 0&&{enableCreateSourceAttachment:Q.enableCreateSourceAttachment}})),execute:f,toModelOutput:({output:I})=>D52(I)})}return w}var w52,$52,rZA,f52;var oY0=p(()=>{Mb();WA();Ot();w52=new Set(["confirmed","confirmationToken","contentHash"]),$52=new Set(["upload","transform","sourceAttachment"]),rZA=H.lazy(()=>H.union([H.null(),H.string(),H.number(),H.boolean(),H.array(rZA),H.record(rZA)])),f52=H.object({success:H.literal(!0),data:H.object({documentId:H.string().min(1).optional(),entityId:H.string().min(1).optional(),attachment:H.object({mediaType:H.string().min(1),url:H.string().min(1),downloadUrl:H.string().min(1).optional(),previewUrl:H.string().min(1).optional(),filename:H.string().min(1).optional(),sizeBytes:H.number().nonnegative().optional(),source:H.object({entityType:H.string().optional(),entityId:H.string().optional(),attachmentType:H.string().optional()}).optional()}).passthrough()}).passthrough()}).passthrough()});function nZA(A){let{model:Q,modelId:B,webSearch:w,temperature:$,maxTokens:f,messageBus:I}=A,D=cf0(B),U=iZA(I);return function(J){let X=dZA(J.tools,{conversationId:"",interfaceType:"agent"},U);return new Tf0({model:Q,callOptionsSchema:U52,prepareCall:({options:G,...Z})=>{let N=J.getToolsForPermission(G.userPermissionLevel).filter((M)=>!(G.disableDocumentGenerate===!0&&M.name==="document_generate")&&!(G.disableSystemCreate===!0&&M.name==="system_create")&&!(G.enableUploadSave!==!0&&M.name==="system_upload_save")),V=N.map((M)=>M.name),L=dZA(N,{conversationId:G.conversationId,channelId:G.channelId,channelName:G.channelName,interfaceType:G.interfaceType,userPermissionLevel:G.userPermissionLevel,enableCreateUpload:G.enableCreateUpload,enableCreateTransform:G.enableCreateTransform,enableCreateSourceAttachment:G.enableCreateSourceAttachment},U);return{...Z,instructions:dY0(J.identity,G.userPermissionLevel,J.pluginInstructions,J.profile,J.agentInstructions,G.agentContextInstructions),tools:L,activeTools:V,...$!==void 0&&D&&{temperature:$},...f!==void 0&&{maxTokens:f},...w&&{providerOptions:{anthropic:{webSearch:!0}}}}},tools:X,stopWhen:Bg(J.stepLimit??10)})}}var U52;var sY0=p(()=>{Mb();WA();Ob();Ot();oY0();U52=H.object({userPermissionLevel:H.enum(["anchor","trusted","public"]),conversationId:H.string(),channelId:H.string().optional(),channelName:H.string().optional(),interfaceType:H.string(),agentContextInstructions:H.string().optional(),enableCreateUpload:H.boolean().optional(),enableCreateTransform:H.boolean().optional(),enableCreateSourceAttachment:H.boolean().optional(),enableUploadSave:H.boolean().optional(),disableDocumentGenerate:H.boolean().optional(),disableSystemCreate:H.boolean().optional()})});var Rt=p(()=>{OU0();Ob();RU0();rY0();cZA();sY0();Ot()});function eY0(A){return{...A,...A.source!==void 0&&{source:aY0(A.source)},...A.target!==void 0&&{target:aY0(A.target)}}}function aY0(A){if(A instanceof RegExp)return A;if(!A.includes("*"))return A;let Q=A.split("*").map((B)=>B.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${Q}$`)}function AJ0(A,Q){if(!Q)return!0;if(!tY0(A.source,Q.source))return!1;if(!tY0(A.target,Q.target,!0))return!1;if(!Y52(A.metadata,Q.metadata))return!1;return Q.predicate?Q.predicate(A):!0}function tY0(A,Q,B=!1){if(!Q)return!0;if(B&&!A)return!1;return J52(A,Q)}function Y52(A,Q){if(!Q)return!0;if(!A)return!1;return Object.entries(Q).every(([B,w])=>A[B]===w)}function J52(A,Q){if(!A)return!1;if(Q instanceof RegExp){Q.lastIndex=0;let B=Q.test(A);return Q.lastIndex=0,B}return A===Q}var bt,QJ0;var oZA=p(()=>{WA();bt=H.object({success:H.boolean(),data:H.unknown().optional(),error:H.string().optional()}),QJ0=H.object({id:H.string().min(1),timestamp:H.string(),type:H.string().min(1),source:H.string().min(1),target:H.string().optional(),metadata:H.record(H.string(),H.unknown()).optional()})});function BJ0(A){let Q=X52.safeParse(A);if(!Q.success)throw Error("Invalid message response format");return Q.data}var X52;var wJ0=p(()=>{WA();oZA();X52=H.union([H.object({noop:H.literal(!0)}),bt])});function fJ0(A,Q,B,w,$){return{id:UJ0("msg"),type:A,timestamp:YJ0(),source:B,target:w,metadata:$,payload:Q}}function IJ0(A,Q){let B=BJ0(Q);if("noop"in B)return $J0(A,!0);return $J0(A,B.success,B.data,B.error)}function DJ0(A,Q){if(Q?.success)return{success:!0,data:Q.data};return{success:!1,error:Q?.error?.message??`No handler found for message type: ${A}`}}function $J0(A,Q,B,w){return{id:UJ0("resp"),requestId:A,timestamp:YJ0(),success:Q,data:B,error:w?{message:w}:void 0}}function UJ0(A){return`${A}-${Date.now()}-${Math.random().toString(36).slice(2,11)}`}function YJ0(){return new Date().toISOString()}var sZA=p(()=>{wJ0()});class aZA{handlers=new Map;add(A,Q,B){let w=this.createHandlerEntry(Q,B);return this.getOrCreateHandlers(A).add(w),w}remove(A,Q){let B=this.handlers.get(A);if(!B)return!1;let w=B.delete(Q);return this.deleteEmptyHandlerSet(A,B),w}removeHandler(A,Q){let B=this.handlers.get(A);if(!B)return;for(let w of Array.from(B))if(w.originalHandler===Q)B.delete(w);this.deleteEmptyHandlerSet(A,B)}getMatchingHandlers(A,Q){let B=this.handlers.get(A);if(!B||B.size===0)return;return{entries:Array.from(B).filter((w)=>AJ0(Q,w.filter)),totalHandlers:B.size}}hasHandlers(A){let Q=this.handlers.get(A);return Q!==void 0&&Q.size>0}clearHandlers(A){return this.handlers.delete(A)}clearAllHandlers(){this.handlers.clear()}getHandlerCount(A){return this.handlers.get(A)?.size??0}getTargetedHandlerCount(A,Q){let B=this.handlers.get(A);if(!B)return 0;return Array.from(B).filter((w)=>w.filter?.target===Q).length}createHandlerEntry(A,Q){let B={handler:this.wrapHandler(A),originalHandler:A};return Q?{...B,filter:eY0(Q)}:B}wrapHandler(A){return async(Q)=>{let w=await A(Q);return IJ0(Q.id,w)}}getOrCreateHandlers(A){let Q=this.handlers.get(A);if(!Q)Q=new Set,this.handlers.set(A,Q);return Q}deleteEmptyHandlerSet(A,Q){if(Q.size===0)this.handlers.delete(A)}}var JJ0=p(()=>{sZA()});async function XJ0(A,Q,B){for(let w of Q)await HJ0(w,A,B);return null}async function WJ0(A,Q,B){for(let w of Q){let $=await HJ0(w,A,B);if($)return $}return null}async function HJ0(A,Q,B){try{return await A.handler(Q)}catch(w){return B.error(`Error in message handler for ${Q.type}`,w),null}}class tZA{registry;logger;constructor(A,Q){this.registry=A;this.logger=Q}async publish(A,Q){if(typeof A!=="object"||!A.type||!A.id)return this.logger.error("Invalid message structure - missing required fields 'id' or 'type'"),null;let{type:B}=A;this.logger.debug(`Publishing message of type: ${B}`,{source:A.source,target:A.target,hasMetadata:!!A.metadata});let w=this.registry.getMatchingHandlers(B,A);if(!w)return this.logger.debug(`No handlers found for message type: ${B}`),null;if(w.entries.length===0)return this.logger.debug(`No matching handlers for message type: ${B}`,{totalHandlers:w.totalHandlers,target:A.target}),null;return Q===!0?XJ0(A,w.entries,this.logger):WJ0(A,w.entries,this.logger)}}var GJ0=()=>{};function KJ0(A,Q){try{return{valid:!0,data:Q.parse(A)}}catch(B){if(B instanceof H.ZodError)return{valid:!1,error:B.issues[0]?.message??"Validation failed"};return{valid:!1,error:"Unknown validation error"}}}var FJ0=p(()=>{WA()});class YJ{static instance=null;registry=new aZA;publisher;logger;static getInstance(A){return YJ.instance??=new YJ(A),YJ.instance}static resetInstance(){YJ.instance=null}static createFresh(A){return new YJ(A)}constructor(A){this.logger=A,this.publisher=new tZA(this.registry,A)}subscribe(A,Q,B){let w=this.registry.add(A,Q,B);return this.logger.debug(`Registered handler for message type: ${A}`,{hasFilter:!!B,filterTarget:B?.target}),()=>{this.registry.remove(A,w)}}async send(A){let{type:Q,payload:B,sender:w,target:$,metadata:f,broadcast:I}=A,D=fJ0(Q,B,w,$,f),U=await this.publisher.publish(D,I);return DJ0(Q,U)}validateMessage(A,Q){return KJ0(A,Q)}hasHandlers(A){return this.registry.hasHandlers(A)}unsubscribe(A,Q){this.registry.removeHandler(A,Q)}clearHandlers(A){if(this.registry.clearHandlers(A))this.logger.info(`Cleared all handlers for message type: ${A}`)}clearAllHandlers(){this.registry.clearAllHandlers(),this.logger.info("Cleared all message handlers")}getHandlerCount(A){return this.registry.getHandlerCount(A)}getTargetedHandlerCount(A,Q){return this.registry.getTargetedHandlerCount(A,Q)}}var ZJ0=p(()=>{JJ0();sZA();GJ0();FJ0()});var H52;var NJ0=p(()=>{WA();oZA();H52=H.object({id:H.string().min(1),requestId:H.string().min(1),success:H.boolean(),data:H.unknown().optional(),error:H.object({message:H.string(),code:H.string().optional()}).optional(),timestamp:H.string().datetime()})});var eZA=p(()=>{ZJ0();NJ0()});var t8;var ANA=p(()=>{LN();t8=DU("runtime_state_records",{namespace:HQ("namespace").notNull(),key:HQ("key").notNull(),value:HQ("value",{mode:"json"}).notNull(),createdAt:o$("created_at").notNull(),updatedAt:o$("updated_at").notNull()},(A)=>({pk:PR({columns:[A.namespace,A.key]}),namespaceUpdatedAtIdx:OI("idx_runtime_state_namespace_updated_at").on(A.namespace,A.updatedAt)}))});import{createClient as zJ0}from"@libsql/client";function Pt(A){let Q=A.url,B=A.authToken??process.env.RUNTIME_STATE_DATABASE_AUTH_TOKEN,w=B?zJ0({url:Q,authToken:B}):zJ0({url:Q});return{db:UU(w,{schema:{runtimeStateRecords:t8}}),client:w,url:Q}}async function kt(A,Q){if(Q.startsWith("file:"))await A.execute("PRAGMA journal_mode = WAL"),await A.execute("PRAGMA busy_timeout = 5000")}var QNA=p(()=>{TR();ANA()});class jt{db;namespace;schema;now;constructor(A,Q,B,w=()=>new Date){this.db=A;this.namespace=Q;this.schema=B;this.now=w;K52(Q)}async get(A){let Q=Fg(A),w=(await this.db.select().from(t8).where(Mw(M2(t8.namespace,this.namespace),M2(t8.key,Q))).limit(1))[0];if(!w)return null;return this.schema.parse(w.value)}async has(A){let Q=Fg(A);return(await this.db.select({key:t8.key}).from(t8).where(Mw(M2(t8.namespace,this.namespace),M2(t8.key,Q))).limit(1)).length>0}async set(A,Q){let B=Fg(A),w=this.schema.parse(Q),$=this.now().getTime();await this.db.insert(t8).values({namespace:this.namespace,key:B,value:w,createdAt:$,updatedAt:$}).onConflictDoUpdate({target:[t8.namespace,t8.key],set:{value:w,updatedAt:$}})}async setIfNotExists(A,Q){let B=Fg(A),w=this.schema.parse(Q),$=this.now().getTime(),f=await this.db.insert(t8).values({namespace:this.namespace,key:B,value:w,createdAt:$,updatedAt:$}).onConflictDoNothing({target:[t8.namespace,t8.key]});return Number(f.rowsAffected)>0}async delete(A){let Q=Fg(A),B=await this.db.delete(t8).where(Mw(M2(t8.namespace,this.namespace),M2(t8.key,Q)));return Number(B.rowsAffected)>0}async list(A={}){let Q=await this.listRows(),B=A.keyPrefix;if(B!==void 0)qJ0(B);return Q.filter((w)=>B===void 0||w.key.startsWith(B)).map((w)=>({key:w.key,value:this.schema.parse(w.value),createdAt:new Date(w.createdAt),updatedAt:new Date(w.updatedAt)}))}async clear(A={}){let Q=A.keyPrefix;if(Q===void 0){let w=await this.db.delete(t8).where(M2(t8.namespace,this.namespace));return Number(w.rowsAffected)}qJ0(Q);let B=await this.list({keyPrefix:Q});return await Promise.all(B.map((w)=>this.delete(w.key))),B.length}async listRows(){return this.db.select().from(t8).where(M2(t8.namespace,this.namespace))}}function K52(A){if(!G52.test(A))throw Error(`Invalid runtime state namespace: ${A}. Use 1-128 alphanumeric, _, ., :, or - characters.`)}function Fg(A){if(A.length===0||A.length>LJ0)throw Error("Runtime state keys must be 1-512 characters long");return A}function qJ0(A){if(A.length>LJ0)throw Error("Runtime state key prefixes must be 512 characters or shorter");return A}var G52,LJ0=512;var BNA=p(()=>{nG();ANA();G52=/^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,127}$/});class NU{static instance=null;db;client;logger;static getInstance(A,Q){return NU.instance??=new NU(A,Q??d2.getInstance()),NU.instance}static createFresh(A,Q){return new NU(A,Q??d2.getInstance())}static resetInstance(){NU.instance?.close(),NU.instance=null}constructor(A,Q){let{db:B,client:w,url:$}=Pt(A);this.db=B,this.client=w,this.logger=Q.child("RuntimeStateService"),kt(w,$).catch((f)=>{this.logger.warn("Failed to enable runtime state WAL mode (non-fatal)",f)})}scoped(A){return new jt(this.db,A.namespace,A.schema)}close(){this.client.close()}}var VJ0=p(()=>{WA();QNA();BNA()});var wNA=p(()=>{VJ0();BNA()});async function EJ0(A,Q){if(A.status==="running"){Q.warn(`Daemon already running: ${A.name}`);return}A.status="starting",delete A.error;try{await A.daemon.start(),A.status="running",A.startedAt=new Date,Q.debug(`Daemon started successfully: ${A.name}`)}catch(B){throw A.status="error",A.error=QU(B),Q.warn(`Daemon ${A.name} failed to start: ${y0(B)}`),B}}async function MJ0(A,Q){if(A.status==="stopped"){Q.warn(`Daemon already stopped: ${A.name}`);return}A.status="stopping";try{await A.daemon.stop(),A.status="stopped",A.stoppedAt=new Date,Q.debug(`Daemon stopped successfully: ${A.name}`)}catch(B){throw A.status="error",A.error=QU(B),Q.error(`Failed to stop daemon: ${A.name}`,B),B}}async function CJ0(A){if(!A.daemon.healthCheck)return;try{let Q=await A.daemon.healthCheck();return A.health=Q,Q}catch(Q){let B={status:"error",message:y0(Q),lastCheck:new Date};return A.health=B,B}}function OJ0(A){return{name:A.name,pluginId:A.pluginId,status:A.status,health:A.health}}var RJ0=p(()=>{WA()});class NW{static instance=null;daemons=new Map;logger;static getInstance(A=d2.getInstance()){return NW.instance??=new NW(A),NW.instance}static resetInstance(){NW.instance=null}static createFresh(A){return new NW(A)}constructor(A){this.logger=A.child("DaemonRegistry")}register(A,Q,B){if(this.daemons.has(A))this.logger.warn(`Daemon already registered: ${A}, overwriting`);let w={name:A,daemon:Q,pluginId:B,status:"stopped"};this.daemons.set(A,w),this.logger.debug(`Registered daemon: ${A} from plugin: ${B}`)}has(A){return this.daemons.has(A)}get(A){return this.daemons.get(A)}async start(A){let Q=this.daemons.get(A);if(!Q)throw Error(`Daemon not registered: ${A}`);await EJ0(Q,this.logger)}async stop(A){let Q=this.daemons.get(A);if(!Q)throw Error(`Daemon not registered: ${A}`);await MJ0(Q,this.logger)}async checkHealth(A){let Q=this.daemons.get(A);if(!Q)throw Error(`Daemon not registered: ${A}`);return CJ0(Q)}getByPlugin(A){return Array.from(this.daemons.values()).filter((Q)=>Q.pluginId===A)}getAll(){return Array.from(this.daemons.keys())}getAllInfo(){return Array.from(this.daemons.values())}async getStatuses(){let A=this.getAllInfo();for(let Q of A)if(Q.daemon.healthCheck)await this.checkHealth(Q.name);return A.map(OJ0)}async unregister(A){let Q=this.daemons.get(A);if(!Q){this.logger.warn(`Daemon not registered: ${A}`);return}if(Q.status==="running")await this.stop(A);this.daemons.delete(A),this.logger.debug(`Unregistered daemon: ${A}`)}async startPlugin(A){let Q=this.getByPlugin(A);this.logger.debug(`Starting ${Q.length} daemons for plugin: ${A}`);let B;for(let w of Q)try{await this.start(w.name)}catch($){B??=QU($)}if(B)throw B}async stopPlugin(A){let Q=this.getByPlugin(A);this.logger.debug(`Stopping ${Q.length} daemons for plugin: ${A}`);for(let B of Q)try{await this.stop(B.name)}catch(w){this.logger.error(`Failed to stop daemon: ${B.name}`,w)}}async clear(){this.logger.debug("Clearing all daemons");let A=Array.from(this.daemons.values()).filter((Q)=>Q.status==="running");for(let Q of A)try{await this.stop(Q.name)}catch(B){this.logger.error(`Failed to stop daemon during clear: ${Q.name}`,B)}this.daemons.clear(),this.logger.debug("All daemons cleared")}}var $NA=p(()=>{WA();RJ0()});function fNA(A,Q,B,w,$){return["entity:created","entity:updated","entity:deleted"].map((I)=>A.subscribe(I,async(D)=>{if(D.payload.entityType===Q&&(B===null||D.payload.entityId===B)){await w();let U=I.replace("entity:","");$.debug(`${Q} entity ${U}, cache refreshed`)}return{success:!0}}))}async function F52(A,Q,B){let w=Z52(A.kind);if(!w)return null;try{let $=Q.scoped({namespace:w,refKind:A.kind,routePath:""});return N52(await $.read(A.id),A)}catch($){return B.debug("Skipped unavailable prior runtime upload",{uploadKind:A.kind,uploadId:A.id,error:$ instanceof Error?$.message:String($)}),null}}function Z52(A){return A==="upload"?"upload":null}function N52(A,Q){let{record:B,content:w}=A;if(z52(B.mediaType))return{kind:"text",filename:B.filename,mediaType:B.mediaType,content:new TextDecoder("utf-8").decode(w).replace(/^\uFEFF/,""),sizeBytes:B.sizeBytes,source:Q};return{kind:"file",filename:B.filename,mediaType:B.mediaType,data:new Uint8Array(w),sizeBytes:B.sizeBytes,source:Q}}function z52(A){let Q=A.toLowerCase();return Q.startsWith("text/")||Q==="application/json"}function bJ0(A){let{config:Q,entityService:B,logger:w,messageBus:$,aiService:f,mcpService:I,conversationService:D,runtimeUploadRegistry:U,disposables:Y}=A,J=WU.getInstance(B,w,Q.identity);Y.push(...fNA($,K4.BRAIN_CHARACTER,K4.BRAIN_CHARACTER,()=>J.refreshCache(),w));let X=G4.getInstance(B,w,Q.profile),G=QK.getInstance(w),Z=nZA({model:f.getModel(),modelId:f.getConfig().model,webSearch:f.getConfig().webSearch,temperature:f.getConfig().temperature,maxTokens:f.getConfig().maxTokens,messageBus:$}),N=mZA(Q.name),V=Zf.getInstance(I,D,J,X,w,{agentFactory:Z,canonicalIdentityResolver:G,uploadAttachmentResolver:(L)=>F52(L,U,w),agentContextProvider:async(L)=>{let M=await $.send({type:Ux,sender:"shell:agent-service",payload:L});if("noop"in M||!M.success)return[];return qDA(M.data)},...N?{assistantActorId:N}:{},...Q.agentInstructions&&{agentInstructions:Q.agentInstructions}});Y.push(...fNA($,K4.ANCHOR_PROFILE,K4.ANCHOR_PROFILE,()=>X.refreshCache(),w));for(let L of[K4.BRAIN_CHARACTER,K4.ANCHOR_PROFILE])Y.push(...fNA($,L,L,async()=>V.invalidateAgent(),w));return{identityService:J,profileService:X,canonicalIdentityService:G,agentService:V}}var PJ0=p(()=>{Rt();o8();BK();uL()});function kJ0(A){let{dependencies:Q,jobQueueService:B,messageBus:w,logger:$}=A,f=Q?.batchJobManager??iY.getInstance(B,$),I=Q?.jobProgressMonitor??rY.getInstance(B,w,f,$),D=Q?.jobQueueWorker??pY.getInstance(B,I,$,{pollInterval:100,concurrency:1,autoStart:!1});return{batchJobManager:f,jobProgressMonitor:I,jobQueueWorker:D}}var jJ0=p(()=>{oG()});function _J0(A,Q){if(Q)return Q;let B={debug:2,info:3,warn:4,error:5}[A.logging.level];return d2.createFresh({level:B,context:A.logging.context,format:A.logging.format==="json"?"json":"text",...A.logging.file?{logFile:A.logging.file}:{}})}function vJ0(A){return{apiKey:A.ai.apiKey,model:A.ai.model,temperature:A.ai.temperature,maxTokens:A.ai.maxTokens,webSearch:A.ai.webSearch,...A.ai.imageApiKey?{imageApiKey:A.ai.imageApiKey}:{}}}function rb(A){return{url:A.url,...A.authToken?{authToken:A.authToken}:{}}}var yJ0=p(()=>{WA()});function TJ0(A){let{config:Q,dependencies:B,initializerLogger:w}=A;w.debug("Initializing Shell services");let $=_J0(Q,B?.logger),f=[],I=B?.embeddingService??DJ.getInstance({apiKey:Q.ai.apiKey,logger:$}),D=B?.aiService??IJ.getInstance(vJ0(Q),$),U=bI.getInstance($),Y=B?.messageBus??YJ.getInstance($),J=B?.templateRegistry??BU.getInstance($),X=B?.dataSourceRegistry??dY.getInstance($),G=B?.renderService??gY.getInstance(J),Z=B?.daemonRegistry??NW.getInstance($),N=B?.pluginManager??HU.getInstance($,Z),V=B?.permissionService??new W$(Q.permissions,{spaces:Q.spaces}),L=B?.attachmentRegistry??nY.getInstance(),M=B?.runtimeUploadRegistry??cx.createFresh({dataDir:Q.dataDir}),O=B?.runtimeStateService??NU.createFresh(rb(Q.runtimeStateDatabase),$),E=B?.mcpService??wU.getInstance(Y,$),S=B?.jobQueueService??RI.getInstance(rb(Q.jobQueueDatabase),$),T=PI.getInstance({embeddingService:I,entityRegistry:U,logger:$,jobQueueService:S,messageBus:Y,dbConfig:rb(Q.database),embeddingDbConfig:rb(Q.embeddingDatabase)}),y=B?.conversationService??Uf.getInstance($,Y,rb(Q.conversationDatabase)),_=B?.contentService??new Rs({logger:$,entityService:T,aiService:D,templateRegistry:J,dataSourceRegistry:X}),{identityService:x,profileService:g,canonicalIdentityService:n,agentService:m}=bJ0({config:Q,entityService:T,entityRegistry:U,logger:$,messageBus:Y,aiService:D,mcpService:E,conversationService:y,runtimeUploadRegistry:M,disposables:f}),{batchJobManager:BA,jobProgressMonitor:a,jobQueueWorker:j}=kJ0({dependencies:B,jobQueueService:S,messageBus:Y,logger:$});return{logger:$,disposables:f,entityRegistry:U,messageBus:Y,renderService:G,daemonRegistry:Z,pluginManager:N,templateRegistry:J,dataSourceRegistry:X,mcpService:E,embeddingService:I,entityService:T,aiService:D,conversationService:y,contentService:_,jobQueueService:S,jobQueueWorker:j,batchJobManager:BA,jobProgressMonitor:a,permissionService:V,identityService:x,profileService:g,canonicalIdentityService:n,agentService:m,attachmentRegistry:L,runtimeUploadRegistry:M,runtimeStateService:O}}var xJ0=p(()=>{Rt();Ps();ux();J8();J8();oG();$f();eZA();aA();wNA();Xw();$NA();PJ0();jJ0();yJ0()});function SJ0(A,Q){A.register(ox.name,ox),Q.debug("Shell system templates registered")}function gJ0(A,Q){A.register(sR.BASE_ENTITY_DISPLAY,{name:"base-entity-display",description:"Display template for base entities",schema:A2,formatter:new Xs,requiredPermission:"public"}),Q.debug("Base entity display template registered")}function hJ0(A,Q){A.registerEntityType(K4.NOTE,A2,new hx),Q.debug("Fallback base entity adapter registered")}function mJ0(A,Q){let B=new rR;A.registerEntityType(K4.BRAIN_CHARACTER,B.schema,B),Q.debug("Brain character entity support registered")}function uJ0(A,Q){let B=new JW;A.registerEntityType(K4.ANCHOR_PROFILE,B.schema,B),Q.debug("Anchor profile entity support registered")}async function cJ0(A){let{plugins:Q,pluginManager:B,logger:w,initOptions:$}=A;w.debug(`Found ${Q.length} plugins to register`);for(let f of Q)w.debug(`Registering plugin: ${f.id}`),B.registerPlugin(f);if(await B.initializePlugins($?.registrationContext),!$?.registerOnly){for(let{id:f,error:I}of B.getFailedPlugins())if(B.getPlugin(f)?.requiresDaemonStartup?.())throw I}w.debug("Plugin initialization complete")}var lJ0=p(()=>{Ps();J8();BK();uL()});function pJ0(){PI.resetInstance(),bI.resetInstance(),dY.resetInstance(),DJ.resetInstance(),Uf.resetInstance(),HU.resetInstance(),wU.resetInstance(),YJ.resetInstance(),BU.resetInstance(),gY.resetInstance(),NW.resetInstance(),IJ.resetInstance(),Zf.resetInstance(),WU.resetInstance(),G4.resetInstance(),RI.resetInstance(),iY.resetInstance(),pY.resetInstance(),rY.resetInstance(),nY.resetInstance(),NU.resetInstance()}var iJ0=p(()=>{Rt();ux();J8();BK();oG();$f();eZA();aA();wNA();Xw();$NA()});class JJ{static instance=null;logger;config;static getInstance(A,Q){return JJ.instance??=new JJ(A,Q),JJ.instance}static resetInstance(){JJ.instance=null}static createFresh(A,Q){return new JJ(A,Q)}constructor(A,Q){this.logger=A.child("ShellInitializer"),this.config=Q}registerShellTemplates(A){SJ0(A,this.logger)}registerBaseEntityDisplayTemplate(A){gJ0(A,this.logger)}registerFallbackBaseEntity(A){hJ0(A,this.logger)}registerBrainCharacterSupport(A){mJ0(A,this.logger)}registerAnchorProfileSupport(A){uJ0(A,this.logger)}async initializePlugins(A,Q){await cJ0({plugins:this.config.plugins,pluginManager:A,logger:this.logger,initOptions:Q})}initializeServices(A){return TJ0({config:this.config,dependencies:A,initializerLogger:this.logger})}registerJobHandlers(A,Q,B){let w=wK.createFresh(Q,B);A.registerHandler("shell:content-generation",w,"shell")}wireShell(A,Q){A.pluginManager.setShell(Q)}async initializeAll(A,Q,B,w){this.logger.debug("Starting Shell initialization");try{if(this.registerShellTemplates(A),this.registerBaseEntityDisplayTemplate(A),this.registerBrainCharacterSupport(Q),this.registerAnchorProfileSupport(Q),await this.initializePlugins(B,w),!Q.hasEntityType(K4.NOTE))this.registerFallbackBaseEntity(Q);this.logger.debug("Shell registration phase complete")}catch($){throw this.logger.error("Shell initialization failed",$),$}}}function Zg(){JJ.resetInstance(),pJ0()}async function rJ0(){let{Shell:A}=await Promise.resolve().then(() => (INA(),dJ0));await A.resetInstance(),Zg()}var _t=p(()=>{Ps();uL();xJ0();lJ0();iJ0()});class DNA{config;services;hooks;constructor(A,Q,B){this.config=A;this.services=Q;this.hooks=B}async boot(A){this.services.logger.debug("Starting Shell boot");let Q=JJ.getInstance(this.services.logger,this.config);if(await this.services.entityService.initialize(),await Q.initializeAll(this.services.templateRegistry,this.services.entityRegistry,this.services.pluginManager,{...A?.mode==="register-only"&&{registerOnly:!0},...this.config.entityDisplay!==void 0&&{registrationContext:{entityDisplay:this.config.entityDisplay}}}),Q.registerJobHandlers(this.services.jobQueueService,this.services.contentService,this.services.entityService),this.hooks.registerCoreDataSources(),this.hooks.registerSystemCapabilities(),A?.mode==="register-only"){this.services.logger.debug("Shell boot complete (register-only mode)");return}if(A?.mode!=="startup-check")await this.startEarlyWebserver(),await this.emitPluginsRegistered();if(await this.prepareReadyState(),await this.services.pluginManager.readyPlugins(),A?.mode==="startup-check"){this.services.logger.debug("Shell boot complete (startup-check mode)");return}await this.startRuntimeServices(),this.services.logger.debug("Shell boot complete")}async startEarlyWebserver(){if(!this.services.daemonRegistry.has("webserver:webserver"))return;await this.services.daemonRegistry.start("webserver:webserver"),this.services.logger.debug("Started webserver before initial sync")}async emitPluginsRegistered(){await this.services.messageBus.send({type:mL.pluginsRegistered,payload:{timestamp:new Date().toISOString(),pluginCount:this.services.pluginManager.getAllPluginIds().length},sender:"shell",broadcast:!0}),this.services.logger.debug("Emitted plugins registered event")}async prepareReadyState(){await Promise.all([this.services.identityService.initialize(),this.services.profileService.initialize(),this.services.canonicalIdentityService.refreshCache()]),this.services.logger.debug("Identity services initialized");let A=await NYA(this.services.templateRegistry,this.services.entityService);if(A>0)this.services.logger.debug(`Materialized ${A} prompt entities`)}async startRuntimeServices(){await this.services.pluginManager.startPluginDaemons(),await this.services.jobQueueWorker.start(),this.services.jobProgressMonitor.start(),this.services.batchJobManager.start()}}var nJ0=p(()=>{aA();_t()});class oJ0{handlers=new Map;register(A,Q){this.handlers.set(A,Q)}getTypes(){return Array.from(this.handlers.keys())}async get(A,Q,B){let w=this.handlers.get(A);if(!w)throw Error(`Unknown insight type: ${A}. Available: ${this.getTypes().join(", ")}`);return w(Q,B)}}function sJ0(){let A=new oJ0;return A.register("overview",L52),A.register("publishing-cadence",V52),A.register("content-health",E52),A}async function L52(A,Q){let B=await A.getEntityCounts(Q),w={},$=0;for(let{entityType:Z,count:N}of B)w[Z]=N,$+=N;let f=await UNA(A,Q),I=Date.now(),D=I-604800000,U=I-2592000000,Y=0,J=0;for(let Z of f){let N=new Date(Z.created).getTime();if(N>=D)Y++;if(N>=U)J++}let X=aJ0(f),G=f.filter((Z)=>Z.metadata.status==="published");return{entityCounts:w,totalEntities:$,recentActivity:{last7days:Y,last30days:J},contentHealth:{drafts:X.length,published:G.length}}}async function V52(A,Q){let B=await UNA(A,Q),w=new Map;for(let f of B){let I=new Date(f.created);if(isNaN(I.getTime()))continue;let D=`${I.getUTCFullYear()}-${String(I.getUTCMonth()+1).padStart(2,"0")}`,U=w.get(D);if(!U)U={},w.set(D,U);U[f.entityType]=(U[f.entityType]??0)+1}return{months:Array.from(w.entries()).sort((f,I)=>I[0].localeCompare(f[0])).map(([f,I])=>{let D=0;for(let U of Object.values(I))D+=U;return{month:f,counts:I,total:D}})}}async function E52(A,Q){let B=await UNA(A,Q),w=aJ0(B).map((D)=>({id:D.id,entityType:D.entityType,title:typeof D.metadata.title==="string"?D.metadata.title:D.id,created:D.created})),$=Date.now(),f=$-7776000000,I=B.filter((D)=>{if(D.entityType==="image")return!1;let U=new Date(D.updated).getTime();return!isNaN(U)&&U<f}).map((D)=>({id:D.id,entityType:D.entityType,title:typeof D.metadata.title==="string"?D.metadata.title:D.id,updated:D.updated,daysSinceUpdate:Math.floor(($-new Date(D.updated).getTime())/86400000)}));return{drafts:w,stale:I}}function aJ0(A){return A.filter((Q)=>Q.metadata.status==="draft")}async function UNA(A,Q){let B=A.getEntityTypes(),w=[];for(let $ of B){let f=await A.listEntities({entityType:$,options:{limit:1000,filter:{visibilityScope:Q}}});w.push(...f)}return w}class Ng{parse;idOf;items=new Map;constructor(A,Q){this.parse=A;this.idOf=Q}register(A){let Q=this.parse(A);this.items.set(this.keyFor(Q.pluginId,this.idOf(Q)),Q)}unregister(A,Q){if(Q!==void 0){this.items.delete(this.keyFor(A,Q));return}let B=`${A}:`;for(let w of this.items.keys())if(w.startsWith(B))this.items.delete(w)}list(){return Array.from(this.items.values()).sort((A,Q)=>A.priority-Q.priority||A.label.localeCompare(Q.label))}keyFor(A,Q){return`${A}:${Q}`}}var YNA;var tJ0=p(()=>{aA();YNA=class YNA extends Ng{constructor(){super((A)=>LR.parse(A),(A)=>A.url)}}});var JNA;var eJ0=p(()=>{aA();JNA=class JNA extends Ng{constructor(){super((A)=>VR.parse(A),(A)=>A.id)}}});function AX0(A,Q){return{enqueueBatch:A.enqueueBatch.bind(A),getActiveBatches:A.getActiveBatches.bind(A),getBatchStatus:A.getBatchStatus.bind(A),getActiveJobs:Q.getActiveJobs.bind(Q),getStatus:Q.getStatus.bind(Q)}}function QX0(A){let Q=[];for(let[B,w]of A.getAllPlugins()){let{plugin:$}=w;if("getApiRoutes"in $&&typeof $.getApiRoutes==="function")for(let f of $.getApiRoutes())Q.push({pluginId:B,fullPath:`/api/${B}${f.path}`,definition:f})}return Q}function BX0(A){let Q=[];for(let[B,w]of A.getAllPlugins()){let{plugin:$}=w;if("getWebRoutes"in $&&typeof $.getWebRoutes==="function")for(let f of $.getWebRoutes())Q.push({pluginId:B,fullPath:f.path,definition:f})}return Q}async function wX0(A){A.batchJobManager.stop(),A.jobProgressMonitor.stop(),await A.jobQueueWorker.stop();for(let[Q]of A.pluginManager.getAllPlugins())await A.pluginManager.disablePlugin(Q);for(let Q of A.disposables.splice(0))try{Q()}catch(B){A.logger.warn("Failed to dispose shell subscription",B)}A.entityService.close(),A.jobQueueService.close(),A.conversationService.close(),A.runtimeStateService.close()}var $X0,fX0,IX0,M52,C52,DX0,UX0,YX0,JX0,XX0,WX0,HX0,GX0,KX0,FX0,ZX0,jZB,_ZB;var zW=p(()=>{J8();WA();$X0=H.object({query:H.string().describe("Search term"),entityType:H.string().optional().describe("Entity type to filter by"),limit:H.number().optional().describe("Maximum number of results"),includeUngenerated:H.boolean().optional().describe("Include queued/failed generation stubs in results")}),fX0=H.object({entityType:H.string().describe("Entity type"),id:H.string().describe("Entity ID, slug, or title")}),IX0=H.object({entityType:H.string().describe("Entity type to list"),status:H.string().optional().describe("Filter by status"),limit:H.number().optional().describe("Maximum number of results (default: 20)")}),M52=H.union([H.object({generate:H.literal(!0).describe("Set to true when the user asks for a cover image"),prompt:H.string().optional().describe("Prompt for cover image generation")}),H.literal(!0).describe("Set to true when the user asks for a cover image"),H.literal(!1).describe("Do not generate a cover image")]),C52=H.object({sourceEntityType:H.string().min(1).describe("Source entity type"),sourceEntityId:H.string().min(1).describe("Source entity ID"),attachmentType:H.string().min(1).describe("Source attachment type")}),DX0=H.object({kind:H.literal("upload").describe("Upload ref kind"),id:H.string().min(1).describe("Upload ID")}),UX0=H.object({upload:DX0.describe('Exact upload ref to save, copied from the current message or conversation upload refs hint, e.g. { kind: "upload", id: "upload-..." }.'),title:H.string().optional().describe("Optional title for the saved file"),confirmed:H.literal(!0).optional().describe("Confirm the upload save"),confirmationToken:H.string().optional().describe("Internal confirmation token returned by the confirmation flow")}),YX0=H.object({entityType:H.string().describe("Entity type to create. Do not use system_create for status-only requests such as making an existing post a draft; use system_update instead."),title:H.string().optional().describe("Title for a new entity. Do not invent placeholder titles like 'Draft Post' unless the user explicitly asked to create a new post."),prompt:H.string().optional().describe("Prompt for AI generation of a new entity. Do not use for finalized/exact/as-written content, and do not use for status changes like 'make one draft' or 'change it to draft'."),content:H.string().optional().describe("Direct content to store. Use this for finalized/exact/as-written user-provided markdown, including deck markdown with frontmatter and slide separators; omit prompt in those cases."),url:H.string().optional().describe("URL or domain for URL-first create flows such as saving a link or remote agent"),upload:DX0.optional().describe('Use only with transform: "extract-markdown" to turn an uploaded text, JSON, markdown, or PDF file into a note. For raw uploaded file preservation use system_upload_save instead. Omit for ordinary direct creates that use content, prompt, url, or sourceAttachment. Never combine upload with sourceAttachment.'),transform:H.string().optional().describe('Optional upload transform. Set to exactly "extract-markdown" only with upload and entityType note to extract markdown/text from an uploaded text or PDF file into a markdown note. Omit for raw file promotion to document/image; never include transform with entityType document or image.'),sourceAttachment:C52.optional().describe("Create from a source-derived entity artifact such as a deck carousel or post printable PDF. Use this instead of upload when the requested source is an existing entity artifact. Omit upload when using sourceAttachment. Omit for ordinary direct creates that use content, prompt, or url."),replace:H.boolean().optional().describe("Force regeneration instead of reusing a deterministic artifact"),targetEntityType:H.string().optional().describe("Existing entity type to attach to after creation. Use only when the user explicitly asks to set/replace a cover or attach the artifact to an existing entity; omit for standalone image/document generation."),targetEntityId:H.string().optional().describe("Existing entity ID to attach to after creation. Use only with targetEntityType; omit for standalone image/document generation."),coverImage:M52.optional().describe("For creating a new entity with a cover image in the same request. Use { generate: true, prompt } or true. Do not make a separate image create call for the new entity."),confirmed:H.literal(!0).optional().describe("Confirm the creation"),confirmationToken:H.string().optional().describe("Internal confirmation token returned by the confirmation flow")}),JX0=H.object({entityType:H.string().describe("Entity type"),id:H.string().describe("Entity ID"),fields:H.record(H.unknown()).optional().describe("Partial frontmatter fields to update. Use this for status, title, and metadata changes such as approving an agent."),content:H.string().optional().describe("Full markdown content replacement only. Do not use this for status/title/frontmatter updates; use fields instead."),confirmed:H.literal(!0).optional().describe("Confirm the update"),contentHash:H.string().optional().describe("Content hash for optimistic concurrency")}),XX0=H.object({entityType:H.string().describe("Entity type"),id:H.string().describe("Entity ID"),confirmed:H.literal(!0).optional().describe("Confirm the deletion"),confirmationToken:H.string().optional().describe("Internal confirmation token returned by the confirmation flow")}),WX0=H.object({entityType:H.string().describe("Entity type to extract"),source:H.string().optional().describe("Source entity ID \u2014 omit for batch"),mode:H.enum(["derive","rebuild"]).optional().describe("Batch mode: project incrementally or rebuild from scratch"),confirmed:H.literal(!0).optional().describe("Confirm destructive rebuild")}),HX0=H.object({batchId:H.string().optional().describe("Specific batch ID to check"),jobTypes:H.array(H.string()).optional().describe("Filter by job types")}),GX0=H.object({conversationId:H.string().describe("Conversation ID")}),KX0=H.object({searchQuery:H.string().optional().describe("Optional search query"),limit:H.number().optional().describe("Maximum results (default: 20)")}),FX0=H.object({conversationId:H.string().describe("Conversation ID"),limit:H.number().optional().describe("Maximum messages (default: 20)")}),ZX0=H.object({type:H.string().describe("Type of insight to retrieve. Built-in: overview, publishing-cadence, content-health. Plugins may register additional types.")}),jZB=H.object({entityId:H.string().optional(),status:H.enum(["created","generating"]),jobId:H.string().optional(),attachment:wYA.optional()}),_ZB=H.object({status:H.literal("extracting"),jobId:H.string(),entityType:H.string(),source:H.string().optional(),mode:H.enum(["derive","rebuild"]).optional()})});function NX0(A){let{conversationService:Q}=A;return[oQ("system","get-conversation","Get conversation details",GX0,async(B)=>{let w=await Q.getConversation(B.conversationId);if(!w)return{success:!1,error:`Conversation not found: ${B.conversationId}`};return{success:!0,data:{id:w.id,interfaceType:w.interfaceType,channelId:w.channelId,created:w.created,lastActive:w.lastActive}}},{visibility:"public"}),oQ("system","list-conversations","List conversations, optionally filtered by search query",KX0,async(B)=>{let w=await Q.searchConversations(B.searchQuery??""),$=w.slice(0,B.limit??20);return{success:!0,data:{conversations:$.map((f)=>({id:f.id,interfaceType:f.interfaceType,channelId:f.channelId,created:f.created,lastActive:f.lastActive})),totalFound:w.length,returned:$.length,searchQuery:B.searchQuery}}},{visibility:"public"}),oQ("system","get-messages","Get messages from a specific conversation",FX0,async(B)=>{let w=await Q.getMessages(B.conversationId,{limit:B.limit??20});return{success:!0,data:{conversationId:B.conversationId,messages:w.map(($)=>({id:$.id,role:$.role,content:$.content,timestamp:$.timestamp})),messageCount:w.length,requestedLimit:B.limit??20}}},{visibility:"public"})]}var zX0=p(()=>{$f();zW()});function XJ(A,Q,B,w){try{A.permissionService.assertEntityActionAllowed(Q,B,w.userPermissionLevel);return}catch($){if($ instanceof Dx||$ instanceof Error)return{success:!1,error:$.message};throw $}}var db=p(()=>{Xw()});function zU(A,Q,B,w,$={}){let{visibility:f="anchor"}=$;return{name:`${O52}_${A}`,description:Q,inputSchema:B.shape,handler:async(I,D)=>{let U=B.safeParse(I);if(!U.success)return{success:!1,error:`Invalid input: ${U.error.errors.map((Y)=>`${Y.path.join(".")}: ${Y.message}`).join(", ")}`};try{return await w(U.data,D)}catch(Y){return{success:!1,error:y0(Y)}}},visibility:f}}function XNA(A){if(A.entityType==="image"&&A.content.startsWith("data:"))return{...A,content:"[binary image data \u2014 use metadata for image info]"};return A}function WJ(A){if(A===void 0)return;let Q=A.trim();return Q.length>0?Q:void 0}function qX0(A){if(A.fields)return{fields:A.fields};if(!A.content)return{};try{let Q=JSON.parse(A.content);if(typeof Q==="object"&&Q!==null&&!Array.isArray(Q)){if("fields"in Q&&typeof Q.fields==="object"&&Q.fields!==null&&!Array.isArray(Q.fields))return{fields:Q.fields};return{fields:Q}}}catch{}return{content:A.content}}function vt(A){return[A.metadata.title,A.metadata.name,A.metadata.subject,A.metadata.slug].find((w)=>typeof w==="string"&&w.trim().length>0)??A.id}function LX0(A){return!!A&&Object.keys(A.shape).length>0}var O52="system";var yN=p(()=>{WA()});function VX0(A){if(A===void 0||A===!1)return;if(A===!0)return{generate:!0};if(A.generate===!1)return;let Q=WJ(A.prompt);return{generate:!0,...Q&&{prompt:Q}}}function R52(A,Q){return A.prompt??`Editorial cover image for: ${Q}. `}function b52(A){let Q=A.title?` "${A.title}"`:` ${A.entityType}`,B=`${A.prompt?"Generate":"Create"}${Q}?`,w=[`Entity type: ${A.entityType}`,...A.title?[`Title: ${A.title}`]:[],...A.url?[`URL: ${A.url}`]:[],...A.upload?["Upload: uploaded file"]:[],...A.sourceAttachment?[`Source attachment: ${A.sourceAttachment.sourceEntityType}/${A.sourceAttachment.sourceEntityId} (${A.sourceAttachment.attachmentType})`]:[],...A.prompt?[`Prompt: ${A.prompt}`]:[],...A.content?[`Content preview: ${A.content.slice(0,500)}`]:[]];return{summary:B,preview:w.join(`
|
|
512
|
-
`)}}async function EX0(A,Q,B){return A.jobs.enqueue({type:"image:image-generate",data:{prompt:R52(Q.coverImage,Q.title),title:`${Q.title} Cover`,aspectRatio:"16:9",targetEntityType:Q.entityType,targetEntityId:Q.entityId,entityTitle:Q.title,...Q.content&&{entityContent:Q.content}},toolContext:B})}function MX0(A,Q){if(A.entityRegistry.getAdapter(Q).supportsCoverImage)return;return{success:!1,error:`Entity type '${Q}' doesn't support cover images`}}function P52(A){if(typeof A==="string")try{let Q=JSON.parse(A);return yt(Q)?Q:null}catch{return null}return yt(A)?A:null}function yt(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}async function k52(A,Q,B){if(!B)return!1;let w=await A.conversationService.getMessages(B,{limit:100});for(let $ of w){let I=P52($.metadata)?.attachments;if(!Array.isArray(I))continue;for(let D of I){if(!yt(D))continue;let U=D.source;if(!yt(U))continue;if(U.kind===Q.kind&&U.id===Q.id)return!0}}return!1}function j52(A){let Q=WJ(A.prompt),B=WJ(A.content),w=WJ(A.url),$=Boolean(B??Q??w),f=A.sourceAttachment||$?void 0:A.upload,I=A.sourceAttachment?{kind:"entity-attachment",...A.sourceAttachment}:f,D=WJ(A.transform),U=$&&A.upload?void 0:D;if(U!==void 0&&U!=="extract-markdown")return{success:!1,error:'Unsupported transform. Use "extract-markdown" only for upload-to-note imports, or omit transform.'};return{success:!0,source:{...Q&&{prompt:Q},...B&&{content:B},...w&&{url:w},...I&&{from:I},...f&&{uploadRef:f},...U&&{transform:U}}}}function CX0(A){let{entityService:Q,jobs:B,entityRegistry:w}=A,$=new Set;return zU("create","Create a new entity. Requires confirmation. Provide content for direct creation, a prompt for AI generation, a url for URL-first flows, upload only for upload-to-note extraction, or sourceAttachment for source attachment saves. Use system_upload_save for raw uploaded file preservation. On the initial create request, do not pass confirmed; the tool will return confirmation args after the user confirms.",YX0,async(f,I)=>{let D=j52(f);if(!D.success)return D;let{prompt:U,content:Y,url:J,from:X,uploadRef:G,transform:Z}=D.source,N=WJ(f.title);if(Z==="extract-markdown"&&(!G||f.entityType!=="note"))return{success:!1,error:'Transform "extract-markdown" requires entityType "note" and an upload ref. Omit transform for raw file promotion to document/image.'};let V=f.replace===!0,L=WJ(f.targetEntityType),M=WJ(f.targetEntityId),O=VX0(f.coverImage);if(!!L!==!!M)return{success:!1,error:"Provide both 'targetEntityType' and 'targetEntityId' together, or omit both."};if(!Y&&!U&&!J&&!X)return{success:!1,error:"Provide 'content' (direct create), 'prompt' (AI generation), 'url' (URL-first create), 'upload' with transform (upload-to-note extraction), or 'sourceAttachment' (source attachment create), or a supported combination."};if(G){if(!await k52(A,G,I.conversationId??I.channelId))return{success:!1,error:"Upload ref is not accessible in this conversation or no longer exists."}}if(Y&&Ys(Y)){let x=_L(Y);if(!xR(I.userPermissionLevel,x))return{success:!1,error:`Cannot create entity with visibility "${x}" \u2014 caller permission "${I.userPermissionLevel??"public"}" is not allowed to write at that level.`}}let E={entityType:f.entityType,...U&&{prompt:U},...N&&{title:N},...Y&&{content:Y},...J&&{url:J},...X&&{from:X},...Z&&{transform:Z},...V&&{replace:V},...L&&{targetEntityType:L},...M&&{targetEntityId:M},...O&&{coverImage:O}};if(O){let x=MX0(A,E.entityType);if(x)return x}let S=XJ(A,E.entityType,"create",I);if(S)return S;let T=A.entityRegistry.getCreateInterceptor(E.entityType);if(!E.content&&!E.prompt&&!T)return{success:!1,error:"URL-only, upload-derived, or attachment-derived creation is supported only for entity types that explicitly handle it. Provide 'content' or 'prompt' for this entity type."};if(f.confirmed){let x=f.confirmationToken;if(!x||!$.has(x))return{success:!1,error:"No pending create confirmation found. Please request creation again and confirm the new approval."};$.delete(x)}else{let x=crypto.randomUUID();$.add(x);let g=b52({entityType:f.entityType,...N&&{title:N},...U&&{prompt:U},...Y&&{content:Y},...J&&{url:J},...G&&{upload:G},...f.sourceAttachment&&{sourceAttachment:f.sourceAttachment}}),n={entityType:E.entityType,...E.title&&{title:E.title},...E.prompt&&{prompt:E.prompt},...E.content&&{content:E.content},...E.url&&{url:E.url},...G&&{upload:G},...f.sourceAttachment&&{sourceAttachment:f.sourceAttachment},...E.transform&&{transform:E.transform},...E.replace&&{replace:E.replace},...E.targetEntityType&&{targetEntityType:E.targetEntityType},...E.targetEntityId&&{targetEntityId:E.targetEntityId},...E.coverImage&&{coverImage:E.coverImage},confirmed:!0,confirmationToken:x};return{needsConfirmation:!0,toolName:"system_create",summary:g.summary,preview:g.preview,args:n}}if(T){let x={interfaceType:I.interfaceType,userId:I.userId,...I.channelId&&{channelId:I.channelId},...I.channelName&&{channelName:I.channelName}},g=await T(E,x);if(g.kind==="handled"){if(O&&g.result.success&&g.result.data.status==="created"&&g.result.data.entityId)await EX0(A,{entityType:E.entityType,entityId:g.result.data.entityId,title:E.title??g.result.data.entityId,...E.content&&{content:E.content},coverImage:O},I);return g.result}E=g.input;let n=XJ(A,E.entityType,"create",I);if(n)return n;if(O=VX0(E.coverImage),O){let m=MX0(A,E.entityType);if(m)return m;E={...E,coverImage:O}}}if(!E.content&&!E.prompt)return{success:!1,error:"URL-only, upload-derived, or attachment-derived creation is supported only for entity types that explicitly handle it. Provide 'content' or 'prompt' for this entity type."};if(E.prompt){let x=X1(E.title??E.prompt).slice(0,100);if(!x)return{success:!1,error:"Could not derive a slug from the provided title/prompt. Provide a 'title' with at least one URL-safe character."};let g=E.title??x,n=KYA(A.entityRegistry,{entityType:E.entityType,id:x,title:g});if(!n)return{success:!1,error:`Entity type '${E.entityType}' does not support queued (prompt-based) creation. Provide 'content' instead.`};let m;try{m=(await Q.createEntity({entity:n,options:{deduplicateId:!0}})).entityId}catch(BA){return{success:!1,error:BA instanceof Error?BA.message:"Failed to persist generation stub"}}try{let BA=await B.enqueue({type:`${E.entityType}:generation`,data:{entityId:m,prompt:E.prompt,...E.title&&{title:E.title},...E.content&&{content:E.content},...E.targetEntityType&&{targetEntityType:E.targetEntityType},...E.targetEntityId&&{targetEntityId:E.targetEntityId},...O&&{coverImage:O}},toolContext:I});return{success:!0,data:{entityId:m,status:"generating",jobId:BA}}}catch(BA){return{success:!1,error:BA instanceof Error?BA.message:"Failed to queue generation job"}}}let y=X1(E.title??`${E.entityType}-${Date.now()}`),_=w.getEffectiveFrontmatterSchema(E.entityType);try{let x=E.content&&LX0(_)?await Q.createEntityFromMarkdown({input:{entityType:E.entityType,id:y,markdown:E.content},options:{deduplicateId:!0}}):await Q.createEntity({entity:{id:y,entityType:E.entityType,content:E.content??"",metadata:{title:E.title??y},created:new Date().toISOString(),updated:new Date().toISOString()},options:{deduplicateId:!0}});if(O)await EX0(A,{entityType:E.entityType,entityId:x.entityId,title:E.title??x.entityId,...E.content&&{content:E.content},coverImage:O},I);return{success:!0,data:{entityId:x.entityId,status:"created"}}}catch(x){return{success:!1,error:x instanceof Error?x.message:"Failed to create entity"}}},{visibility:"trusted"})}var OX0=p(()=>{J8();WA();zW();db();yN()});function RX0(A){let{entityService:Q,entityRegistry:B,logger:w}=A,$=new Set;return zU("delete","Delete an entity. Requires confirmation. On the initial delete request, do not pass confirmed; the tool will return confirmation args after the user confirms.",XX0,async(f,I)=>{if(B.getAdapter(f.entityType).isSingleton===!0)return{success:!1,error:`${f.entityType} is a singleton entity and cannot be deleted through system tools. Update it instead.`};let D=XJ(A,f.entityType,"delete",I);if(D)return D;let U=s$(I.userPermissionLevel),Y=await XU(Q,f.entityType,f.id,w,void 0,U);if(!Y.ok)return{success:!1,error:Y.error};let{entity:J}=Y;if(f.confirmed){let Z=f.confirmationToken;if(Z&&$.has(Z)){$.delete(Z);try{await Q.deleteEntity({entityType:f.entityType,id:J.id})}catch(N){return{success:!1,error:N instanceof Error?N.message:"Failed to delete entity"}}return{success:!0,data:{deleted:J.id}}}}let X=vt(J),G=crypto.randomUUID();return $.add(G),{needsConfirmation:!0,toolName:"system_delete",summary:`Delete "${X}"?`,preview:J.content.slice(0,200),args:{...f,id:J.id,confirmed:!0,confirmationToken:G}}},{visibility:"trusted"})}var bX0=p(()=>{J8();zW();db();yN()});function PX0(A){let{entityService:Q,jobs:B}=A;return zU("extract",'Generate derived entities (e.g. topics) from existing content. Use this for requests like "generate topics for me", "extract topics", "derive topics from my notes" \u2014 call once with `entityType` (typically `"topic"`); do not preflight with search/list. Provide `source` to derive from a single entity, omit for a batch over all sources. `mode: "rebuild"` is currently only supported for `entityType: "topic"` and requires confirmation; other entity types fall back to normal projection mode.',WX0,async(w,$)=>{let{entityType:f,source:I}=w,U=(w.mode??"derive")==="rebuild",Y=f==="topic"&&!I,J=U&&Y?"rebuild":"derive";if(!Q.getEntityTypes().includes(f))return{success:!1,error:`Unknown entity type: ${f}. Available types: ${Q.getEntityTypes().join(", ")}`};let X=XJ(A,f,"extract",$);if(X)return X;if(U&&Y&&!w.confirmed)return{needsConfirmation:!0,toolName:"system_extract",summary:"Rebuild all derived topic entities from current source content?",preview:"This will delete existing topics and regenerate them from scratch.",args:{...w,confirmed:!0}};try{let G={mode:J};if(I){let N=s$($.userPermissionLevel);for(let V of Q.getEntityTypes()){let L=await Q.getEntity({entityType:V,id:I,visibilityScope:N});if(L){G.mode="source",G.entityId=L.id,G.entityType=L.entityType;break}}if(!G.entityId)return{success:!1,error:`Source entity not found: ${I}`}}return{success:!0,data:{status:"extracting",jobId:await B.enqueue({type:`${f}:project`,data:G,toolContext:$}),entityType:f,mode:J,...I&&{source:I}},...U&&!Y?{message:I||f!=="topic"?`Rebuild is currently only supported for batch topic extraction. Ran normal projection mode for ${f} instead.`:void 0}:{}}}catch(G){return{success:!1,error:G instanceof Error?G.message:"Failed to queue extraction job"}}},{visibility:"trusted"})}var kX0=p(()=>{J8();zW();db();yN()});var jX0,_X0,vX0,zg,_52;var WNA=p(()=>{WA();J8();jX0=H.enum(["png","jpg","jpeg","webp","gif","svg"]),_X0=H.enum(["pending","draft","failed"]),vX0=H.object({title:H.string().optional(),alt:H.string().optional(),format:jX0,width:H.number(),height:H.number(),status:_X0.optional(),processingJobId:H.string().optional(),processingError:H.string().optional(),sourceUrl:H.string().url().optional(),sourceEntityType:H.string().optional(),sourceEntityId:H.string().optional(),sourceUploadId:H.string().optional(),sourceFilename:H.string().optional(),sourceMediaType:H.string().optional(),attachmentType:H.string().optional(),dedupKey:H.string().optional()}),zg=A2.extend({entityType:H.literal("image"),metadata:vX0}),_52=H.object({url:H.string(),alt:H.string(),title:H.string(),width:H.number(),height:H.number()})});function TN(A){let Q=A.trim().match(/^data:image\/([a-z+]+);base64,(.+)$/i);if(!Q?.[1]||!Q[2])throw Error("Invalid image data URL");return{format:Q[1].toLowerCase(),base64:Q[2]}}function HNA(A,Q){return`data:image/${Q==="jpg"?"jpeg":Q};base64,${A}`}function ZV(A){for(let[Q,B]of Object.entries(v52))if(A.startsWith(B))return Q;return null}async function qU(A){return Uo(A,"image/")}function xN(A){let Q=Buffer.from(A,"base64");if(Q[0]===137&&Q[1]===80&&Q[2]===78&&Q[3]===71){let B=Q.readUInt32BE(16),w=Q.readUInt32BE(20);return{width:B,height:w}}if(Q[0]===255&&Q[1]===216){let B=2;while(B<Q.length-8){if(Q[B]!==255){B++;continue}let w=Q[B+1];if(w===192||w===194){let f=Q.readUInt16BE(B+5);return{width:Q.readUInt16BE(B+7),height:f}}let $=Q.readUInt16BE(B+2);B+=2+$}}if(Q[0]===71&&Q[1]===73&&Q[2]===70){let B=Q.readUInt16LE(6),w=Q.readUInt16LE(8);return{width:B,height:w}}if(Q.length>=30&&Q[0]===82&&Q[1]===73&&Q[2]===70&&Q[3]===70){if(Q[12]===86&&Q[13]===80&&Q[14]===56){if(Q[15]===32){let B=Q[26]??0,w=Q[27]??0,$=Q[28]??0,f=Q[29]??0,I=(B|w<<8)&16383,D=($|f<<8)&16383;return{width:I,height:D}}if(Q[15]===76&&Q.length>=25){let B=Q.readUInt32LE(21),w=(B&16383)+1,$=(B>>14&16383)+1;return{width:w,height:$}}}}return null}var v52;var GNA=p(()=>{WA();v52={png:"iVBORw",jpg:"/9j/",gif:"R0lGOD",webp:"UklGR"}});class KNA{entityType="image";schema=zg;toMarkdown(A){return A.content}fromMarkdown(A){let{format:Q,base64:B}=TN(A),w=xN(B);return{entityType:"image",content:A,metadata:{format:Q,width:w?.width??0,height:w?.height??0}}}extractMetadata(A){return A.metadata}parseFrontMatter(A,Q){return Q.parse({})}generateFrontMatter(A){return""}getBodyTemplate(){return""}createImageEntity(A){let{dataUrl:Q,title:B,alt:w}=A,{format:$,base64:f}=TN(Q),I=xN(f),U=ZV(f)??$;return{entityType:"image",content:Q,metadata:{title:B,alt:w??B,format:U,width:I?.width??0,height:I?.height??0,...A.status&&{status:A.status},...A.sourceUrl&&{sourceUrl:A.sourceUrl},...A.sourceEntityType&&{sourceEntityType:A.sourceEntityType},...A.sourceEntityId&&{sourceEntityId:A.sourceEntityId},...A.sourceUploadId&&{sourceUploadId:A.sourceUploadId},...A.sourceFilename&&{sourceFilename:A.sourceFilename},...A.sourceMediaType&&{sourceMediaType:A.sourceMediaType},...A.attachmentType&&{attachmentType:A.attachmentType},...A.dedupKey&&{dedupKey:A.dedupKey}}}}}var mI;var yX0=p(()=>{WNA();GNA();mI=new KNA});async function TX0(A,Q){let B=await Q.getEntity({entityType:"image",id:A});if(!B)return;return{url:B.content,alt:B.metadata.alt??"",title:B.metadata.title??"",width:B.metadata.width,height:B.metadata.height}}function xX0(A,Q){let B=y52.exec(A.content);if(!B?.[1])return;try{let w=Bo(B[1]);if(w&&typeof w==="object"&&!Array.isArray(w)){let $=w[Q];return typeof $==="string"?$:void 0}}catch{return}return}function qg(A){return xX0(A,"coverImageId")}function Tt(A){return xX0(A,"ogImageId")}function NV(A,Q){return{...A,content:X4(A.content,"coverImageId",Q)}}function Lg(A,Q){return{...A,content:X4(A.content,"ogImageId",Q)}}async function FNA(A,Q){let B=qg(A);if(!B)return;return TX0(B,Q)}var y52;var SX0=p(()=>{WA();y52=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/});function ZNA(A){let Q=[],B=T52.parse(A);return cT(B,"image",(w)=>{Q.push({url:w.url,alt:w.alt??"",title:w.title??void 0})}),Q}var T52;var gX0=p(()=>{rn();CIA();T52=dO()});var C7=p(()=>{WNA();yX0();SX0();gX0();GNA()});function hX0(A,Q,B,w){let $=w.getEntityTypeConfig(A).publish?.publishStatuses;if(!$?.length)return"non-publish";if(typeof B!=="string")return"non-publish";let f=typeof Q==="string"&&$.includes(Q);if(!$.includes(B))return"non-publish";return f?"within-publish-set":"boundary"}function x52(A,Q){return Q==="visibility"?A.visibility:A.metadata[Q]}function S52(A,Q){let{visibility:B,coverImageId:w,ogImageId:$,...f}=Q,I=B===void 0?A.visibility:P9.parse(B),D=Object.hasOwn(Q,"coverImageId")?NV(A,typeof w==="string"?w:null):A,U=Object.hasOwn(Q,"ogImageId")?Lg(D,typeof $==="string"?$:null):D,Y={...A.metadata};for(let[J,X]of Object.entries(f))if(X===null)delete Y[J];else Y[J]=X;return{...U,visibility:I,metadata:Y}}function g52(A,Q,B){if(!Q.fields||!("coverImageId"in Q.fields))return;let w=Q.fields.coverImageId;if(w!==null&&w!==void 0&&typeof w!=="string")return{success:!1,error:"coverImageId must be a string or null"};if(w==="__PENDING__")return{success:!1,error:"coverImageId must reference an existing image id or be null"};if(B.getAdapter(A).supportsCoverImage)return;return{success:!1,error:`Entity type '${A}' doesn't support cover images`}}function h52(A,Q,B){if(Q.fields&&"status"in Q.fields)return Q.fields.status;if(Q.content!==void 0){let w=B.getEffectiveFrontmatterSchema(A.entityType);if(!w)return A.metadata.status;try{return B.getAdapter(A.entityType).parseFrontMatter(Q.content,w).status}catch{return A.metadata.status}}return A.metadata.status}function m52(A,Q){if(Q.fields)return Object.entries(Q.fields).map(([f,I])=>`${f}: ${String(x52(A,f)??"(empty)")} \u2192 ${String(I)}`).join(`
|
|
512
|
+
`)}}async function EX0(A,Q,B){return A.jobs.enqueue({type:"image:image-generate",data:{prompt:R52(Q.coverImage,Q.title),title:`${Q.title} Cover`,aspectRatio:"16:9",targetEntityType:Q.entityType,targetEntityId:Q.entityId,entityTitle:Q.title,...Q.content&&{entityContent:Q.content}},toolContext:B})}function MX0(A,Q){if(A.entityRegistry.getAdapter(Q).supportsCoverImage)return;return{success:!1,error:`Entity type '${Q}' doesn't support cover images`}}function P52(A){if(typeof A==="string")try{let Q=JSON.parse(A);return yt(Q)?Q:null}catch{return null}return yt(A)?A:null}function yt(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}async function k52(A,Q,B){if(!B)return!1;let w=await A.conversationService.getMessages(B,{limit:100});for(let $ of w){let I=P52($.metadata)?.attachments;if(!Array.isArray(I))continue;for(let D of I){if(!yt(D))continue;let U=D.source;if(!yt(U))continue;if(U.kind===Q.kind&&U.id===Q.id)return!0}}return!1}function j52(A){let Q=WJ(A.prompt),B=WJ(A.content),w=WJ(A.url),$=Boolean(B??Q??w),f=A.sourceAttachment||$?void 0:A.upload,I=A.sourceAttachment?{kind:"entity-attachment",...A.sourceAttachment}:f,D=WJ(A.transform),U=$&&A.upload?void 0:D;if(U!==void 0&&U!=="extract-markdown")return{success:!1,error:'Unsupported transform. Use "extract-markdown" only for upload-to-note imports, or omit transform.'};return{success:!0,source:{...Q&&{prompt:Q},...B&&{content:B},...w&&{url:w},...I&&{from:I},...f&&{uploadRef:f},...U&&{transform:U}}}}function CX0(A){let{entityService:Q,jobs:B,entityRegistry:w}=A,$=new Set;return zU("create","Create a new entity. Requires confirmation. Provide content for direct creation, a prompt for AI generation, a url for URL-first flows, upload only for upload-to-note extraction, or sourceAttachment for source attachment saves. Use system_upload_save for raw uploaded file preservation. On the initial create request, do not pass confirmed; the tool will return confirmation args after the user confirms.",YX0,async(f,I)=>{let D=j52(f);if(!D.success)return D;let{prompt:U,content:Y,url:J,from:X,uploadRef:G,transform:Z}=D.source,N=WJ(f.title);if(Z==="extract-markdown"&&(!G||f.entityType!=="note"))return{success:!1,error:'Transform "extract-markdown" requires entityType "note" and an upload ref. Omit transform for raw file promotion to document/image.'};let V=f.replace===!0,L=WJ(f.targetEntityType),M=WJ(f.targetEntityId),O=VX0(f.coverImage);if(!!L!==!!M)return{success:!1,error:"Provide both 'targetEntityType' and 'targetEntityId' together, or omit both."};if(!Y&&!U&&!J&&!X)return{success:!1,error:"Provide 'content' (direct create), 'prompt' (AI generation), 'url' (URL-first create), 'upload' with transform (upload-to-note extraction), or 'sourceAttachment' (source attachment create), or a supported combination."};if(G){if(!await k52(A,G,I.conversationId??I.channelId))return{success:!1,error:"Upload ref is not accessible in this conversation or no longer exists."}}if(Y&&Ys(Y)){let x=_L(Y);if(!xR(I.userPermissionLevel,x))return{success:!1,error:`Cannot create entity with visibility "${x}" \u2014 caller permission "${I.userPermissionLevel??"public"}" is not allowed to write at that level.`}}let E={entityType:f.entityType,...U&&{prompt:U},...N&&{title:N},...Y&&{content:Y},...J&&{url:J},...X&&{from:X},...Z&&{transform:Z},...V&&{replace:V},...L&&{targetEntityType:L},...M&&{targetEntityId:M},...O&&{coverImage:O}};if(O){let x=MX0(A,E.entityType);if(x)return x}let S=XJ(A,E.entityType,"create",I);if(S)return S;let T=A.entityRegistry.getCreateInterceptor(E.entityType);if(!E.content&&!E.prompt&&!T)return{success:!1,error:"URL-only, upload-derived, or attachment-derived creation is supported only for entity types that explicitly handle it. Provide 'content' or 'prompt' for this entity type."};if(f.confirmed){let x=f.confirmationToken;if(!x||!$.has(x))return{success:!1,error:"No pending create confirmation found. Please request creation again and confirm the new approval."};$.delete(x)}else{let x=crypto.randomUUID();$.add(x);let g=b52({entityType:f.entityType,...N&&{title:N},...U&&{prompt:U},...Y&&{content:Y},...J&&{url:J},...G&&{upload:G},...f.sourceAttachment&&{sourceAttachment:f.sourceAttachment}}),n={entityType:E.entityType,...E.title&&{title:E.title},...E.prompt&&{prompt:E.prompt},...E.content&&{content:E.content},...E.url&&{url:E.url},...G&&{upload:G},...f.sourceAttachment&&{sourceAttachment:f.sourceAttachment},...E.transform&&{transform:E.transform},...E.replace&&{replace:E.replace},...E.targetEntityType&&{targetEntityType:E.targetEntityType},...E.targetEntityId&&{targetEntityId:E.targetEntityId},...E.coverImage&&{coverImage:E.coverImage},confirmed:!0,confirmationToken:x};return{needsConfirmation:!0,toolName:"system_create",summary:g.summary,preview:g.preview,args:n}}if(T){let x={interfaceType:I.interfaceType,userId:I.userId,...I.channelId&&{channelId:I.channelId},...I.channelName&&{channelName:I.channelName}},g=await T(E,x);if(g.kind==="handled"){if(O&&g.result.success&&g.result.data.status==="created"&&g.result.data.entityId)await EX0(A,{entityType:E.entityType,entityId:g.result.data.entityId,title:E.title??g.result.data.entityId,...E.content&&{content:E.content},coverImage:O},I);return g.result}E=g.input;let n=XJ(A,E.entityType,"create",I);if(n)return n;if(O=VX0(E.coverImage),O){let m=MX0(A,E.entityType);if(m)return m;E={...E,coverImage:O}}}if(!E.content&&!E.prompt)return{success:!1,error:"URL-only, upload-derived, or attachment-derived creation is supported only for entity types that explicitly handle it. Provide 'content' or 'prompt' for this entity type."};if(E.prompt){let x=X1(E.title??E.prompt).slice(0,100);if(!x)return{success:!1,error:"Could not derive a slug from the provided title/prompt. Provide a 'title' with at least one URL-safe character."};let g=E.title??x,n=KYA(A.entityRegistry,{entityType:E.entityType,id:x,title:g});if(!n)return{success:!1,error:`Entity type '${E.entityType}' does not support queued (prompt-based) creation. Provide 'content' instead.`};let m;try{m=(await Q.createEntity({entity:n,options:{deduplicateId:!0}})).entityId}catch(BA){return{success:!1,error:BA instanceof Error?BA.message:"Failed to persist generation stub"}}try{let BA=await B.enqueue({type:`${E.entityType}:generation`,data:{entityId:m,prompt:E.prompt,...E.title&&{title:E.title},...E.content&&{content:E.content},...E.targetEntityType&&{targetEntityType:E.targetEntityType},...E.targetEntityId&&{targetEntityId:E.targetEntityId},...O&&{coverImage:O}},toolContext:I});return{success:!0,data:{entityId:m,status:"generating",jobId:BA}}}catch(BA){return{success:!1,error:BA instanceof Error?BA.message:"Failed to queue generation job"}}}let y=X1(E.title??`${E.entityType}-${Date.now()}`),_=w.getEffectiveFrontmatterSchema(E.entityType);try{let x=E.content&&LX0(_)?await Q.createEntityFromMarkdown({input:{entityType:E.entityType,id:y,markdown:E.content},options:{deduplicateId:!0}}):await Q.createEntity({entity:{id:y,entityType:E.entityType,content:E.content??"",metadata:{title:E.title??y},created:new Date().toISOString(),updated:new Date().toISOString()},options:{deduplicateId:!0}});if(O)await EX0(A,{entityType:E.entityType,entityId:x.entityId,title:E.title??x.entityId,...E.content&&{content:E.content},coverImage:O},I);return{success:!0,data:{entityId:x.entityId,status:"created"}}}catch(x){return{success:!1,error:x instanceof Error?x.message:"Failed to create entity"}}},{visibility:"trusted"})}var OX0=p(()=>{J8();WA();zW();db();yN()});function RX0(A){let{entityService:Q,entityRegistry:B,logger:w}=A,$=new Set;return zU("delete","Request entity deletion by id. Unauthorized callers get a permission error; authorized callers get confirmation first. Do not pass confirmed on the initial request.",XX0,async(f,I)=>{if((I.userPermissionLevel??"public")==="public")return{success:!1,error:"Changing content requires higher permission; current permission is Public."};let D=XJ(A,f.entityType,"delete",I);if(D)return D;if(B.getAdapter(f.entityType).isSingleton===!0)return{success:!1,error:`${f.entityType} is a singleton entity and cannot be deleted through system tools. Update it instead.`};let U=s$(I.userPermissionLevel),Y=await XU(Q,f.entityType,f.id,w,void 0,U);if(!Y.ok)return{success:!1,error:Y.error};let{entity:J}=Y;if(f.confirmed){let Z=f.confirmationToken;if(Z&&$.has(Z)){$.delete(Z);try{await Q.deleteEntity({entityType:f.entityType,id:J.id})}catch(N){return{success:!1,error:N instanceof Error?N.message:"Failed to delete entity"}}return{success:!0,data:{deleted:J.id}}}}let X=vt(J),G=crypto.randomUUID();return $.add(G),{needsConfirmation:!0,toolName:"system_delete",summary:`Delete "${X}"?`,preview:J.content.slice(0,200),args:{...f,id:J.id,confirmed:!0,confirmationToken:G}}},{visibility:"public"})}var bX0=p(()=>{J8();zW();db();yN()});function PX0(A){let{entityService:Q,jobs:B}=A;return zU("extract",'Generate derived entities (e.g. topics) from existing content. Use this for requests like "generate topics for me", "extract topics", "derive topics from my notes" \u2014 call once with `entityType` (typically `"topic"`); do not preflight with search/list. Provide `source` to derive from a single entity, omit for a batch over all sources. `mode: "rebuild"` is currently only supported for `entityType: "topic"` and requires confirmation; other entity types fall back to normal projection mode.',WX0,async(w,$)=>{let{entityType:f,source:I}=w,U=(w.mode??"derive")==="rebuild",Y=f==="topic"&&!I,J=U&&Y?"rebuild":"derive";if(!Q.getEntityTypes().includes(f))return{success:!1,error:`Unknown entity type: ${f}. Available types: ${Q.getEntityTypes().join(", ")}`};let X=XJ(A,f,"extract",$);if(X)return X;if(U&&Y&&!w.confirmed)return{needsConfirmation:!0,toolName:"system_extract",summary:"Rebuild all derived topic entities from current source content?",preview:"This will delete existing topics and regenerate them from scratch.",args:{...w,confirmed:!0}};try{let G={mode:J};if(I){let N=s$($.userPermissionLevel);for(let V of Q.getEntityTypes()){let L=await Q.getEntity({entityType:V,id:I,visibilityScope:N});if(L){G.mode="source",G.entityId=L.id,G.entityType=L.entityType;break}}if(!G.entityId)return{success:!1,error:`Source entity not found: ${I}`}}return{success:!0,data:{status:"extracting",jobId:await B.enqueue({type:`${f}:project`,data:G,toolContext:$}),entityType:f,mode:J,...I&&{source:I}},...U&&!Y?{message:I||f!=="topic"?`Rebuild is currently only supported for batch topic extraction. Ran normal projection mode for ${f} instead.`:void 0}:{}}}catch(G){return{success:!1,error:G instanceof Error?G.message:"Failed to queue extraction job"}}},{visibility:"trusted"})}var kX0=p(()=>{J8();zW();db();yN()});var jX0,_X0,vX0,zg,_52;var WNA=p(()=>{WA();J8();jX0=H.enum(["png","jpg","jpeg","webp","gif","svg"]),_X0=H.enum(["pending","draft","failed"]),vX0=H.object({title:H.string().optional(),alt:H.string().optional(),format:jX0,width:H.number(),height:H.number(),status:_X0.optional(),processingJobId:H.string().optional(),processingError:H.string().optional(),sourceUrl:H.string().url().optional(),sourceEntityType:H.string().optional(),sourceEntityId:H.string().optional(),sourceUploadId:H.string().optional(),sourceFilename:H.string().optional(),sourceMediaType:H.string().optional(),attachmentType:H.string().optional(),dedupKey:H.string().optional()}),zg=A2.extend({entityType:H.literal("image"),metadata:vX0}),_52=H.object({url:H.string(),alt:H.string(),title:H.string(),width:H.number(),height:H.number()})});function TN(A){let Q=A.trim().match(/^data:image\/([a-z+]+);base64,(.+)$/i);if(!Q?.[1]||!Q[2])throw Error("Invalid image data URL");return{format:Q[1].toLowerCase(),base64:Q[2]}}function HNA(A,Q){return`data:image/${Q==="jpg"?"jpeg":Q};base64,${A}`}function ZV(A){for(let[Q,B]of Object.entries(v52))if(A.startsWith(B))return Q;return null}async function qU(A){return Uo(A,"image/")}function xN(A){let Q=Buffer.from(A,"base64");if(Q[0]===137&&Q[1]===80&&Q[2]===78&&Q[3]===71){let B=Q.readUInt32BE(16),w=Q.readUInt32BE(20);return{width:B,height:w}}if(Q[0]===255&&Q[1]===216){let B=2;while(B<Q.length-8){if(Q[B]!==255){B++;continue}let w=Q[B+1];if(w===192||w===194){let f=Q.readUInt16BE(B+5);return{width:Q.readUInt16BE(B+7),height:f}}let $=Q.readUInt16BE(B+2);B+=2+$}}if(Q[0]===71&&Q[1]===73&&Q[2]===70){let B=Q.readUInt16LE(6),w=Q.readUInt16LE(8);return{width:B,height:w}}if(Q.length>=30&&Q[0]===82&&Q[1]===73&&Q[2]===70&&Q[3]===70){if(Q[12]===86&&Q[13]===80&&Q[14]===56){if(Q[15]===32){let B=Q[26]??0,w=Q[27]??0,$=Q[28]??0,f=Q[29]??0,I=(B|w<<8)&16383,D=($|f<<8)&16383;return{width:I,height:D}}if(Q[15]===76&&Q.length>=25){let B=Q.readUInt32LE(21),w=(B&16383)+1,$=(B>>14&16383)+1;return{width:w,height:$}}}}return null}var v52;var GNA=p(()=>{WA();v52={png:"iVBORw",jpg:"/9j/",gif:"R0lGOD",webp:"UklGR"}});class KNA{entityType="image";schema=zg;toMarkdown(A){return A.content}fromMarkdown(A){let{format:Q,base64:B}=TN(A),w=xN(B);return{entityType:"image",content:A,metadata:{format:Q,width:w?.width??0,height:w?.height??0}}}extractMetadata(A){return A.metadata}parseFrontMatter(A,Q){return Q.parse({})}generateFrontMatter(A){return""}getBodyTemplate(){return""}createImageEntity(A){let{dataUrl:Q,title:B,alt:w}=A,{format:$,base64:f}=TN(Q),I=xN(f),U=ZV(f)??$;return{entityType:"image",content:Q,metadata:{title:B,alt:w??B,format:U,width:I?.width??0,height:I?.height??0,...A.status&&{status:A.status},...A.sourceUrl&&{sourceUrl:A.sourceUrl},...A.sourceEntityType&&{sourceEntityType:A.sourceEntityType},...A.sourceEntityId&&{sourceEntityId:A.sourceEntityId},...A.sourceUploadId&&{sourceUploadId:A.sourceUploadId},...A.sourceFilename&&{sourceFilename:A.sourceFilename},...A.sourceMediaType&&{sourceMediaType:A.sourceMediaType},...A.attachmentType&&{attachmentType:A.attachmentType},...A.dedupKey&&{dedupKey:A.dedupKey}}}}}var mI;var yX0=p(()=>{WNA();GNA();mI=new KNA});async function TX0(A,Q){let B=await Q.getEntity({entityType:"image",id:A});if(!B)return;return{url:B.content,alt:B.metadata.alt??"",title:B.metadata.title??"",width:B.metadata.width,height:B.metadata.height}}function xX0(A,Q){let B=y52.exec(A.content);if(!B?.[1])return;try{let w=Bo(B[1]);if(w&&typeof w==="object"&&!Array.isArray(w)){let $=w[Q];return typeof $==="string"?$:void 0}}catch{return}return}function qg(A){return xX0(A,"coverImageId")}function Tt(A){return xX0(A,"ogImageId")}function NV(A,Q){return{...A,content:X4(A.content,"coverImageId",Q)}}function Lg(A,Q){return{...A,content:X4(A.content,"ogImageId",Q)}}async function FNA(A,Q){let B=qg(A);if(!B)return;return TX0(B,Q)}var y52;var SX0=p(()=>{WA();y52=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/});function ZNA(A){let Q=[],B=T52.parse(A);return cT(B,"image",(w)=>{Q.push({url:w.url,alt:w.alt??"",title:w.title??void 0})}),Q}var T52;var gX0=p(()=>{rn();CIA();T52=dO()});var C7=p(()=>{WNA();yX0();SX0();gX0();GNA()});function hX0(A,Q,B,w){let $=w.getEntityTypeConfig(A).publish?.publishStatuses;if(!$?.length)return"non-publish";if(typeof B!=="string")return"non-publish";let f=typeof Q==="string"&&$.includes(Q);if(!$.includes(B))return"non-publish";return f?"within-publish-set":"boundary"}function x52(A,Q){return Q==="visibility"?A.visibility:A.metadata[Q]}function S52(A,Q){let{visibility:B,coverImageId:w,ogImageId:$,...f}=Q,I=B===void 0?A.visibility:P9.parse(B),D=Object.hasOwn(Q,"coverImageId")?NV(A,typeof w==="string"?w:null):A,U=Object.hasOwn(Q,"ogImageId")?Lg(D,typeof $==="string"?$:null):D,Y={...A.metadata};for(let[J,X]of Object.entries(f))if(X===null)delete Y[J];else Y[J]=X;return{...U,visibility:I,metadata:Y}}function g52(A,Q,B){if(!Q.fields||!("coverImageId"in Q.fields))return;let w=Q.fields.coverImageId;if(w!==null&&w!==void 0&&typeof w!=="string")return{success:!1,error:"coverImageId must be a string or null"};if(w==="__PENDING__")return{success:!1,error:"coverImageId must reference an existing image id or be null"};if(B.getAdapter(A).supportsCoverImage)return;return{success:!1,error:`Entity type '${A}' doesn't support cover images`}}function h52(A,Q,B){if(Q.fields&&"status"in Q.fields)return Q.fields.status;if(Q.content!==void 0){let w=B.getEffectiveFrontmatterSchema(A.entityType);if(!w)return A.metadata.status;try{return B.getAdapter(A.entityType).parseFrontMatter(Q.content,w).status}catch{return A.metadata.status}}return A.metadata.status}function m52(A,Q){if(Q.fields)return Object.entries(Q.fields).map(([f,I])=>`${f}: ${String(x52(A,f)??"(empty)")} \u2192 ${String(I)}`).join(`
|
|
513
513
|
`);let B=A.content.split(`
|
|
514
514
|
`),w=(Q.content??"").split(`
|
|
515
515
|
`),$=[];for(let f=0;f<Math.max(B.length,w.length);f++)if((B[f]??"")!==(w[f]??"")){if(B[f])$.push(`- ${B[f]}`);if(w[f])$.push(`+ ${w[f]}`)}return $.join(`
|
|
@@ -522,7 +522,7 @@ Some entity actions are gated by policy beyond simple tool availability. Two cas
|
|
|
522
522
|
hash text NOT NULL,
|
|
523
523
|
created_at numeric
|
|
524
524
|
)
|
|
525
|
-
`;await A.session.run($);let I=(await A.values(hA`SELECT id, hash, created_at FROM ${hA.identifier(w)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,D=[];for(let U of B)if(!I||Number(I[2])<U.folderMillis){for(let Y of U.sql)D.push(A.run(hA.raw(Y)));D.push(A.run(hA`INSERT INTO ${hA.identifier(w)} ("hash", "created_at") VALUES(${U.hash}, ${U.folderMillis})`))}await A.session.migrate(D)}var Vg=p(()=>{WW0();K$()});async function HW0(A,Q){let B=Q?.child("entity-migrate")??d2.getInstance().child("entity-migrate"),{db:w,client:$,url:f}=ws(A);B.debug("Running entity database migrations...");try{await $s($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await gN(w,{migrationsFolder:D}),await fs($),B.debug("Entity database migrations completed successfully")}catch(I){throw B.error("Entity database migration failed:",I),I}finally{$.close()}}var GW0=p(()=>{Vg();nUA();WA()});async function KW0(A,Q){let B=Q?.child("job-queue-migrate")??d2.getInstance().child("job-queue-migrate"),{db:w,client:$,url:f}=As(A);B.debug("Running job queue migrations...");try{await Qs($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await gN(w,{migrationsFolder:D}),B.debug("Job queue migrations completed successfully")}catch(I){throw B.error("Job queue migration failed:",I),I}finally{$.close()}}var FW0=p(()=>{Vg();gUA();WA()});async function ZW0(A,Q){let B=Q?.child("conversation-migrate")??d2.getInstance().child("conversation-migrate"),{db:w,client:$,url:f}=Ks(A);B.debug("Running conversation database migrations...");try{if(f.startsWith("file:"))await $.execute("PRAGMA journal_mode = WAL");let D=import.meta.url.includes("/dist/")?new URL("./migrations/conversation-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await gN(w,{migrationsFolder:D}),B.debug("Conversation database migrations completed successfully")}catch(I){throw B.error("Conversation database migration failed:",I),I}finally{$.close()}}var NW0=p(()=>{Vg();bYA();WA()});async function zW0(A,Q){let B=Q?.child("runtime-state-migrate")??d2.getInstance().child("runtime-state-migrate"),{db:w,client:$,url:f}=Pt(A);B.debug("Running runtime state migrations...");try{await kt($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/runtime-state",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await gN(w,{migrationsFolder:D}),B.debug("Runtime state migrations completed successfully")}catch(I){throw B.error("Runtime state migration failed:",I),I}finally{$.close()}}var qW0=p(()=>{Vg();WA();QNA()});class Eg{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:dx,migrateEntities:HW0,migrateJobQueue:KW0,migrateConversations:ZW0,migrateRuntimeState:zW0}}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 qNA=p(()=>{gt();GW0();FW0();NW0();qW0()});function o52(){return process.env[n52]}function LW0(){return o52()!=="production"}var n52="NODE_ENV";var mt;var LNA=p(()=>{WA();mt=H.object({theme:H.object({primaryColor:H.string().describe("Primary color for the CLI theme").default("#0066cc"),accentColor:H.string().describe("Accent color for the CLI theme").default("#ff6600")}).describe("Theme configuration for the CLI interface").default({primaryColor:"#0066cc",accentColor:"#ff6600"})})});var EW0;var VW0=p(()=>{EW0={name:"@brains/chat-repl",private:!0,version:"0.2.0-alpha.125",type:"module",main:"./src/index.ts",module:"./src/index.ts",types:"./src/index.ts",files:["src"],scripts:{dev:"tsc --watch",typecheck:"tsc --noEmit",lint:"eslint --max-warnings 0 .","lint:fix":"eslint --fix .",test:"bun test"},dependencies:{"@brains/plugins":"workspace:*",chalk:"^5.4.1",ink:"^6.0.1","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0",marked:"^12.0.0",react:"^19.2.6"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/react":"^19.0.3",typescript:"^5.3.3"}}});var wB=h((a52,ut)=>{(function(){function A(IA,mA){Object.defineProperty(w.prototype,IA,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",mA[0],mA[1])}})}function Q(IA){if(IA===null||typeof IA!=="object")return null;return IA=yA&&IA[yA]||IA["@@iterator"],typeof IA==="function"?IA:null}function B(IA,mA){IA=(IA=IA.constructor)&&(IA.displayName||IA.name)||"ReactClass";var jA=IA+"."+mA;GA[jA]||(console.error("Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",mA,IA),GA[jA]=!0)}function w(IA,mA,jA){this.props=IA,this.context=mA,this.refs=cA,this.updater=jA||qA}function $(){}function f(IA,mA,jA){this.props=IA,this.context=mA,this.refs=cA,this.updater=jA||qA}function I(){}function D(IA){return""+IA}function U(IA){try{D(IA);var mA=!1}catch(K0){mA=!0}if(mA){mA=console;var jA=mA.error,iA=typeof Symbol==="function"&&Symbol.toStringTag&&IA[Symbol.toStringTag]||IA.constructor.name||"Object";return jA.call(mA,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",iA),D(IA)}}function Y(IA){if(IA==null)return null;if(typeof IA==="function")return IA.$$typeof===I0?null:IA.displayName||IA.name||null;if(typeof IA==="string")return IA;switch(IA){case e:return"Fragment";case XA:return"Profiler";case s:return"StrictMode";case w0:return"Suspense";case fA:return"SuspenseList";case KA:return"Activity"}if(typeof IA==="object")switch(typeof IA.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),IA.$$typeof){case l:return"Portal";case wA:return IA.displayName||"Context";case NA:return(IA._context.displayName||"Context")+".Consumer";case lA:var mA=IA.render;return IA=IA.displayName,IA||(IA=mA.displayName||mA.name||"",IA=IA!==""?"ForwardRef("+IA+")":"ForwardRef"),IA;case OA:return mA=IA.displayName||null,mA!==null?mA:Y(IA.type)||"Memo";case kA:mA=IA._payload,IA=IA._init;try{return Y(IA(mA))}catch(jA){}}return null}function J(IA){if(IA===e)return"<>";if(typeof IA==="object"&&IA!==null&&IA.$$typeof===kA)return"<...>";try{var mA=Y(IA);return mA?"<"+mA+">":"<...>"}catch(jA){return"<...>"}}function X(){var IA=Q0.A;return IA===null?null:IA.getOwner()}function G(){return Error("react-stack-top-frame")}function Z(IA){if(bA.call(IA,"key")){var mA=Object.getOwnPropertyDescriptor(IA,"key").get;if(mA&&mA.isReactWarning)return!1}return IA.key!==void 0}function N(IA,mA){function jA(){DA||(DA=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",mA))}jA.isReactWarning=!0,Object.defineProperty(IA,"key",{get:jA,configurable:!0})}function V(){var IA=Y(this.type);return e0[IA]||(e0[IA]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),IA=this.props.ref,IA!==void 0?IA:null}function L(IA,mA,jA,iA,K0,C0){var B0=jA.ref;return IA={$$typeof:c,type:IA,key:mA,props:jA,_owner:iA},(B0!==void 0?B0:null)!==null?Object.defineProperty(IA,"ref",{enumerable:!1,get:V}):Object.defineProperty(IA,"ref",{enumerable:!1,value:null}),IA._store={},Object.defineProperty(IA._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(IA,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(IA,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:K0}),Object.defineProperty(IA,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:C0}),Object.freeze&&(Object.freeze(IA.props),Object.freeze(IA)),IA}function M(IA,mA){return mA=L(IA.type,mA,IA.props,IA._owner,IA._debugStack,IA._debugTask),IA._store&&(mA._store.validated=IA._store.validated),mA}function O(IA){E(IA)?IA._store&&(IA._store.validated=1):typeof IA==="object"&&IA!==null&&IA.$$typeof===kA&&(IA._payload.status==="fulfilled"?E(IA._payload.value)&&IA._payload.value._store&&(IA._payload.value._store.validated=1):IA._store&&(IA._store.validated=1))}function E(IA){return typeof IA==="object"&&IA!==null&&IA.$$typeof===c}function S(IA){var mA={"=":"=0",":":"=2"};return"$"+IA.replace(/[=:]/g,function(jA){return mA[jA]})}function T(IA,mA){return typeof IA==="object"&&IA!==null&&IA.key!=null?(U(IA.key),S(""+IA.key)):mA.toString(36)}function y(IA){switch(IA.status){case"fulfilled":return IA.value;case"rejected":throw IA.reason;default:switch(typeof IA.status==="string"?IA.then(I,I):(IA.status="pending",IA.then(function(mA){IA.status==="pending"&&(IA.status="fulfilled",IA.value=mA)},function(mA){IA.status==="pending"&&(IA.status="rejected",IA.reason=mA)})),IA.status){case"fulfilled":return IA.value;case"rejected":throw IA.reason}}throw IA}function _(IA,mA,jA,iA,K0){var C0=typeof IA;if(C0==="undefined"||C0==="boolean")IA=null;var B0=!1;if(IA===null)B0=!0;else switch(C0){case"bigint":case"string":case"number":B0=!0;break;case"object":switch(IA.$$typeof){case c:case l:B0=!0;break;case kA:return B0=IA._init,_(B0(IA._payload),mA,jA,iA,K0)}}if(B0){B0=IA,K0=K0(B0);var a0=iA===""?"."+T(B0,0):iA;return Z0(K0)?(jA="",a0!=null&&(jA=a0.replace(TA,"$&/")+"/"),_(K0,mA,jA,"",function(m1){return m1})):K0!=null&&(E(K0)&&(K0.key!=null&&(B0&&B0.key===K0.key||U(K0.key)),jA=M(K0,jA+(K0.key==null||B0&&B0.key===K0.key?"":(""+K0.key).replace(TA,"$&/")+"/")+a0),iA!==""&&B0!=null&&E(B0)&&B0.key==null&&B0._store&&!B0._store.validated&&(jA._store.validated=2),K0=jA),mA.push(K0)),1}if(B0=0,a0=iA===""?".":iA+":",Z0(IA))for(var g0=0;g0<IA.length;g0++)iA=IA[g0],C0=a0+T(iA,g0),B0+=_(iA,mA,jA,C0,K0);else if(g0=Q(IA),typeof g0==="function")for(g0===IA.entries&&(dA||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),dA=!0),IA=g0.call(IA),g0=0;!(iA=IA.next()).done;)iA=iA.value,C0=a0+T(iA,g0++),B0+=_(iA,mA,jA,C0,K0);else if(C0==="object"){if(typeof IA.then==="function")return _(y(IA),mA,jA,iA,K0);throw mA=String(IA),Error("Objects are not valid as a React child (found: "+(mA==="[object Object]"?"object with keys {"+Object.keys(IA).join(", ")+"}":mA)+"). If you meant to render a collection of children, use an array instead.")}return B0}function x(IA,mA,jA){if(IA==null)return IA;var iA=[],K0=0;return _(IA,iA,"","",function(C0){return mA.call(jA,C0,K0++)}),iA}function g(IA){if(IA._status===-1){var mA=IA._ioInfo;mA!=null&&(mA.start=mA.end=performance.now()),mA=IA._result;var jA=mA();if(jA.then(function(K0){if(IA._status===0||IA._status===-1){IA._status=1,IA._result=K0;var C0=IA._ioInfo;C0!=null&&(C0.end=performance.now()),jA.status===void 0&&(jA.status="fulfilled",jA.value=K0)}},function(K0){if(IA._status===0||IA._status===-1){IA._status=2,IA._result=K0;var C0=IA._ioInfo;C0!=null&&(C0.end=performance.now()),jA.status===void 0&&(jA.status="rejected",jA.reason=K0)}}),mA=IA._ioInfo,mA!=null){mA.value=jA;var iA=jA.displayName;typeof iA==="string"&&(mA.name=iA)}IA._status===-1&&(IA._status=0,IA._result=jA)}if(IA._status===1)return mA=IA._result,mA===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
|
|
525
|
+
`;await A.session.run($);let I=(await A.values(hA`SELECT id, hash, created_at FROM ${hA.identifier(w)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,D=[];for(let U of B)if(!I||Number(I[2])<U.folderMillis){for(let Y of U.sql)D.push(A.run(hA.raw(Y)));D.push(A.run(hA`INSERT INTO ${hA.identifier(w)} ("hash", "created_at") VALUES(${U.hash}, ${U.folderMillis})`))}await A.session.migrate(D)}var Vg=p(()=>{WW0();K$()});async function HW0(A,Q){let B=Q?.child("entity-migrate")??d2.getInstance().child("entity-migrate"),{db:w,client:$,url:f}=ws(A);B.debug("Running entity database migrations...");try{await $s($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await gN(w,{migrationsFolder:D}),await fs($),B.debug("Entity database migrations completed successfully")}catch(I){throw B.error("Entity database migration failed:",I),I}finally{$.close()}}var GW0=p(()=>{Vg();nUA();WA()});async function KW0(A,Q){let B=Q?.child("job-queue-migrate")??d2.getInstance().child("job-queue-migrate"),{db:w,client:$,url:f}=As(A);B.debug("Running job queue migrations...");try{await Qs($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await gN(w,{migrationsFolder:D}),B.debug("Job queue migrations completed successfully")}catch(I){throw B.error("Job queue migration failed:",I),I}finally{$.close()}}var FW0=p(()=>{Vg();gUA();WA()});async function ZW0(A,Q){let B=Q?.child("conversation-migrate")??d2.getInstance().child("conversation-migrate"),{db:w,client:$,url:f}=Ks(A);B.debug("Running conversation database migrations...");try{if(f.startsWith("file:"))await $.execute("PRAGMA journal_mode = WAL");let D=import.meta.url.includes("/dist/")?new URL("./migrations/conversation-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await gN(w,{migrationsFolder:D}),B.debug("Conversation database migrations completed successfully")}catch(I){throw B.error("Conversation database migration failed:",I),I}finally{$.close()}}var NW0=p(()=>{Vg();bYA();WA()});async function zW0(A,Q){let B=Q?.child("runtime-state-migrate")??d2.getInstance().child("runtime-state-migrate"),{db:w,client:$,url:f}=Pt(A);B.debug("Running runtime state migrations...");try{await kt($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/runtime-state",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await gN(w,{migrationsFolder:D}),B.debug("Runtime state migrations completed successfully")}catch(I){throw B.error("Runtime state migration failed:",I),I}finally{$.close()}}var qW0=p(()=>{Vg();WA();QNA()});class Eg{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:dx,migrateEntities:HW0,migrateJobQueue:KW0,migrateConversations:ZW0,migrateRuntimeState:zW0}}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 qNA=p(()=>{gt();GW0();FW0();NW0();qW0()});function o52(){return process.env[n52]}function LW0(){return o52()!=="production"}var n52="NODE_ENV";var mt;var LNA=p(()=>{WA();mt=H.object({theme:H.object({primaryColor:H.string().describe("Primary color for the CLI theme").default("#0066cc"),accentColor:H.string().describe("Accent color for the CLI theme").default("#ff6600")}).describe("Theme configuration for the CLI interface").default({primaryColor:"#0066cc",accentColor:"#ff6600"})})});var EW0;var VW0=p(()=>{EW0={name:"@brains/chat-repl",private:!0,version:"0.2.0-alpha.127",type:"module",main:"./src/index.ts",module:"./src/index.ts",types:"./src/index.ts",files:["src"],scripts:{dev:"tsc --watch",typecheck:"tsc --noEmit",lint:"eslint --max-warnings 0 .","lint:fix":"eslint --fix .",test:"bun test"},dependencies:{"@brains/plugins":"workspace:*",chalk:"^5.4.1",ink:"^6.0.1","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0",marked:"^12.0.0",react:"^19.2.6"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/react":"^19.0.3",typescript:"^5.3.3"}}});var wB=h((a52,ut)=>{(function(){function A(IA,mA){Object.defineProperty(w.prototype,IA,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",mA[0],mA[1])}})}function Q(IA){if(IA===null||typeof IA!=="object")return null;return IA=yA&&IA[yA]||IA["@@iterator"],typeof IA==="function"?IA:null}function B(IA,mA){IA=(IA=IA.constructor)&&(IA.displayName||IA.name)||"ReactClass";var jA=IA+"."+mA;GA[jA]||(console.error("Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",mA,IA),GA[jA]=!0)}function w(IA,mA,jA){this.props=IA,this.context=mA,this.refs=cA,this.updater=jA||qA}function $(){}function f(IA,mA,jA){this.props=IA,this.context=mA,this.refs=cA,this.updater=jA||qA}function I(){}function D(IA){return""+IA}function U(IA){try{D(IA);var mA=!1}catch(K0){mA=!0}if(mA){mA=console;var jA=mA.error,iA=typeof Symbol==="function"&&Symbol.toStringTag&&IA[Symbol.toStringTag]||IA.constructor.name||"Object";return jA.call(mA,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",iA),D(IA)}}function Y(IA){if(IA==null)return null;if(typeof IA==="function")return IA.$$typeof===I0?null:IA.displayName||IA.name||null;if(typeof IA==="string")return IA;switch(IA){case e:return"Fragment";case XA:return"Profiler";case s:return"StrictMode";case w0:return"Suspense";case fA:return"SuspenseList";case KA:return"Activity"}if(typeof IA==="object")switch(typeof IA.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),IA.$$typeof){case l:return"Portal";case wA:return IA.displayName||"Context";case NA:return(IA._context.displayName||"Context")+".Consumer";case lA:var mA=IA.render;return IA=IA.displayName,IA||(IA=mA.displayName||mA.name||"",IA=IA!==""?"ForwardRef("+IA+")":"ForwardRef"),IA;case OA:return mA=IA.displayName||null,mA!==null?mA:Y(IA.type)||"Memo";case kA:mA=IA._payload,IA=IA._init;try{return Y(IA(mA))}catch(jA){}}return null}function J(IA){if(IA===e)return"<>";if(typeof IA==="object"&&IA!==null&&IA.$$typeof===kA)return"<...>";try{var mA=Y(IA);return mA?"<"+mA+">":"<...>"}catch(jA){return"<...>"}}function X(){var IA=Q0.A;return IA===null?null:IA.getOwner()}function G(){return Error("react-stack-top-frame")}function Z(IA){if(bA.call(IA,"key")){var mA=Object.getOwnPropertyDescriptor(IA,"key").get;if(mA&&mA.isReactWarning)return!1}return IA.key!==void 0}function N(IA,mA){function jA(){DA||(DA=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",mA))}jA.isReactWarning=!0,Object.defineProperty(IA,"key",{get:jA,configurable:!0})}function V(){var IA=Y(this.type);return e0[IA]||(e0[IA]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),IA=this.props.ref,IA!==void 0?IA:null}function L(IA,mA,jA,iA,K0,C0){var B0=jA.ref;return IA={$$typeof:c,type:IA,key:mA,props:jA,_owner:iA},(B0!==void 0?B0:null)!==null?Object.defineProperty(IA,"ref",{enumerable:!1,get:V}):Object.defineProperty(IA,"ref",{enumerable:!1,value:null}),IA._store={},Object.defineProperty(IA._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(IA,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(IA,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:K0}),Object.defineProperty(IA,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:C0}),Object.freeze&&(Object.freeze(IA.props),Object.freeze(IA)),IA}function M(IA,mA){return mA=L(IA.type,mA,IA.props,IA._owner,IA._debugStack,IA._debugTask),IA._store&&(mA._store.validated=IA._store.validated),mA}function O(IA){E(IA)?IA._store&&(IA._store.validated=1):typeof IA==="object"&&IA!==null&&IA.$$typeof===kA&&(IA._payload.status==="fulfilled"?E(IA._payload.value)&&IA._payload.value._store&&(IA._payload.value._store.validated=1):IA._store&&(IA._store.validated=1))}function E(IA){return typeof IA==="object"&&IA!==null&&IA.$$typeof===c}function S(IA){var mA={"=":"=0",":":"=2"};return"$"+IA.replace(/[=:]/g,function(jA){return mA[jA]})}function T(IA,mA){return typeof IA==="object"&&IA!==null&&IA.key!=null?(U(IA.key),S(""+IA.key)):mA.toString(36)}function y(IA){switch(IA.status){case"fulfilled":return IA.value;case"rejected":throw IA.reason;default:switch(typeof IA.status==="string"?IA.then(I,I):(IA.status="pending",IA.then(function(mA){IA.status==="pending"&&(IA.status="fulfilled",IA.value=mA)},function(mA){IA.status==="pending"&&(IA.status="rejected",IA.reason=mA)})),IA.status){case"fulfilled":return IA.value;case"rejected":throw IA.reason}}throw IA}function _(IA,mA,jA,iA,K0){var C0=typeof IA;if(C0==="undefined"||C0==="boolean")IA=null;var B0=!1;if(IA===null)B0=!0;else switch(C0){case"bigint":case"string":case"number":B0=!0;break;case"object":switch(IA.$$typeof){case c:case l:B0=!0;break;case kA:return B0=IA._init,_(B0(IA._payload),mA,jA,iA,K0)}}if(B0){B0=IA,K0=K0(B0);var a0=iA===""?"."+T(B0,0):iA;return Z0(K0)?(jA="",a0!=null&&(jA=a0.replace(TA,"$&/")+"/"),_(K0,mA,jA,"",function(m1){return m1})):K0!=null&&(E(K0)&&(K0.key!=null&&(B0&&B0.key===K0.key||U(K0.key)),jA=M(K0,jA+(K0.key==null||B0&&B0.key===K0.key?"":(""+K0.key).replace(TA,"$&/")+"/")+a0),iA!==""&&B0!=null&&E(B0)&&B0.key==null&&B0._store&&!B0._store.validated&&(jA._store.validated=2),K0=jA),mA.push(K0)),1}if(B0=0,a0=iA===""?".":iA+":",Z0(IA))for(var g0=0;g0<IA.length;g0++)iA=IA[g0],C0=a0+T(iA,g0),B0+=_(iA,mA,jA,C0,K0);else if(g0=Q(IA),typeof g0==="function")for(g0===IA.entries&&(dA||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),dA=!0),IA=g0.call(IA),g0=0;!(iA=IA.next()).done;)iA=iA.value,C0=a0+T(iA,g0++),B0+=_(iA,mA,jA,C0,K0);else if(C0==="object"){if(typeof IA.then==="function")return _(y(IA),mA,jA,iA,K0);throw mA=String(IA),Error("Objects are not valid as a React child (found: "+(mA==="[object Object]"?"object with keys {"+Object.keys(IA).join(", ")+"}":mA)+"). If you meant to render a collection of children, use an array instead.")}return B0}function x(IA,mA,jA){if(IA==null)return IA;var iA=[],K0=0;return _(IA,iA,"","",function(C0){return mA.call(jA,C0,K0++)}),iA}function g(IA){if(IA._status===-1){var mA=IA._ioInfo;mA!=null&&(mA.start=mA.end=performance.now()),mA=IA._result;var jA=mA();if(jA.then(function(K0){if(IA._status===0||IA._status===-1){IA._status=1,IA._result=K0;var C0=IA._ioInfo;C0!=null&&(C0.end=performance.now()),jA.status===void 0&&(jA.status="fulfilled",jA.value=K0)}},function(K0){if(IA._status===0||IA._status===-1){IA._status=2,IA._result=K0;var C0=IA._ioInfo;C0!=null&&(C0.end=performance.now()),jA.status===void 0&&(jA.status="rejected",jA.reason=K0)}}),mA=IA._ioInfo,mA!=null){mA.value=jA;var iA=jA.displayName;typeof iA==="string"&&(mA.name=iA)}IA._status===-1&&(IA._status=0,IA._result=jA)}if(IA._status===1)return mA=IA._result,mA===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
|
|
526
526
|
|
|
527
527
|
Your code should look like:
|
|
528
528
|
const MyComponent = lazy(() => import('./MyComponent'))
|
|
@@ -1819,7 +1819,7 @@ Example bad output: "A dreamlike crystal formation glowing with ethereal light i
|
|
|
1819
1819
|
Title: "${A.entityTitle??D}"
|
|
1820
1820
|
|
|
1821
1821
|
Content:
|
|
1822
|
-
${J}`,bD2);Y=`${w.trim()} ${M.imagePrompt}`}catch(M){this.logger.warn("AI prompt distillation failed, using fallback",{error:y0(M)})}}await this.reportProgress(B,{progress:qQ.PROCESS,message:"Generating image"});let X=this.context.identity.get(),G=this.context.identity.getProfile(),N=dZ0(X,G)+Y,V;try{V=await this.context.ai.generateImage(N,{...$&&{aspectRatio:$}})}catch(M){return this.logger.error("Image generation failed",{jobId:Q,error:y0(M)}),K6.failure(M)}await this.reportProgress(B,{progress:qQ.GENERATE,message:"Creating image entity"});let L=mI.createImageEntity({dataUrl:V.dataUrl,title:D,status:"draft",attachmentType:"generated",...f&&{sourceEntityType:f},...I&&{sourceEntityId:I}});if(await kI({entityService:this.context.entityService,entity:{...L,id:U}}),this.logger.debug("Created image entity",{imageId:U}),f&&I){await this.reportProgress(B,{progress:qQ.SAVE,message:`Updating ${f} with cover image`});let M=await vL(this.context.entityService,f,I,this.logger);if(!M)return K6.failure(Error(`Target entity not found: ${f}/${I}`));let O=NV(M,U);await this.context.entities.update(O),this.logger.debug("Updated target entity with cover image",{targetEntityType:f,targetEntityId:I,imageId:U})}return await this.reportProgress(B,{progress:qQ.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:U,targetEntityType:f,targetEntityId:I}),{success:!0,imageId:U}}catch(Y){let J=y0(Y);return this.logger.error("Image generation job failed",{jobId:Q,error:J}),await fW({entityService:this.context.entityService,entityType:"image",id:U,error:J}),K6.failure(Y)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}aA();WA();o8();C7();var kD2=H.object({sourceEntityType:H.string().min(1),sourceEntityId:H.string().min(1),attachmentType:H.string().min(1),imageId:H.string().min(1),dedupKey:H.string().min(1).optional(),replace:H.boolean().optional(),targetEntityType:H.string().min(1).optional(),targetEntityId:H.string().min(1).optional(),targetImageField:H.enum(["coverImageId","ogImageId"]).optional()});class SzA extends ZB{context;constructor(A,Q){super(Q,{schema:kD2,jobTypeName:"image-render-source"});this.context=A}async process(A,Q,B){this.logger.debug("Starting source image render job",{jobId:Q,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,imageId:A.imageId});try{if(A.replace!==!0&&A.dedupKey){let I=await this.findImageByDedupKey(A.dedupKey);if(I)return await this.updateTarget(A,I.id),await this.reportProgress(B,{progress:qQ.COMPLETE,message:"Reusing existing generated image"}),{success:!0,imageId:I.id,reused:!0}}await this.reportProgress(B,{progress:qQ.PROCESS,message:"Rendering source image"});let w=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!w)return K6.failure(Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`));if(w.type!=="image")return K6.failure(Error(`Attachment provider returned ${w.type}; expected image`));await this.reportProgress(B,{progress:qQ.GENERATE,message:"Creating image entity"});let $=w.mimeType.split("/")[1]??"png",f=mI.createImageEntity({dataUrl:HNA(w.data.toString("base64"),$),title:A.imageId,status:"draft",sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,...A.dedupKey&&{dedupKey:A.dedupKey}});return await kI({entityService:this.context.entityService,entity:{...f,id:A.imageId}}),await this.updateTarget(A,A.imageId),await this.reportProgress(B,{progress:qQ.COMPLETE,message:"Image render complete"}),{success:!0,imageId:A.imageId,reused:!1}}catch(w){let $=y0(w);return this.logger.error("Source image render job failed",{jobId:Q,error:$}),await fW({entityService:this.context.entityService,entityType:"image",id:A.imageId,error:$}),K6.failure(w)}}async findImageByDedupKey(A){return(await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{dedupKey:A}}}})).find((B)=>B.metadata.status!=="pending"&&B.metadata.status!=="failed")}async updateTarget(A,Q){if(!A.targetEntityType||!A.targetEntityId)return;let B=await vL(this.context.entityService,A.targetEntityType,A.targetEntityId,this.logger);if(!B)throw Error(`Target entity not found: ${A.targetEntityType}/${A.targetEntityId}`);let $=(A.targetImageField??"coverImageId")==="ogImageId"?Lg(B,Q):NV(B,Q);await this.context.entities.update($)}}aA();WA();o8();C7();WA();var bP={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};function UAA(A){return["image/png","image/jpeg","image/webp","image/gif"].includes(A.toLowerCase())}function YAA(A){let Q=jD2(A.title,A.filename),B=X1(Q);if(!B)throw Error("Could not derive an image id from the uploaded filename. Provide a title.");return{id:B,title:Q}}function nZ0(A,Q){return`data:${A};base64,${Q.toString("base64")}`}function jD2(A,Q){let B=A?.trim();if(B)return B;return Q.replace(/\.[^.]+$/,"").trim()||Q}var _D2=H.object({uploadId:H.string().min(1),imageId:H.string().min(1).optional(),title:H.string().optional()});class gzA extends ZB{context;constructor(A,Q){super(A,{schema:_D2,jobTypeName:"upload-promote"});this.context=Q}async process(A,Q,B){try{await this.reportProgress(B,{progress:10,message:"Reading uploaded image"});let w=await this.context.uploads.scoped(bP).read(A.uploadId);if(!UAA(w.record.mediaType))throw Error("Only image uploads can be promoted to image entities");let $=YAA({filename:w.record.filename,...A.title!==void 0?{title:A.title}:{}}),f=A.imageId??$.id;await this.reportProgress(B,{progress:60,message:"Saving uploaded image"});let I=new Date().toISOString(),D=mI.createImageEntity({dataUrl:nZ0(w.record.mediaType,w.content),title:$.title,status:"draft",sourceUploadId:A.uploadId,sourceFilename:w.record.filename,sourceMediaType:w.record.mediaType,attachmentType:"uploaded"}),U=await kI({entityService:this.context.entityService,entity:{id:f,...D,created:I,updated:I}});return await this.reportProgress(B,{progress:100,message:"Uploaded image promoted"}),{entityId:U.entityId,status:"created"}}catch(w){if(A.imageId)await fW({entityService:this.context.entityService,entityType:"image",id:A.imageId,error:y0(w)});return K6.failure(w)}}summarizeDataForLog(A){return{uploadId:A.uploadId,imageId:A.imageId,hasTitle:A.title!==void 0}}}var oZ0={name:"@brains/image-plugin",private:!0,version:"0.2.0-alpha.125",description:"Plugin for AI-powered image generation and management",type:"module",main:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/entity-service":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var yD2="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==",TD2=H.object({defaultAspectRatio:H.enum(["1:1","16:9","9:16","4:3","3:4"]).default("16:9").describe("Default aspect ratio for generated images")});function zJ(A){let Q=A?.trim();if(!Q)return;return Q}function xD2(A){let Q=zJ(A.prompt);if(Q)return Q;let B=zJ(A.content);if(B&&!xzA(B))return B;return}function SD2(A){let Q=A.attachmentType==="og-image"?"og":A.attachmentType;return X1(`${Q}-${A.sourceEntityType}-${A.sourceEntityId}`)}function sZ0(A){let Q=zJ(A.title)??(A.targetEntityId?`cover-${A.targetEntityId}`:A.prompt.slice(0,60).trim());return X1(Q)}async function gD2(A,Q){let B=`${Q.attachmentType}:${Q.sourceEntityType}:${Q.sourceEntityId}:resolved-attachment`,w=await A.entityService.getEntity({entityType:Q.sourceEntityType,id:Q.sourceEntityId});return w?`${B}:${w.contentHash}`:B}function hzA(A,Q="generated"){let B=encodeURIComponent(A);return{mediaType:"image/png",url:`/api/chat/attachments/image?id=${B}`,downloadUrl:`/api/chat/attachments/image?id=${B}&download=1`,filename:`${A}.png`,source:{entityType:"image",entityId:A,attachmentType:Q}}}function hD2(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 mzA extends _Q{entityType=mI.entityType;schema=zg;adapter=mI;constructor(A={}){super("image",oZ0,A,TD2)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,B){if(A.from?.kind===bP.refKind)return this.promoteUpload(A,B);let w=xD2(A),$=zJ(A.targetEntityType),f=zJ(A.targetEntityId),I=$===this.entityType?f:void 0,D=A.from;if(D?.kind==="entity-attachment")return this.enqueueSourceImageRender({...A,from:D},B);if(!$||!f||I){if(!w)return{kind:"continue",input:A};let G=zJ(A.title)??I,Z=sZ0({prompt:w,...G&&{title:G}});await this.createPendingImage(B,{id:Z,title:G??w.slice(0,60).trim(),alt:G??w.slice(0,60).trim(),attachmentType:"generated"});let N=await B.jobs.enqueue({type:"image-generate",data:{prompt:w,...G&&{title:G}}});return{kind:"handled",result:{success:!0,data:{entityId:Z,status:"generating",jobId:N,attachment:hzA(Z)}}}}let U=await XU(B.entityService,$,f,this.logger,"Target entity");if(!U.ok)return{kind:"handled",result:{success:!1,error:U.error}};if(!w)return{kind:"continue",input:{...A,targetEntityId:U.entity.id}};let Y=IAA(U.entity.content),J=sZ0({prompt:w,...A.title&&{title:A.title},targetEntityId:U.entity.id});await this.createPendingImage(B,{id:J,title:A.title??`cover-${U.entity.id}`,alt:A.title??`cover-${U.entity.id}`,attachmentType:"generated",sourceEntityType:$,sourceEntityId:U.entity.id});let X=await B.jobs.enqueue({type:"image-generate",data:{prompt:w,...A.title&&{title:A.title},targetEntityType:$,targetEntityId:U.entity.id,entityTitle:typeof U.entity.metadata.title==="string"?U.entity.metadata.title:U.entity.id,...Y&&{entityContent:Y}}});return{kind:"handled",result:{success:!0,data:{entityId:J,status:"generating",jobId:X,attachment:hzA(J)}}}}async promoteUpload(A,Q){let B=A.from;if(B?.kind!==bP.refKind)return{kind:"handled",result:{success:!1,error:"Unsupported upload ref kind"}};let w=B.id,$;try{$=await Q.uploads.scoped(bP).readRecord(w)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}if(!UAA($.mediaType))return{kind:"handled",result:{success:!1,error:"Only image uploads can be promoted to image entities"}};let f;try{f=YAA({filename:$.filename,...A.title!==void 0?{title:A.title}:{}})}catch(D){return{kind:"handled",result:{success:!1,error:D instanceof Error?D.message:String(D)}}}await this.createPendingImage(Q,{id:f.id,title:f.title,alt:f.title,sourceUploadId:w,sourceFilename:$.filename,sourceMediaType:$.mediaType,attachmentType:"uploaded"});let I=await Q.jobs.enqueue({type:"upload-promote",data:{uploadId:w,imageId:f.id,title:f.title}});return{kind:"handled",result:{success:!0,data:{entityId:f.id,status:"generating",jobId:I,attachment:hD2({mediaType:$.mediaType,entityId:f.id,filename:$.filename})}}}}async enqueueSourceImageRender(A,Q){let B=zJ(A.from.sourceEntityType),w=zJ(A.from.sourceEntityId),$=zJ(A.from.attachmentType);if(!B||!w||!$)return{kind:"handled",result:{success:!1,error:"Image source requires sourceEntityType, sourceEntityId, and attachmentType"}};let f=await XU(Q.entityService,B,w,this.logger,"Source entity");if(!f.ok)return{kind:"handled",result:{success:!1,error:f.error}};let I=zJ(A.targetEntityType),D=zJ(A.targetEntityId),U;if(I&&D){let Z=await XU(Q.entityService,I,D,this.logger,"Target entity");if(!Z.ok)return{kind:"handled",result:{success:!1,error:Z.error}};U=Z.entity.id}let Y={sourceEntityType:B,sourceEntityId:f.entity.id,attachmentType:$},J=await gD2(Q,Y),X=SD2(Y);await this.createPendingImage(Q,{id:X,title:X,alt:X,sourceEntityType:Y.sourceEntityType,sourceEntityId:Y.sourceEntityId,attachmentType:$,dedupKey:J});let G=await Q.jobs.enqueue({type:"image-render-source",data:{...Y,imageId:X,dedupKey:J,...A.replace===!0&&{replace:!0},...I&&{targetEntityType:I},...U&&{targetEntityId:U},...$==="og-image"&&{targetImageField:"ogImageId"}}});return{kind:"handled",result:{success:!0,data:{entityId:X,status:"generating",jobId:G,attachment:hzA(X,$)}}}}async createPendingImage(A,Q){let B=new Date().toISOString(),w=mI.createImageEntity({dataUrl:yD2,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 TL({entityService:A.entityService,entity:{id:Q.id,...w,created:B,updated:B}})}async getInstructions(){return'For durable raw image saves/promotions from uploaded images, call system_upload_save with the exact upload object shown in the current turn or conversation "Available upload refs" hint. Do this only after the user explicitly asks to save/import/promote the uploaded image file itself. If that hint is absent, omit upload entirely; never invent upload IDs or placeholder upload refs. Describing or summarizing an uploaded image should use it as chat context, not create an image entity. Saving an image description, discussion, interpretation, or caption as a note should create a note entity with content from the conversation, not upload/transform. After a bare upload acknowledgement, a short label/title-only follow-up is ambiguous; ask what to do with the upload instead of turning that label into an AI image-generation prompt. For AI-generated images and cover images, call system_create with entityType: "image" and a prompt, and omit upload/sourceAttachment entirely unless the user explicitly asks to reuse the uploaded image file.'}createGenerationHandler(A){return new DAA(A,this.logger)}async onRegister(A){A.entities.registerUploadSaveHandler({entityType:this.entityType,mediaTypes:["image/*"],handler:async(B)=>{let w=await this.promoteUpload({entityType:this.entityType,...B.title!==void 0?{title:B.title}:{},from:B.upload},A);return w.kind==="handled"?w.result:{success:!1,error:"Image upload save was not handled"}}});let Q=new DAA(A,this.logger);A.jobs.registerHandler("image-generate",Q),A.jobs.registerHandler("image-render-source",new SzA(A,this.logger)),A.jobs.registerHandler("upload-promote",new gzA(this.logger.child("UploadPromotionJobHandler"),A))}}function zh(A){return new mzA(A)}aA();import{StdioServerTransport as mD2}from"@modelcontextprotocol/sdk/server/stdio.js";function aZ0(){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 uzA(){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 JAA(A){if(A&&typeof A==="object"&&"info"in A&&"debug"in A&&"error"in A&&"warn"in A){let Q=A;return{info:(B,...w)=>Q.info(B,...w),debug:(B,...w)=>Q.debug(B,...w),error:(B,...w)=>Q.error(B,...w),warn:(B,...w)=>Q.warn(B,...w)}}return uzA()}class qJ{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return qJ.instance??=new qJ(A),qJ.instance}static resetInstance(){if(qJ.instance)qJ.instance.stop(),qJ.instance=null}static createFresh(A){return new qJ(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?JAA(this.config.logger):aZ0()}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 mD2,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 tZ0}from"crypto";import{WebStandardStreamableHTTPServerTransport as uD2}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as cD2}from"@modelcontextprotocol/sdk/types.js";aA();var lD2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, DELETE, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization, MCP-Session-Id, MCP-Protocol-Version, Last-Event-ID","Access-Control-Allow-Private-Network":"true","X-Content-Type-Options":"nosniff"};function pD2(A){let Q=new URL(A.url),w=A.headers.get("x-forwarded-proto")?.split(",")[0]?.trim(),$=A.headers.get("x-forwarded-host")??A.headers.get("host");if(!$)return Q.origin;return`${w??Q.protocol.replace(":","")}://${$}`}class VK{static instance=null;transports={};mcpServer=null;mcpTransport=null;agentService=null;server=null;boundPort=null;config;logger;authConfig;constructor(A={}){if(this.config=A,this.logger=this.config.logger?JAA(this.config.logger):uzA(),this.authConfig=A.auth??{},!this.authConfig.disabled&&!this.authConfig.token&&!this.authConfig.verifyBearerToken)throw Error("MCP HTTP transport requires an auth token or bearer token verifier. Set MCP_AUTH_TOKEN, configure OAuth verification, or pass auth: { disabled: true } for local dev.")}static getInstance(A){return VK.instance??=new VK(A),VK.instance}static resetInstance(){VK.instance=null}static createFresh(A){return new VK(A)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(lD2))Q.set(B,w);return new Response(A.body,{status:A.status,statusText:A.statusText,headers:Q})}createJsonResponse(A,Q=200){return this.withCors(new Response(JSON.stringify(A),{status:Q,headers:{"Content-Type":"application/json"}}))}createTextResponse(A,Q=200){return this.withCors(new Response(A,{status:Q,headers:{"Content-Type":"text/plain; charset=utf-8"}}))}getAuthErrorResponse(A,Q=401,B){let w=this.createJsonResponse({jsonrpc:"2.0",error:{code:-32001,message:A},id:null},Q);if(!B)return w;let $=new Headers(w.headers);return $.set("WWW-Authenticate",B),new Response(w.body,{status:w.status,statusText:w.statusText,headers:$})}getBearerChallenge(A,Q={}){let w={resource_metadata:`${pD2(A)}/.well-known/oauth-protected-resource`,...Q};return`Bearer ${Object.entries(w).map(([f,I])=>`${f}="${iD2(I)}"`).join(", ")}`}async authenticate(A){let Q=new URL(A.url).pathname;if(Q==="/health"||Q==="/status"||Q==="/mcp"&&A.method==="OPTIONS")return null;if(this.authConfig.disabled)return null;let B=A.headers.get("authorization");if(!B?.startsWith("Bearer "))return this.logger.warn("Authentication failed: Missing Bearer token"),this.getAuthErrorResponse("Unauthorized: Bearer token required",401,this.getBearerChallenge(A,{realm:"mcp"}));if(this.authConfig.token){if(B.substring(7)!==this.authConfig.token)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));return this.logger.debug("Authentication successful"),null}try{let w=await this.authConfig.verifyBearerToken?.(A);if(!w)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));let $=this.authConfig.requiredScopes??[],f=$.filter((I)=>!w.scope?.includes(I));if(f.length>0)return this.logger.warn(`Authentication failed: Missing required scope(s): ${f.join(", ")}`),this.getAuthErrorResponse("Forbidden: Missing required scope",403,this.getBearerChallenge(A,{error:"insufficient_scope",scope:$.join(" ")}));return this.logger.debug("Authentication successful"),null}catch(w){return this.logger.warn("Authentication failed: Invalid token",w),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}))}}async handleMcpRequest(A){let Q=A.headers.get("mcp-session-id")??void 0;if(A.method==="GET"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.debug(`GET /mcp - SSE stream for session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="DELETE"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.info(`DELETE /mcp - Terminating session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="OPTIONS")return this.withCors(new Response(null,{status:204}));if(A.method!=="POST")return this.createTextResponse("Method Not Allowed",405);if(!this.mcpServer)return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Service Unavailable: MCP server not connected"},id:null},503);let B=await A.json();this.logger.debug(`POST /mcp - Session: ${Q??"new"}`);try{let w;if(Q&&this.transports[Q])w=this.transports[Q];else if(!Q&&cD2(B))w=new uD2({sessionIdGenerator:()=>tZ0(),onsessioninitialized:(f)=>{this.logger.info(`Session initialized: ${f}`),this.transports[f]=w},onsessionclosed:(f)=>{this.logger.info(`Session closed: ${f}`),delete this.transports[f]}}),await(this.mcpTransport?this.mcpTransport.createMcpServer():this.mcpServer).connect(w);else return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32000,message:"Bad Request: Server not initialized"},id:null},400);return this.withCors(await w.handleRequest(A,{parsedBody:B}))}catch(w){return this.logger.error("MCP transport error:",w),this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Internal error"}},500)}}async handleAgentChatRequest(A){if(!this.agentService)return this.createJsonResponse({error:"Agent service not connected"},503);let{message:Q,conversationId:B}=await A.json();if(!Q||typeof Q!=="string")return this.createJsonResponse({error:"Missing or invalid 'message' field"},400);let w=B??tZ0();this.logger.debug(`POST /api/chat - conversation: ${w}`);try{let $=await this.agentService.chat(Q,w);return this.createJsonResponse($)}catch($){return this.logger.error("Agent chat error:",$),this.createJsonResponse({error:$ instanceof Error?$.message:"Internal error"},500)}}async handleAgentConfirmRequest(A){if(!this.agentService)return this.createJsonResponse({error:"Agent service not connected"},503);let{conversationId:Q,confirmed:B,approvalId:w,context:$}=await A.json();if(!Q||typeof Q!=="string")return this.createJsonResponse({error:"Missing or invalid 'conversationId' field"},400);if(typeof B!=="boolean")return this.createJsonResponse({error:"Missing or invalid 'confirmed' field"},400);if(typeof w!=="string"||w.length===0)return this.createJsonResponse({error:"Missing or invalid 'approvalId' field"},400);let f=vYA.safeParse($);if(!f.success||!f.data.userPermissionLevel)return this.createJsonResponse({error:"Missing or invalid 'context' field"},400);this.logger.debug(`POST /api/chat/confirm - conversation: ${Q}`);try{let I=await this.agentService.confirmPendingAction(Q,B,w,f.data);return this.createJsonResponse(I)}catch(I){return this.logger.error("Agent confirm error:",I),this.createJsonResponse({error:I instanceof Error?I.message:"Internal error"},500)}}async handleRequest(A){let Q=new URL(A.url);this.logger.debug(`${A.method} ${Q.pathname}`);let B=await this.authenticate(A);if(B)return B;if(Q.pathname==="/health")return this.createJsonResponse({status:"ok",transport:"streamable-http",timestamp:new Date().toISOString()});if(Q.pathname==="/status")return this.createJsonResponse({sessions:Object.keys(this.transports).length,uptime:process.uptime(),memory:process.memoryUsage(),port:this.boundPort??this.config.port??3333});if(Q.pathname==="/mcp")return this.handleMcpRequest(A);if(Q.pathname==="/api/chat"&&A.method==="POST")return this.handleAgentChatRequest(A);if(Q.pathname==="/api/chat/confirm"&&A.method==="POST")return this.handleAgentConfirmRequest(A);return this.createTextResponse("Not Found",404)}connectMCPServer(A,Q){this.mcpServer=A,this.mcpTransport=Q??null,this.logger.debug("MCP server connected to StreamableHTTP transport")}connectAgentService(A){this.agentService=A,this.logger.debug("Agent service connected to StreamableHTTP transport")}async start(){if(this.server)throw Error("Server is already running");let A=Number(this.config.port??3333),Q=this.config.host??"0.0.0.0";try{this.server=Bun.serve({port:A,hostname:Q,fetch:(B)=>this.handleRequest(B)}),this.boundPort=this.server.port??A,this.logger.info(`StreamableHTTP server listening on http://${Q}:${this.boundPort}/mcp`)}catch(B){if(B.code==="EADDRINUSE")this.logger.error(`Port ${A} is already in use`);throw B}}async stop(){for(let A in this.transports)try{let Q=this.transports[A];if(Q)this.logger.debug(`Closing transport for session ${A}`),await Q.close(),delete this.transports[A]}catch(Q){this.logger.error(`Error closing transport for session ${A}:`,Q)}if(this.server)await this.server.stop(),this.logger.info("StreamableHTTP server stopped"),this.server=null,this.boundPort=null}getPort(){if(this.boundPort===null)throw Error("Server is not running");return this.boundPort}getApp(){return{fetch:(A)=>this.handleRequest(A)}}isRunning(){return this.server!==null}getSessionCount(){return Object.keys(this.transports).length}}function iD2(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}import{randomUUID as dD2}from"crypto";import{mkdir as nD2,readFile as oD2,writeFile as sD2,chmod as aD2}from"fs/promises";import{dirname as tD2,join as eD2}from"path";function eZ0(A){let Q=A.toLowerCase();return Q==="localhost"||Q==="[::1]"||Q==="::1"||Q.startsWith("127.")}function AN0(A){try{return new URL(A)}catch{return}}function czA(A,Q){if(A===Q)return!0;let B=AN0(A),w=AN0(Q);if(!B||!w)return!1;if(!eZ0(B.hostname)||!eZ0(w.hostname))return!1;return B.protocol===w.protocol&&B.port===w.port&&rD2(B.pathname,w.pathname)&&B.search===w.search&&B.hash===w.hash}function rD2(A,Q){return A===Q||A===`${Q}/debug`||Q===`${A}/debug`}function lzA(A,Q){return A.some((B)=>czA(B,Q))}var AU2="oauth-auth-codes.json",QU2=600;function QN0(){return Math.floor(Date.now()/1000)}function BU2(A){if(!A||typeof A!=="object")return!1;let Q=A;return typeof Q.code==="string"&&typeof Q.client_id==="string"&&typeof Q.redirect_uri==="string"&&typeof Q.code_challenge==="string"&&Q.code_challenge_method==="S256"&&typeof Q.subject==="string"&&typeof Q.created_at==="number"&&typeof Q.expires_at==="number"}function wU2(A){if(!A||typeof A!=="object")return{codes:[]};let Q=A.codes;if(!Array.isArray(Q))return{codes:[]};return{codes:Q.filter(BU2)}}async function $U2(A){let Q=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(A));return Buffer.from(Q).toString("base64url")}class XAA{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=eD2(A.storageDir,A.storeFile??AU2)}async createCode(A){let Q=QN0(),B={code:`ocd_${dD2()}`,client_id:A.clientId,redirect_uri:A.redirectUri,code_challenge:A.codeChallenge,code_challenge_method:"S256",...A.scope?{scope:A.scope}:{},subject:A.subject,created_at:Q,expires_at:Q+QU2};return await this.enqueueWrite(async()=>{let w=await this.readStore();w.codes=w.codes.filter(($)=>$.expires_at>Q),w.codes.push(B),await this.writeStore(w)}),B}async consumeCode(A){let Q=QN0(),B;if(await this.enqueueWrite(async()=>{let w=await this.readStore(),$=w.codes.findIndex((D)=>D.code===A.code),f=$>=0?w.codes[$]:void 0;if(!f)throw new LJ("Authorization code not found");if(f.consumed_at!==void 0)throw new LJ("Authorization code already consumed");if(f.expires_at<=Q)throw new LJ("Authorization code expired");if(f.client_id!==A.clientId)throw new LJ("Authorization code client mismatch");if(!czA(f.redirect_uri,A.redirectUri))throw new LJ("Authorization code redirect URI mismatch");let I=await $U2(A.codeVerifier);if(f.code_challenge!==I)throw new LJ("PKCE verification failed");B={...f,consumed_at:Q},w.codes[$]=B,await this.writeStore(w)}),!B)throw new LJ("Authorization code not consumed");return B}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return wU2(JSON.parse(await oD2(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{codes:[]};throw A}}async writeStore(A){await nD2(tD2(this.storeFile),{recursive:!0,mode:448}),await sD2(this.storeFile,`${JSON.stringify(A,null,2)}
|
|
1822
|
+
${J}`,bD2);Y=`${w.trim()} ${M.imagePrompt}`}catch(M){this.logger.warn("AI prompt distillation failed, using fallback",{error:y0(M)})}}await this.reportProgress(B,{progress:qQ.PROCESS,message:"Generating image"});let X=this.context.identity.get(),G=this.context.identity.getProfile(),N=dZ0(X,G)+Y,V;try{V=await this.context.ai.generateImage(N,{...$&&{aspectRatio:$}})}catch(M){return this.logger.error("Image generation failed",{jobId:Q,error:y0(M)}),K6.failure(M)}await this.reportProgress(B,{progress:qQ.GENERATE,message:"Creating image entity"});let L=mI.createImageEntity({dataUrl:V.dataUrl,title:D,status:"draft",attachmentType:"generated",...f&&{sourceEntityType:f},...I&&{sourceEntityId:I}});if(await kI({entityService:this.context.entityService,entity:{...L,id:U}}),this.logger.debug("Created image entity",{imageId:U}),f&&I){await this.reportProgress(B,{progress:qQ.SAVE,message:`Updating ${f} with cover image`});let M=await vL(this.context.entityService,f,I,this.logger);if(!M)return K6.failure(Error(`Target entity not found: ${f}/${I}`));let O=NV(M,U);await this.context.entities.update(O),this.logger.debug("Updated target entity with cover image",{targetEntityType:f,targetEntityId:I,imageId:U})}return await this.reportProgress(B,{progress:qQ.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:U,targetEntityType:f,targetEntityId:I}),{success:!0,imageId:U}}catch(Y){let J=y0(Y);return this.logger.error("Image generation job failed",{jobId:Q,error:J}),await fW({entityService:this.context.entityService,entityType:"image",id:U,error:J}),K6.failure(Y)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}aA();WA();o8();C7();var kD2=H.object({sourceEntityType:H.string().min(1),sourceEntityId:H.string().min(1),attachmentType:H.string().min(1),imageId:H.string().min(1),dedupKey:H.string().min(1).optional(),replace:H.boolean().optional(),targetEntityType:H.string().min(1).optional(),targetEntityId:H.string().min(1).optional(),targetImageField:H.enum(["coverImageId","ogImageId"]).optional()});class SzA extends ZB{context;constructor(A,Q){super(Q,{schema:kD2,jobTypeName:"image-render-source"});this.context=A}async process(A,Q,B){this.logger.debug("Starting source image render job",{jobId:Q,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,imageId:A.imageId});try{if(A.replace!==!0&&A.dedupKey){let I=await this.findImageByDedupKey(A.dedupKey);if(I)return await this.updateTarget(A,I.id),await this.reportProgress(B,{progress:qQ.COMPLETE,message:"Reusing existing generated image"}),{success:!0,imageId:I.id,reused:!0}}await this.reportProgress(B,{progress:qQ.PROCESS,message:"Rendering source image"});let w=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!w)return K6.failure(Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`));if(w.type!=="image")return K6.failure(Error(`Attachment provider returned ${w.type}; expected image`));await this.reportProgress(B,{progress:qQ.GENERATE,message:"Creating image entity"});let $=w.mimeType.split("/")[1]??"png",f=mI.createImageEntity({dataUrl:HNA(w.data.toString("base64"),$),title:A.imageId,status:"draft",sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,...A.dedupKey&&{dedupKey:A.dedupKey}});return await kI({entityService:this.context.entityService,entity:{...f,id:A.imageId}}),await this.updateTarget(A,A.imageId),await this.reportProgress(B,{progress:qQ.COMPLETE,message:"Image render complete"}),{success:!0,imageId:A.imageId,reused:!1}}catch(w){let $=y0(w);return this.logger.error("Source image render job failed",{jobId:Q,error:$}),await fW({entityService:this.context.entityService,entityType:"image",id:A.imageId,error:$}),K6.failure(w)}}async findImageByDedupKey(A){return(await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{dedupKey:A}}}})).find((B)=>B.metadata.status!=="pending"&&B.metadata.status!=="failed")}async updateTarget(A,Q){if(!A.targetEntityType||!A.targetEntityId)return;let B=await vL(this.context.entityService,A.targetEntityType,A.targetEntityId,this.logger);if(!B)throw Error(`Target entity not found: ${A.targetEntityType}/${A.targetEntityId}`);let $=(A.targetImageField??"coverImageId")==="ogImageId"?Lg(B,Q):NV(B,Q);await this.context.entities.update($)}}aA();WA();o8();C7();WA();var bP={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};function UAA(A){return["image/png","image/jpeg","image/webp","image/gif"].includes(A.toLowerCase())}function YAA(A){let Q=jD2(A.title,A.filename),B=X1(Q);if(!B)throw Error("Could not derive an image id from the uploaded filename. Provide a title.");return{id:B,title:Q}}function nZ0(A,Q){return`data:${A};base64,${Q.toString("base64")}`}function jD2(A,Q){let B=A?.trim();if(B)return B;return Q.replace(/\.[^.]+$/,"").trim()||Q}var _D2=H.object({uploadId:H.string().min(1),imageId:H.string().min(1).optional(),title:H.string().optional()});class gzA extends ZB{context;constructor(A,Q){super(A,{schema:_D2,jobTypeName:"upload-promote"});this.context=Q}async process(A,Q,B){try{await this.reportProgress(B,{progress:10,message:"Reading uploaded image"});let w=await this.context.uploads.scoped(bP).read(A.uploadId);if(!UAA(w.record.mediaType))throw Error("Only image uploads can be promoted to image entities");let $=YAA({filename:w.record.filename,...A.title!==void 0?{title:A.title}:{}}),f=A.imageId??$.id;await this.reportProgress(B,{progress:60,message:"Saving uploaded image"});let I=new Date().toISOString(),D=mI.createImageEntity({dataUrl:nZ0(w.record.mediaType,w.content),title:$.title,status:"draft",sourceUploadId:A.uploadId,sourceFilename:w.record.filename,sourceMediaType:w.record.mediaType,attachmentType:"uploaded"}),U=await kI({entityService:this.context.entityService,entity:{id:f,...D,created:I,updated:I}});return await this.reportProgress(B,{progress:100,message:"Uploaded image promoted"}),{entityId:U.entityId,status:"created"}}catch(w){if(A.imageId)await fW({entityService:this.context.entityService,entityType:"image",id:A.imageId,error:y0(w)});return K6.failure(w)}}summarizeDataForLog(A){return{uploadId:A.uploadId,imageId:A.imageId,hasTitle:A.title!==void 0}}}var oZ0={name:"@brains/image-plugin",private:!0,version:"0.2.0-alpha.127",description:"Plugin for AI-powered image generation and management",type:"module",main:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/entity-service":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var yD2="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==",TD2=H.object({defaultAspectRatio:H.enum(["1:1","16:9","9:16","4:3","3:4"]).default("16:9").describe("Default aspect ratio for generated images")});function zJ(A){let Q=A?.trim();if(!Q)return;return Q}function xD2(A){let Q=zJ(A.prompt);if(Q)return Q;let B=zJ(A.content);if(B&&!xzA(B))return B;return}function SD2(A){let Q=A.attachmentType==="og-image"?"og":A.attachmentType;return X1(`${Q}-${A.sourceEntityType}-${A.sourceEntityId}`)}function sZ0(A){let Q=zJ(A.title)??(A.targetEntityId?`cover-${A.targetEntityId}`:A.prompt.slice(0,60).trim());return X1(Q)}async function gD2(A,Q){let B=`${Q.attachmentType}:${Q.sourceEntityType}:${Q.sourceEntityId}:resolved-attachment`,w=await A.entityService.getEntity({entityType:Q.sourceEntityType,id:Q.sourceEntityId});return w?`${B}:${w.contentHash}`:B}function hzA(A,Q="generated"){let B=encodeURIComponent(A);return{mediaType:"image/png",url:`/api/chat/attachments/image?id=${B}`,downloadUrl:`/api/chat/attachments/image?id=${B}&download=1`,filename:`${A}.png`,source:{entityType:"image",entityId:A,attachmentType:Q}}}function hD2(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 mzA extends _Q{entityType=mI.entityType;schema=zg;adapter=mI;constructor(A={}){super("image",oZ0,A,TD2)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,B){if(A.from?.kind===bP.refKind)return this.promoteUpload(A,B);let w=xD2(A),$=zJ(A.targetEntityType),f=zJ(A.targetEntityId),I=$===this.entityType?f:void 0,D=A.from;if(D?.kind==="entity-attachment")return this.enqueueSourceImageRender({...A,from:D},B);if(!$||!f||I){if(!w)return{kind:"continue",input:A};let G=zJ(A.title)??I,Z=sZ0({prompt:w,...G&&{title:G}});await this.createPendingImage(B,{id:Z,title:G??w.slice(0,60).trim(),alt:G??w.slice(0,60).trim(),attachmentType:"generated"});let N=await B.jobs.enqueue({type:"image-generate",data:{prompt:w,...G&&{title:G}}});return{kind:"handled",result:{success:!0,data:{entityId:Z,status:"generating",jobId:N,attachment:hzA(Z)}}}}let U=await XU(B.entityService,$,f,this.logger,"Target entity");if(!U.ok)return{kind:"handled",result:{success:!1,error:U.error}};if(!w)return{kind:"continue",input:{...A,targetEntityId:U.entity.id}};let Y=IAA(U.entity.content),J=sZ0({prompt:w,...A.title&&{title:A.title},targetEntityId:U.entity.id});await this.createPendingImage(B,{id:J,title:A.title??`cover-${U.entity.id}`,alt:A.title??`cover-${U.entity.id}`,attachmentType:"generated",sourceEntityType:$,sourceEntityId:U.entity.id});let X=await B.jobs.enqueue({type:"image-generate",data:{prompt:w,...A.title&&{title:A.title},targetEntityType:$,targetEntityId:U.entity.id,entityTitle:typeof U.entity.metadata.title==="string"?U.entity.metadata.title:U.entity.id,...Y&&{entityContent:Y}}});return{kind:"handled",result:{success:!0,data:{entityId:J,status:"generating",jobId:X,attachment:hzA(J)}}}}async promoteUpload(A,Q){let B=A.from;if(B?.kind!==bP.refKind)return{kind:"handled",result:{success:!1,error:"Unsupported upload ref kind"}};let w=B.id,$;try{$=await Q.uploads.scoped(bP).readRecord(w)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}if(!UAA($.mediaType))return{kind:"handled",result:{success:!1,error:"Only image uploads can be promoted to image entities"}};let f;try{f=YAA({filename:$.filename,...A.title!==void 0?{title:A.title}:{}})}catch(D){return{kind:"handled",result:{success:!1,error:D instanceof Error?D.message:String(D)}}}await this.createPendingImage(Q,{id:f.id,title:f.title,alt:f.title,sourceUploadId:w,sourceFilename:$.filename,sourceMediaType:$.mediaType,attachmentType:"uploaded"});let I=await Q.jobs.enqueue({type:"upload-promote",data:{uploadId:w,imageId:f.id,title:f.title}});return{kind:"handled",result:{success:!0,data:{entityId:f.id,status:"generating",jobId:I,attachment:hD2({mediaType:$.mediaType,entityId:f.id,filename:$.filename})}}}}async enqueueSourceImageRender(A,Q){let B=zJ(A.from.sourceEntityType),w=zJ(A.from.sourceEntityId),$=zJ(A.from.attachmentType);if(!B||!w||!$)return{kind:"handled",result:{success:!1,error:"Image source requires sourceEntityType, sourceEntityId, and attachmentType"}};let f=await XU(Q.entityService,B,w,this.logger,"Source entity");if(!f.ok)return{kind:"handled",result:{success:!1,error:f.error}};let I=zJ(A.targetEntityType),D=zJ(A.targetEntityId),U;if(I&&D){let Z=await XU(Q.entityService,I,D,this.logger,"Target entity");if(!Z.ok)return{kind:"handled",result:{success:!1,error:Z.error}};U=Z.entity.id}let Y={sourceEntityType:B,sourceEntityId:f.entity.id,attachmentType:$},J=await gD2(Q,Y),X=SD2(Y);await this.createPendingImage(Q,{id:X,title:X,alt:X,sourceEntityType:Y.sourceEntityType,sourceEntityId:Y.sourceEntityId,attachmentType:$,dedupKey:J});let G=await Q.jobs.enqueue({type:"image-render-source",data:{...Y,imageId:X,dedupKey:J,...A.replace===!0&&{replace:!0},...I&&{targetEntityType:I},...U&&{targetEntityId:U},...$==="og-image"&&{targetImageField:"ogImageId"}}});return{kind:"handled",result:{success:!0,data:{entityId:X,status:"generating",jobId:G,attachment:hzA(X,$)}}}}async createPendingImage(A,Q){let B=new Date().toISOString(),w=mI.createImageEntity({dataUrl:yD2,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 TL({entityService:A.entityService,entity:{id:Q.id,...w,created:B,updated:B}})}async getInstructions(){return'For durable raw image saves/promotions from uploaded images, call system_upload_save with the exact upload object shown in the current turn or conversation "Available upload refs" hint. Do this only after the user explicitly asks to save/import/promote the uploaded image file itself. If that hint is absent, omit upload entirely; never invent upload IDs or placeholder upload refs. Describing or summarizing an uploaded image should use it as chat context, not create an image entity. Saving an image description, discussion, interpretation, or caption as a note should create a note entity with content from the conversation, not upload/transform. After a bare upload acknowledgement, a short label/title-only follow-up is ambiguous; ask what to do with the upload instead of turning that label into an AI image-generation prompt. For AI-generated images and cover images, call system_create with entityType: "image" and a prompt, and omit upload/sourceAttachment entirely unless the user explicitly asks to reuse the uploaded image file.'}createGenerationHandler(A){return new DAA(A,this.logger)}async onRegister(A){A.entities.registerUploadSaveHandler({entityType:this.entityType,mediaTypes:["image/*"],handler:async(B)=>{let w=await this.promoteUpload({entityType:this.entityType,...B.title!==void 0?{title:B.title}:{},from:B.upload},A);return w.kind==="handled"?w.result:{success:!1,error:"Image upload save was not handled"}}});let Q=new DAA(A,this.logger);A.jobs.registerHandler("image-generate",Q),A.jobs.registerHandler("image-render-source",new SzA(A,this.logger)),A.jobs.registerHandler("upload-promote",new gzA(this.logger.child("UploadPromotionJobHandler"),A))}}function zh(A){return new mzA(A)}aA();import{StdioServerTransport as mD2}from"@modelcontextprotocol/sdk/server/stdio.js";function aZ0(){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 uzA(){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 JAA(A){if(A&&typeof A==="object"&&"info"in A&&"debug"in A&&"error"in A&&"warn"in A){let Q=A;return{info:(B,...w)=>Q.info(B,...w),debug:(B,...w)=>Q.debug(B,...w),error:(B,...w)=>Q.error(B,...w),warn:(B,...w)=>Q.warn(B,...w)}}return uzA()}class qJ{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return qJ.instance??=new qJ(A),qJ.instance}static resetInstance(){if(qJ.instance)qJ.instance.stop(),qJ.instance=null}static createFresh(A){return new qJ(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?JAA(this.config.logger):aZ0()}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 mD2,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 tZ0}from"crypto";import{WebStandardStreamableHTTPServerTransport as uD2}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as cD2}from"@modelcontextprotocol/sdk/types.js";aA();var lD2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, DELETE, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization, MCP-Session-Id, MCP-Protocol-Version, Last-Event-ID","Access-Control-Allow-Private-Network":"true","X-Content-Type-Options":"nosniff"};function pD2(A){let Q=new URL(A.url),w=A.headers.get("x-forwarded-proto")?.split(",")[0]?.trim(),$=A.headers.get("x-forwarded-host")??A.headers.get("host");if(!$)return Q.origin;return`${w??Q.protocol.replace(":","")}://${$}`}class VK{static instance=null;transports={};mcpServer=null;mcpTransport=null;agentService=null;server=null;boundPort=null;config;logger;authConfig;constructor(A={}){if(this.config=A,this.logger=this.config.logger?JAA(this.config.logger):uzA(),this.authConfig=A.auth??{},!this.authConfig.disabled&&!this.authConfig.token&&!this.authConfig.verifyBearerToken)throw Error("MCP HTTP transport requires an auth token or bearer token verifier. Set MCP_AUTH_TOKEN, configure OAuth verification, or pass auth: { disabled: true } for local dev.")}static getInstance(A){return VK.instance??=new VK(A),VK.instance}static resetInstance(){VK.instance=null}static createFresh(A){return new VK(A)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(lD2))Q.set(B,w);return new Response(A.body,{status:A.status,statusText:A.statusText,headers:Q})}createJsonResponse(A,Q=200){return this.withCors(new Response(JSON.stringify(A),{status:Q,headers:{"Content-Type":"application/json"}}))}createTextResponse(A,Q=200){return this.withCors(new Response(A,{status:Q,headers:{"Content-Type":"text/plain; charset=utf-8"}}))}getAuthErrorResponse(A,Q=401,B){let w=this.createJsonResponse({jsonrpc:"2.0",error:{code:-32001,message:A},id:null},Q);if(!B)return w;let $=new Headers(w.headers);return $.set("WWW-Authenticate",B),new Response(w.body,{status:w.status,statusText:w.statusText,headers:$})}getBearerChallenge(A,Q={}){let w={resource_metadata:`${pD2(A)}/.well-known/oauth-protected-resource`,...Q};return`Bearer ${Object.entries(w).map(([f,I])=>`${f}="${iD2(I)}"`).join(", ")}`}async authenticate(A){let Q=new URL(A.url).pathname;if(Q==="/health"||Q==="/status"||Q==="/mcp"&&A.method==="OPTIONS")return null;if(this.authConfig.disabled)return null;let B=A.headers.get("authorization");if(!B?.startsWith("Bearer "))return this.logger.warn("Authentication failed: Missing Bearer token"),this.getAuthErrorResponse("Unauthorized: Bearer token required",401,this.getBearerChallenge(A,{realm:"mcp"}));if(this.authConfig.token){if(B.substring(7)!==this.authConfig.token)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));return this.logger.debug("Authentication successful"),null}try{let w=await this.authConfig.verifyBearerToken?.(A);if(!w)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));let $=this.authConfig.requiredScopes??[],f=$.filter((I)=>!w.scope?.includes(I));if(f.length>0)return this.logger.warn(`Authentication failed: Missing required scope(s): ${f.join(", ")}`),this.getAuthErrorResponse("Forbidden: Missing required scope",403,this.getBearerChallenge(A,{error:"insufficient_scope",scope:$.join(" ")}));return this.logger.debug("Authentication successful"),null}catch(w){return this.logger.warn("Authentication failed: Invalid token",w),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}))}}async handleMcpRequest(A){let Q=A.headers.get("mcp-session-id")??void 0;if(A.method==="GET"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.debug(`GET /mcp - SSE stream for session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="DELETE"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.info(`DELETE /mcp - Terminating session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="OPTIONS")return this.withCors(new Response(null,{status:204}));if(A.method!=="POST")return this.createTextResponse("Method Not Allowed",405);if(!this.mcpServer)return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Service Unavailable: MCP server not connected"},id:null},503);let B=await A.json();this.logger.debug(`POST /mcp - Session: ${Q??"new"}`);try{let w;if(Q&&this.transports[Q])w=this.transports[Q];else if(!Q&&cD2(B))w=new uD2({sessionIdGenerator:()=>tZ0(),onsessioninitialized:(f)=>{this.logger.info(`Session initialized: ${f}`),this.transports[f]=w},onsessionclosed:(f)=>{this.logger.info(`Session closed: ${f}`),delete this.transports[f]}}),await(this.mcpTransport?this.mcpTransport.createMcpServer():this.mcpServer).connect(w);else return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32000,message:"Bad Request: Server not initialized"},id:null},400);return this.withCors(await w.handleRequest(A,{parsedBody:B}))}catch(w){return this.logger.error("MCP transport error:",w),this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Internal error"}},500)}}async handleAgentChatRequest(A){if(!this.agentService)return this.createJsonResponse({error:"Agent service not connected"},503);let{message:Q,conversationId:B}=await A.json();if(!Q||typeof Q!=="string")return this.createJsonResponse({error:"Missing or invalid 'message' field"},400);let w=B??tZ0();this.logger.debug(`POST /api/chat - conversation: ${w}`);try{let $=await this.agentService.chat(Q,w);return this.createJsonResponse($)}catch($){return this.logger.error("Agent chat error:",$),this.createJsonResponse({error:$ instanceof Error?$.message:"Internal error"},500)}}async handleAgentConfirmRequest(A){if(!this.agentService)return this.createJsonResponse({error:"Agent service not connected"},503);let{conversationId:Q,confirmed:B,approvalId:w,context:$}=await A.json();if(!Q||typeof Q!=="string")return this.createJsonResponse({error:"Missing or invalid 'conversationId' field"},400);if(typeof B!=="boolean")return this.createJsonResponse({error:"Missing or invalid 'confirmed' field"},400);if(typeof w!=="string"||w.length===0)return this.createJsonResponse({error:"Missing or invalid 'approvalId' field"},400);let f=vYA.safeParse($);if(!f.success||!f.data.userPermissionLevel)return this.createJsonResponse({error:"Missing or invalid 'context' field"},400);this.logger.debug(`POST /api/chat/confirm - conversation: ${Q}`);try{let I=await this.agentService.confirmPendingAction(Q,B,w,f.data);return this.createJsonResponse(I)}catch(I){return this.logger.error("Agent confirm error:",I),this.createJsonResponse({error:I instanceof Error?I.message:"Internal error"},500)}}async handleRequest(A){let Q=new URL(A.url);this.logger.debug(`${A.method} ${Q.pathname}`);let B=await this.authenticate(A);if(B)return B;if(Q.pathname==="/health")return this.createJsonResponse({status:"ok",transport:"streamable-http",timestamp:new Date().toISOString()});if(Q.pathname==="/status")return this.createJsonResponse({sessions:Object.keys(this.transports).length,uptime:process.uptime(),memory:process.memoryUsage(),port:this.boundPort??this.config.port??3333});if(Q.pathname==="/mcp")return this.handleMcpRequest(A);if(Q.pathname==="/api/chat"&&A.method==="POST")return this.handleAgentChatRequest(A);if(Q.pathname==="/api/chat/confirm"&&A.method==="POST")return this.handleAgentConfirmRequest(A);return this.createTextResponse("Not Found",404)}connectMCPServer(A,Q){this.mcpServer=A,this.mcpTransport=Q??null,this.logger.debug("MCP server connected to StreamableHTTP transport")}connectAgentService(A){this.agentService=A,this.logger.debug("Agent service connected to StreamableHTTP transport")}async start(){if(this.server)throw Error("Server is already running");let A=Number(this.config.port??3333),Q=this.config.host??"0.0.0.0";try{this.server=Bun.serve({port:A,hostname:Q,fetch:(B)=>this.handleRequest(B)}),this.boundPort=this.server.port??A,this.logger.info(`StreamableHTTP server listening on http://${Q}:${this.boundPort}/mcp`)}catch(B){if(B.code==="EADDRINUSE")this.logger.error(`Port ${A} is already in use`);throw B}}async stop(){for(let A in this.transports)try{let Q=this.transports[A];if(Q)this.logger.debug(`Closing transport for session ${A}`),await Q.close(),delete this.transports[A]}catch(Q){this.logger.error(`Error closing transport for session ${A}:`,Q)}if(this.server)await this.server.stop(),this.logger.info("StreamableHTTP server stopped"),this.server=null,this.boundPort=null}getPort(){if(this.boundPort===null)throw Error("Server is not running");return this.boundPort}getApp(){return{fetch:(A)=>this.handleRequest(A)}}isRunning(){return this.server!==null}getSessionCount(){return Object.keys(this.transports).length}}function iD2(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}import{randomUUID as dD2}from"crypto";import{mkdir as nD2,readFile as oD2,writeFile as sD2,chmod as aD2}from"fs/promises";import{dirname as tD2,join as eD2}from"path";function eZ0(A){let Q=A.toLowerCase();return Q==="localhost"||Q==="[::1]"||Q==="::1"||Q.startsWith("127.")}function AN0(A){try{return new URL(A)}catch{return}}function czA(A,Q){if(A===Q)return!0;let B=AN0(A),w=AN0(Q);if(!B||!w)return!1;if(!eZ0(B.hostname)||!eZ0(w.hostname))return!1;return B.protocol===w.protocol&&B.port===w.port&&rD2(B.pathname,w.pathname)&&B.search===w.search&&B.hash===w.hash}function rD2(A,Q){return A===Q||A===`${Q}/debug`||Q===`${A}/debug`}function lzA(A,Q){return A.some((B)=>czA(B,Q))}var AU2="oauth-auth-codes.json",QU2=600;function QN0(){return Math.floor(Date.now()/1000)}function BU2(A){if(!A||typeof A!=="object")return!1;let Q=A;return typeof Q.code==="string"&&typeof Q.client_id==="string"&&typeof Q.redirect_uri==="string"&&typeof Q.code_challenge==="string"&&Q.code_challenge_method==="S256"&&typeof Q.subject==="string"&&typeof Q.created_at==="number"&&typeof Q.expires_at==="number"}function wU2(A){if(!A||typeof A!=="object")return{codes:[]};let Q=A.codes;if(!Array.isArray(Q))return{codes:[]};return{codes:Q.filter(BU2)}}async function $U2(A){let Q=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(A));return Buffer.from(Q).toString("base64url")}class XAA{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=eD2(A.storageDir,A.storeFile??AU2)}async createCode(A){let Q=QN0(),B={code:`ocd_${dD2()}`,client_id:A.clientId,redirect_uri:A.redirectUri,code_challenge:A.codeChallenge,code_challenge_method:"S256",...A.scope?{scope:A.scope}:{},subject:A.subject,created_at:Q,expires_at:Q+QU2};return await this.enqueueWrite(async()=>{let w=await this.readStore();w.codes=w.codes.filter(($)=>$.expires_at>Q),w.codes.push(B),await this.writeStore(w)}),B}async consumeCode(A){let Q=QN0(),B;if(await this.enqueueWrite(async()=>{let w=await this.readStore(),$=w.codes.findIndex((D)=>D.code===A.code),f=$>=0?w.codes[$]:void 0;if(!f)throw new LJ("Authorization code not found");if(f.consumed_at!==void 0)throw new LJ("Authorization code already consumed");if(f.expires_at<=Q)throw new LJ("Authorization code expired");if(f.client_id!==A.clientId)throw new LJ("Authorization code client mismatch");if(!czA(f.redirect_uri,A.redirectUri))throw new LJ("Authorization code redirect URI mismatch");let I=await $U2(A.codeVerifier);if(f.code_challenge!==I)throw new LJ("PKCE verification failed");B={...f,consumed_at:Q},w.codes[$]=B,await this.writeStore(w)}),!B)throw new LJ("Authorization code not consumed");return B}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return wU2(JSON.parse(await oD2(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{codes:[]};throw A}}async writeStore(A){await nD2(tD2(this.storeFile),{recursive:!0,mode:448}),await sD2(this.storeFile,`${JSON.stringify(A,null,2)}
|
|
1823
1823
|
`,{mode:384}),await aD2(this.storeFile,384)}}class LJ extends Error{constructor(A){super(A);this.name="InvalidGrantError"}}WA();import{randomUUID as BN0}from"crypto";import{mkdir as fU2,readFile as IU2,writeFile as DU2,chmod as UU2}from"fs/promises";import{dirname as YU2,join as JU2}from"path";var XU2="oauth-clients.json",WU2=H.enum(["none","client_secret_basic","client_secret_post"]),HU2=H.object({redirect_uris:H.array(H.string().url()).min(1),token_endpoint_auth_method:WU2.default("none"),grant_types:H.array(H.enum(["authorization_code","refresh_token"])).default(["authorization_code","refresh_token"]),response_types:H.array(H.literal("code")).default(["code"]),scope:H.string().optional(),client_name:H.string().optional(),client_uri:H.string().url().optional(),logo_uri:H.string().url().optional(),contacts:H.array(H.string()).optional()});function GU2(){return Math.floor(Date.now()/1000)}function KU2(){return`ocs_${BN0().replaceAll("-","")}`}function FU2(A){if(!A||typeof A!=="object")return{clients:[]};let Q=A.clients;if(!Array.isArray(Q))return{clients:[]};return{clients:Q.filter(ZU2)}}function ZU2(A){if(!A||typeof A!=="object")return!1;let Q=A;return typeof Q.client_id==="string"&&Array.isArray(Q.redirect_uris)&&Q.redirect_uris.every((B)=>typeof B==="string")&&typeof Q.client_id_issued_at==="number"}class WAA{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=JU2(A.storageDir,A.storeFile??XU2)}async registerClient(A){let Q=HU2.safeParse(A);if(!Q.success)throw new qh(Q.error.message);let B=Q.data,w=GU2(),$=`oc_${BN0()}`,f=B.token_endpoint_auth_method==="none",I={client_id:$,client_id_issued_at:w,redirect_uris:B.redirect_uris,token_endpoint_auth_method:B.token_endpoint_auth_method,grant_types:B.grant_types,response_types:B.response_types,...B.scope?{scope:B.scope}:{},...B.client_name?{client_name:B.client_name}:{},...B.client_uri?{client_uri:B.client_uri}:{},...B.logo_uri?{logo_uri:B.logo_uri}:{},...B.contacts?{contacts:B.contacts}:{},...!f?{client_secret:KU2(),client_secret_expires_at:0}:{}};return await this.enqueueWrite(async()=>{let D=await this.readStore();D.clients.push(I),await this.writeStore(D)}),I}async getClient(A){return(await this.readStore()).clients.find((B)=>B.client_id===A)}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return FU2(JSON.parse(await IU2(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{clients:[]};throw A}}async writeStore(A){await fU2(YU2(this.storeFile),{recursive:!0,mode:448}),await DU2(this.storeFile,`${JSON.stringify(A,null,2)}
|
|
1824
1824
|
`,{mode:384}),await UU2(this.storeFile,384)}}class qh extends Error{constructor(A){super(A);this.name="InvalidClientMetadataError"}}import{createHash as NU2}from"crypto";import{mkdir as zU2,readFile as qU2,writeFile as LU2,chmod as VU2}from"fs/promises";import{dirname as EU2,join as MU2}from"path";var CU2="oauth-signing-key.jwk";function wN0(A){if(!A||typeof A!=="object")return!1;let Q=A;return Q.kty==="EC"&&Q.crv==="P-256"&&typeof Q.x==="string"&&typeof Q.y==="string"&&typeof Q.d==="string"}function $N0(A){let Q=JSON.stringify({crv:A.crv,kty:A.kty,x:A.x,y:A.y});return NU2("sha256").update(Q).digest("base64url")}function OU2(A){return{kty:"EC",crv:"P-256",x:A.x,y:A.y,kid:A.kid,use:"sig",alg:"ES256"}}async function RU2(){let A=await crypto.subtle.generateKey({name:"ECDSA",namedCurve:"P-256"},!0,["sign","verify"]),Q=await crypto.subtle.exportKey("jwk",A.privateKey);if(!wN0(Q))throw Error("Generated OAuth signing key is not a P-256 private JWK");let B=$N0(Q);return{...Q,kid:B,use:"sig",alg:"ES256"}}class HAA{keyFile;cachedKey;loadPromise;constructor(A){this.keyFile=MU2(A.storageDir,A.keyFile??CU2)}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 RU2();return await zU2(EU2(this.keyFile),{recursive:!0,mode:448}),await LU2(this.keyFile,`${JSON.stringify(Q,null,2)}
|
|
1825
1825
|
`,{mode:384}),await VU2(this.keyFile,384),Q}async getPublicJwk(){return OU2(await this.getPrivateJwk())}async readExistingKey(){try{let A=JSON.parse(await qU2(this.keyFile,"utf8"));if(!wN0(A))throw Error(`OAuth signing key at ${this.keyFile} is not a private P-256 JWK`);let Q=typeof A.kid==="string"?A.kid:$N0(A);return{...A,kid:Q,use:"sig",alg:"ES256"}}catch(A){if(A.code==="ENOENT")return;throw A}}}var t2={};SB(t2,{trimPadding:()=>IN0,toUTF8String:()=>xU2,toBuffer:()=>_U2,toBase64:()=>yU2,isBase64URL:()=>gU2,isBase64:()=>SU2,fromUTF8String:()=>TU2,fromBuffer:()=>vU2});var fN0=(A)=>{let Q=typeof Uint8Array>"u"?[]:new Uint8Array(256),B=64;for(let w=0;w<64;w++)Q[A.charCodeAt(w)]=w;return Q},bU2=fN0("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),PU2=fN0("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"),kU2=/^[-A-Za-z0-9\-_]*$/,jU2=/^[-A-Za-z0-9+/]*={0,3}$/,bW={};bW.toArrayBuffer=(A,Q)=>{let B=A.length,w=A.length*0.75,$,f=0,I,D,U,Y;if(A[A.length-1]==="="){if(w--,A[A.length-2]==="=")w--}let J=new ArrayBuffer(w),X=new Uint8Array(J),G=Q?PU2:bU2;for($=0;$<B;$+=4)I=G[A.charCodeAt($)],D=G[A.charCodeAt($+1)],U=G[A.charCodeAt($+2)],Y=G[A.charCodeAt($+3)],X[f++]=I<<2|D>>4,X[f++]=(D&15)<<4|U>>2,X[f++]=(U&3)<<6|Y&63;return J};bW.fromArrayBuffer=(A,Q)=>{let B=new Uint8Array(A),w,$="",f=B.length,I=Q?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(w=0;w<f;w+=3)$+=I[B[w]>>2],$+=I[(B[w]&3)<<4|B[w+1]>>4],$+=I[(B[w+1]&15)<<2|B[w+2]>>6],$+=I[B[w+2]&63];let D=f%3;if(D===2)$=$.substring(0,$.length-1)+(Q?"":"=");else if(D===1)$=$.substring(0,$.length-2)+(Q?"":"==");return $};bW.toString=(A,Q)=>{return new TextDecoder().decode(bW.toArrayBuffer(A,Q))};bW.fromString=(A,Q)=>{return bW.fromArrayBuffer(new TextEncoder().encode(A),Q)};bW.validate=(A,Q)=>{if(!(typeof A==="string"||A instanceof String))return!1;try{return Q?kU2.test(A):jU2.test(A)}catch(B){return!1}};bW.base64=bW;var EK=bW;function _U2(A,Q="base64url"){let B=EK.toArrayBuffer(A,Q==="base64url");return new Uint8Array(B)}function vU2(A,Q="base64url"){let B=new Uint8Array(A);return EK.fromArrayBuffer(B.buffer,Q==="base64url")}function yU2(A){let Q=EK.toArrayBuffer(A,!0);return EK.fromArrayBuffer(Q)}function TU2(A){return EK.fromString(A,!0)}function xU2(A){return EK.toString(A,!0)}function SU2(A){return EK.validate(A,!1)}function gU2(A){return A=IN0(A),EK.validate(A,!0)}function IN0(A){return A.replace(/=/g,"")}var L4={};SB(L4,{encode:()=>fY2,decodeFirst:()=>$Y2});function PP(A,Q,B){if(Q<24)return[Q,1];let w=A.byteLength-B-1,$=new DataView(A.buffer,B+1),f,I=0;switch(Q){case 24:{if(w>0)f=$.getUint8(0),I=2;break}case 25:{if(w>1)f=$.getUint16(0,!1),I=3;break}case 26:{if(w>3)f=$.getUint32(0,!1),I=5;break}case 27:{if(w>7){let D=$.getBigUint64(0,!1);if(D>=24n&&D<=Number.MAX_SAFE_INTEGER)return[Number(D),9]}break}}if(f&&f>=24)return[f,I];throw Error("Length not supported or not well formed")}var GAA=0,Lh=1,pzA=2,izA=3,rzA=4,dzA=5,nzA=6,DN0=7;function PW(A,Q){let B=A<<5;if(Q<0)throw Error("CBOR Data Item argument must not be negative");let w;if(typeof Q=="number"){if(!Number.isInteger(Q))throw Error("CBOR Data Item argument must be an integer");w=BigInt(Q)}else w=Q;if(A==Lh){if(w==0n)throw Error("CBOR Data Item argument cannot be zero when negative");w=w-1n}if(w>18446744073709551615n)throw Error("CBOR number out of range");let $=new Uint8Array(8);if(new DataView($.buffer).setBigUint64(0,w,!1),w<=23)return[B|$[7]];else if(w<=255)return[B|24,$[7]];else if(w<=65535)return[B|25,...$.slice(6)];else if(w<=4294967295)return[B|26,...$.slice(4)];else return[B|27,...$]}class FAA{constructor(A,Q){Object.defineProperty(this,"tagId",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"tagValue",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.tagId=A,this.tagValue=Q}get tag(){return this.tagId}get value(){return this.tagValue}}function UN0(A,Q,B){return PP(A,Q,B)}function hU2(A,Q,B){let[w,$]=UN0(A,Q,B);return[-w-1,$]}function YN0(A,Q,B){let[w,$]=PP(A,Q,B),f=B+$;return[new Uint8Array(A.buffer.slice(f,f+w)),$+w]}var mU2=new TextDecoder;function uU2(A,Q,B){let[w,$]=YN0(A,Q,B);return[mU2.decode(w),$]}function cU2(A,Q,B){if(Q===0)return[[],1];let[w,$]=PP(A,Q,B),f=$,I=[];for(let D=0;D<w;D++){if(A.byteLength-B-f<=0)throw Error("array is not supported or well formed");let[Y,J]=xV(A,B+f);I.push(Y),f+=J}return[I,f]}var KAA="Map is not supported or well formed";function lU2(A,Q,B){if(Q===0)return[new Map,1];let[w,$]=PP(A,Q,B),f=$,I=new Map;for(let D=0;D<w;D++){let U=A.byteLength-B-f;if(U<=0)throw Error(KAA);let[Y,J]=xV(A,B+f);if(f+=J,U-=J,U<=0)throw Error(KAA);if(typeof Y!=="string"&&typeof Y!=="number")throw Error(KAA);if(I.has(Y))throw Error(KAA);let[X,G]=xV(A,B+f);f+=G,I.set(Y,X)}return[I,f]}function pU2(A,Q){if(Q+3>A.byteLength)throw Error("CBOR stream ended before end of Float 16");let B=A.getUint16(Q+1,!1);if(B==31744)return[1/0,3];else if(B==32256)return[NaN,3];else if(B==64512)return[-1/0,3];throw Error("Float16 data is unsupported")}function iU2(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 rU2(A,Q){if(Q+9>A.byteLength)throw Error("CBOR stream ended before end of Float 64");return[A.getFloat64(Q+1,!1),9]}function dU2(A,Q,B){let[w,$]=PP(A,Q,B),[f,I]=xV(A,B+$);return[new FAA(w,f),$+I]}function xV(A,Q){if(Q>=A.byteLength)throw Error("CBOR stream ended before tag value");let B=A.getUint8(Q),w=B>>5,$=B&31;switch(w){case GAA:return UN0(A,$,Q);case Lh:return hU2(A,$,Q);case pzA:return YN0(A,$,Q);case izA:return uU2(A,$,Q);case rzA:return cU2(A,$,Q);case dzA:return lU2(A,$,Q);case nzA:return dU2(A,$,Q);case DN0: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 pU2(A,Q);case 26:return iU2(A,Q);case 27:return rU2(A,Q)}}throw Error(`Unsupported or not well formed at ${Q}`)}function nU2(A){if(A===!0)return 245;else if(A===!1)return 244;else if(A===null)return 246;return 247}function oU2(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 sU2(A){if(typeof A=="number"){if(Number.isSafeInteger(A))if(A<0)return PW(Lh,Math.abs(A));else return PW(GAA,A);return[oU2(A)]}else if(A<0n)return PW(Lh,A*-1n);else return PW(GAA,A)}var aU2=new TextEncoder;function tU2(A,Q){Q.push(...PW(izA,A.length)),Q.push(aU2.encode(A))}function eU2(A,Q){Q.push(...PW(pzA,A.length)),Q.push(A)}function AY2(A,Q){Q.push(...PW(rzA,A.length));for(let B of A)Vh(B,Q)}function QY2(A,Q){Q.push(new Uint8Array(PW(dzA,A.size)));for(let[B,w]of A.entries())Vh(B,Q),Vh(w,Q)}function BY2(A,Q){Q.push(...PW(nzA,A.tag)),Vh(A.value,Q)}function Vh(A,Q){if(typeof A=="boolean"||A===null||A==null){Q.push(nU2(A));return}if(typeof A=="number"||typeof A=="bigint"){Q.push(...sU2(A));return}if(typeof A=="string"){tU2(A,Q);return}if(A instanceof Uint8Array){eU2(A,Q);return}if(Array.isArray(A)){AY2(A,Q);return}if(A instanceof Map){QY2(A,Q);return}if(A instanceof FAA){BY2(A,Q);return}throw Error("Not implemented")}function ozA(A,Q){if(A.byteLength===0||A.byteLength<=Q||Q<0)throw Error("No data");if(A instanceof Uint8Array)return xV(new DataView(A.buffer),Q);else if(A instanceof ArrayBuffer)return xV(new DataView(A),Q);return xV(A,Q)}function szA(A){let Q=[];Vh(A,Q);let B=0;for(let f of Q)if(typeof f=="number")B+=1;else B+=f.length;let w=new Uint8Array(B),$=0;for(let f of Q)if(typeof f=="number")w[$]=f,$+=1;else w.set(f,$),$+=f.length;return w}function $Y2(A){let Q=new Uint8Array(A),B=ozA(Q,0),[w]=B;return w}function fY2(A){return szA(A)}var jW={};SB(jW,{verify:()=>pL0,getRandomValues:()=>GN0,digest:()=>HN0});function JN0(A){let Q=A.get(o2.kty);return azA(Q)&&Q===lI.OKP}function tN(A){let Q=A.get(o2.kty);return azA(Q)&&Q===lI.EC2}function kP(A){let Q=A.get(o2.kty);return azA(Q)&&Q===lI.RSA}var o2;(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"})(o2||(o2={}));var lI;(function(A){A[A.OKP=1]="OKP",A[A.EC2=2]="EC2",A[A.RSA=3]="RSA"})(lI||(lI={}));function azA(A){return Object.values(lI).indexOf(A)>=0}var R7;(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"})(R7||(R7={}));function XN0(A){return Object.values(R7).indexOf(A)>=0}var MQ;(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"})(MQ||(MQ={}));function kW(A){return Object.values(MQ).indexOf(A)>=0}function eN(A){if([MQ.RS1].indexOf(A)>=0)return"SHA-1";else if([MQ.ES256,MQ.PS256,MQ.RS256].indexOf(A)>=0)return"SHA-256";else if([MQ.ES384,MQ.PS384,MQ.RS384].indexOf(A)>=0)return"SHA-384";else if([MQ.ES512,MQ.PS512,MQ.RS512,MQ.EdDSA].indexOf(A)>=0)return"SHA-512";throw Error(`Could not map COSE alg value of ${A} to a WebCrypto alg`)}var Eh=void 0;function Nf(){return new Promise((Q,B)=>{if(Eh)return Q(Eh);let w=DY2.stubThisGlobalThisCrypto();if(w)return Eh=w,Q(Eh);return B(new WN0)})}class WN0 extends Error{constructor(){super("An instance of the Crypto API could not be located");this.name="MissingWebCrypto"}}var DY2={stubThisGlobalThisCrypto:()=>globalThis.crypto,setCachedCrypto:(A)=>{Eh=A}};async function HN0(A,Q){let B=await Nf(),w=eN(Q),$=await B.subtle.digest(w,A);return new Uint8Array($)}async function GN0(A){return(await Nf()).getRandomValues(A),A}async function jP(A){let Q=await Nf(),{keyData:B,algorithm:w}=A;return Q.subtle.importKey("jwk",B,w,!1,["verify"])}async function ZAA(A){let{cosePublicKey:Q,signature:B,data:w,shaHashOverride:$}=A,f=await Nf(),I=Q.get(o2.alg),D=Q.get(o2.crv),U=Q.get(o2.x),Y=Q.get(o2.y);if(!I)throw Error("Public key was missing alg (EC2)");if(!D)throw Error("Public key was missing crv (EC2)");if(!U)throw Error("Public key was missing x (EC2)");if(!Y)throw Error("Public key was missing y (EC2)");let J;if(D===R7.P256)J="P-256";else if(D===R7.P384)J="P-384";else if(D===R7.P521)J="P-521";else throw Error(`Unexpected COSE crv value of ${D} (EC2)`);let X={kty:"EC",crv:J,x:t2.fromBuffer(U),y:t2.fromBuffer(Y),ext:!1},Z=await jP({keyData:X,algorithm:{name:"ECDSA",namedCurve:J}}),N=eN(I);if($)N=eN($);let V={name:"ECDSA",hash:{name:N}};return f.subtle.verify(V,Z,B,w)}function tzA(A){if([MQ.EdDSA].indexOf(A)>=0)return"Ed25519";else if([MQ.ES256,MQ.ES384,MQ.ES512,MQ.ES256K].indexOf(A)>=0)return"ECDSA";else if([MQ.RS256,MQ.RS384,MQ.RS512,MQ.RS1].indexOf(A)>=0)return"RSASSA-PKCS1-v1_5";else if([MQ.PS256,MQ.PS384,MQ.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 NAA(A){let{cosePublicKey:Q,signature:B,data:w,shaHashOverride:$}=A,f=await Nf(),I=Q.get(o2.alg),D=Q.get(o2.n),U=Q.get(o2.e);if(!I)throw Error("Public key was missing alg (RSA)");if(!kW(I))throw Error(`Public key had invalid alg ${I} (RSA)`);if(!D)throw Error("Public key was missing n (RSA)");if(!U)throw Error("Public key was missing e (RSA)");let Y={kty:"RSA",alg:"",n:t2.fromBuffer(D),e:t2.fromBuffer(U),ext:!1},J={name:tzA(I),hash:{name:eN(I)}},X={name:tzA(I)};if($)J.hash.name=eN($);if(J.name==="RSASSA-PKCS1-v1_5"){if(J.hash.name==="SHA-256")Y.alg="RS256";else if(J.hash.name==="SHA-384")Y.alg="RS384";else if(J.hash.name==="SHA-512")Y.alg="RS512";else if(J.hash.name==="SHA-1")Y.alg="RS1"}else if(J.name==="RSA-PSS"){let Z=0;if(J.hash.name==="SHA-256")Y.alg="PS256",Z=32;else if(J.hash.name==="SHA-384")Y.alg="PS384",Z=48;else if(J.hash.name==="SHA-512")Y.alg="PS512",Z=64;X.saltLength=Z}else throw Error(`Unexpected RSA key algorithm ${I} (${J.name})`);let G=await jP({keyData:Y,algorithm:J});return f.subtle.verify(X,G,B,w)}function zAA(A){let Q=G2.toHex(A);return[Q.slice(0,8),Q.slice(8,12),Q.slice(12,16),Q.slice(16,20),Q.slice(20,32)].join("-")}function i5(A){let Q;if(typeof A==="string")if(t2.isBase64URL(A))Q=t2.toBase64(A);else if(t2.isBase64(A))Q=A;else throw Error("Certificate is not a valid base64 or base64url string");else Q=t2.fromBuffer(A,"base64");let B="";for(let w=0;w<Math.ceil(Q.length/64);w+=1){let $=64*w;B+=`${Q.substr($,64)}
|
|
@@ -2398,8 +2398,8 @@ ${M}`)}if(w!==void 0&&f?.algorithms!==void 0){let L=f.algorithms.map((M)=>M.alg)
|
|
|
2398
2398
|
</form>
|
|
2399
2399
|
</main>
|
|
2400
2400
|
</body>
|
|
2401
|
-
</html>`}function Uu(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(HEA(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function rW(A){return A.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""")}import{randomUUID as hW2}from"crypto";function wE0(A){return Buffer.from(JSON.stringify(A)).toString("base64url")}function gW2(A){let Q=new Uint8Array(A);if(Q.length===64)return Q;if(Q[0]!==48)return Q;let B=2;if(Q[1]&&Q[1]>128)B+=Q[1]-128;if(Q[B]!==2)throw Error("Invalid DER ECDSA signature");let w=Q[B+1];if(w===void 0)throw Error("Invalid DER ECDSA signature");let $=B+2,f=Q.slice($,$+w);if(B=$+w,Q[B]!==2)throw Error("Invalid DER ECDSA signature");let I=Q[B+1];if(I===void 0)throw Error("Invalid DER ECDSA signature");let D=B+2,U=Q.slice(D,D+I);return new Uint8Array([...$E0(f),...$E0(U)])}function $E0(A){let Q=A;while(Q.length>32&&Q[0]===0)Q=Q.slice(1);if(Q.length>32)throw Error("Invalid P-256 signature component length");if(Q.length===32)return Q;let B=new Uint8Array(32);return B.set(Q,32-Q.length),B}async function KEA(A,Q){let B={typ:"JWT",alg:"ES256",kid:A.kid},w=`${wE0(B)}.${wE0(Q)}`,$=await crypto.subtle.importKey("jwk",A,{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),f=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},$,new TextEncoder().encode(w));return`${w}.${Buffer.from(gW2(f)).toString("base64url")}`}var mW2=600;class FEA{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 Uu(A);let B=await this.validateAuthorizationRequest(new URL(A.url).searchParams);if(!B.success)return new Response(B.error,{status:400});let w=this.createAuthorizationApprovalToken(Q,B.params);return ak(BE0(B.params,w))}async handleAuthorizeApproval(A){let Q=await this.sessionStore.getSessionFromRequest(A);if(!Q)return Uu(A);let B=await A.formData(),w=await this.validateAuthorizationRequest(new URLSearchParams(YEA(B)));if(!w.success)return new Response(w.error,{status:400});let $=B.get("approval_token"),f=typeof $==="string"?$:void 0;if(!f||!this.consumeAuthorizationApprovalToken(f,Q,w.params))return new Response("Invalid authorization approval token",{status:400});let I=await this.authCodeStore.createCode({clientId:w.params.clientId,redirectUri:w.params.redirectUri,codeChallenge:w.params.codeChallenge,...w.params.scope?{scope:w.params.scope}:{},subject:Q.subject}),D=new URL(w.params.redirectUri);if(D.searchParams.set("code",I.code),w.params.state)D.searchParams.set("state",w.params.state);return Response.redirect(D.toString(),302)}createAuthorizationApprovalToken(A,Q){this.pruneExpiredAuthorizationApprovalTokens();let B=`oat_${hW2()}`;return this.authorizationApprovalTokens.set(B,{token:B,sessionId:A.id,clientId:Q.clientId,redirectUri:Q.redirectUri,codeChallenge:Q.codeChallenge,...Q.scope?{scope:Q.scope}:{},...Q.state?{state:Q.state}:{},expiresAt:Math.floor(Date.now()/1000)+mW2}),B}consumeAuthorizationApprovalToken(A,Q,B){this.pruneExpiredAuthorizationApprovalTokens();let w=this.authorizationApprovalTokens.get(A);if(!w)return!1;return this.authorizationApprovalTokens.delete(A),w.sessionId===Q.id&&w.clientId===B.clientId&&w.redirectUri===B.redirectUri&&w.codeChallenge===B.codeChallenge&&w.scope===B.scope&&w.state===B.state}pruneExpiredAuthorizationApprovalTokens(){let A=Math.floor(Date.now()/1000);for(let[Q,B]of this.authorizationApprovalTokens.entries())if(B.expiresAt<=A)this.authorizationApprovalTokens.delete(Q)}async validateAuthorizationRequest(A){let Q=A.get("response_type"),B=A.get("client_id"),w=A.get("redirect_uri"),$=A.get("code_challenge"),f=A.get("code_challenge_method"),I=A.get("scope")??void 0,D=A.get("state")??void 0;if(Q!=="code")return{success:!1,error:"Unsupported response_type"};if(!B)return{success:!1,error:"Missing client_id"};if(!w)return{success:!1,error:"Missing redirect_uri"};if(!$)return{success:!1,error:"Missing code_challenge"};if(f!=="S256")return{success:!1,error:"Unsupported code_challenge_method"};let U=await this.clientStore.getClient(B);if(!U)return{success:!1,error:"Unknown client_id"};if(!lzA(U.redirect_uris,w))return{success:!1,error:"Unregistered redirect_uri"};let Y=I??U.scope;return{success:!0,params:{clientId:B,redirectUri:w,codeChallenge:$,...Y?{scope:Y}:{},...D?{state:D}:{},clientName:U.client_name??U.client_id}}}async handleClientRegistration(A){let Q;try{Q=await A.json()}catch{return q6("invalid_client_metadata","Request body must be JSON")}try{let B=await this.clientStore.registerClient(Q);return aI(B,201)}catch(B){if(B instanceof qh)return q6("invalid_client_metadata",B.message);throw B}}async handleTokenRequest(A,Q){let B=await UEA(A),w=B.get("grant_type"),$=XEA(A,B),f=$.clientId??B.get("client_id");if($.error)return q6("invalid_client",$.error);if(!f)return q6("invalid_request","client_id is required");let I=await this.clientStore.getClient(f),D=JEA(I,$);if(D)return q6("invalid_client",D);if(w==="authorization_code")return this.handleAuthorizationCodeGrant(B,f,Q);if(w==="refresh_token")return this.handleRefreshTokenGrant(B,f,Q);return q6("unsupported_grant_type","Only authorization_code and refresh_token are supported")}async handleAuthorizationCodeGrant(A,Q,B){let w=A.get("code"),$=A.get("redirect_uri"),f=A.get("code_verifier");if(!w||!$||!f)return q6("invalid_request","code, redirect_uri, and code_verifier are required");let I=await this.clientStore.getClient(Q);if(!I||!lzA(I.redirect_uris,$))return q6("invalid_grant","Unregistered redirect_uri");try{let D=await this.authCodeStore.consumeCode({code:w,clientId:Q,redirectUri:$,codeVerifier:f});return await this.createTokenResponse({issuer:B,clientId:Q,subject:D.subject,...D.scope?{scope:D.scope}:{}})}catch(D){if(D instanceof LJ)return q6("invalid_grant",D.message);throw D}}async handleRefreshTokenGrant(A,Q,B){let w=A.get("refresh_token");if(!w)return q6("invalid_request","refresh_token is required");try{let $=await this.refreshTokenStore.rotateToken(w,Q);return await this.createTokenResponse({issuer:B,clientId:Q,subject:$.consumed.subject,...$.consumed.scope?{scope:$.consumed.scope}:{},refreshToken:$.replacement.token})}catch($){if($ instanceof rK)return q6("invalid_grant",$.message);throw $}}async createTokenResponse(A){let Q=Math.floor(Date.now()/1000),B=900,w=await KEA(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 aI({access_token:w,token_type:"Bearer",expires_in:900,...A.scope?{scope:A.scope}:{},refresh_token:$})}async handleRevokeRequest(A){let Q=await UEA(A),B=XEA(A,Q),w=B.clientId??Q.get("client_id")??void 0,$=Q.get("token");if(B.error)return q6("invalid_client",B.error);if(!$)return q6("invalid_request","token is required");if(w){let f=await this.clientStore.getClient(w),I=JEA(f,B);if(I)return q6("invalid_client",I)}return await this.refreshTokenStore.revokeToken($,w),new Response(null,{status:200})}}class ZEA{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 q6("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return q6("access_denied","Invalid setup token");let Q=await this.passkeyService.generateRegistrationOptions(a0A(A));return aI(Q)}async handleRegistrationVerify(A){if(await this.passkeyService.hasCredentials())return q6("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return q6("access_denied","Invalid setup token");let Q=await this.passkeyService.verifyRegistrationResponse(await A.json(),a0A(A));if(!Q.verified)return q6("access_denied","Passkey registration failed");await this.setupFlow.clearSetupState();let B=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:$u(A)});return aI({verified:!0},200,{"Set-Cookie":B.cookie})}async handleAuthenticationOptions(A){if(!await this.passkeyService.hasCredentials())return q6("access_denied","No passkey registered");let Q=await this.passkeyService.generateAuthenticationOptions(a0A(A));return aI(Q)}async handleAuthenticationVerify(A){let Q=await this.passkeyService.verifyAuthenticationResponse(await A.json(),a0A(A));if(!Q.verified)return q6("access_denied","Passkey authentication failed");let B=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:$u(A)});return aI({verified:!0},200,{"Set-Cookie":B.cookie})}}function a0A(A){let Q=pk(A),B=new URL(Q);return{origin:B.origin,rpID:B.hostname}}import{randomUUID as uW2}from"crypto";var Yu=86400;class NEA{setupStateStore;passkeyService;setupTokenTtlSeconds;setupToken;constructor(A){this.setupStateStore=A.setupStateStore,this.passkeyService=A.passkeyService,this.setupTokenTtlSeconds=A.setupTokenTtlSeconds??Yu}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_${uW2()}`,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 B=new URL(A.url);return(B.searchParams.get("setup_token")??B.searchParams.get("token"))===Q.token}async clearSetupState(){this.setupToken=void 0,await this.setupStateStore.clearSetupState()}getSetupUrl(A){let Q=this.getValidSetupToken();if(!Q)return;return iW(A,`/setup?token=${encodeURIComponent(Q.token)}`)}async getOperatorSetupRequired(A){if(await this.passkeyService.hasCredentials())return;let Q=this.getValidSetupToken();if(!Q)return;return{setupUrl:iW(A,`/setup?token=${encodeURIComponent(Q.token)}`),expiresAt:Q.expiresAt,setupTokenId:uVA(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 ak(AE0(Q))}async hasSetupEmailDelivery(A,Q){return this.setupStateStore.hasDelivery(A,Q)}async recordSetupEmailDelivery(A,Q,B={}){await this.setupStateStore.recordDelivery(A,Q,B)}}class t0A{issuer;trustedIssuers;allowLocalhostIssuers;keyStore;clientStore;authCodeStore;sessionStore;passkeyService;setupFlow;oauthEndpoints;webauthnEndpoints;logger;constructor(A){this.issuer=_J(A.issuer),this.trustedIssuers=new Set([this.issuer,...(A.trustedIssuers??[]).map((Q)=>_J(Q))]),this.allowLocalhostIssuers=A.allowLocalhostIssuers??lk(this.issuer),this.keyStore=new HAA({storageDir:A.storageDir}),this.clientStore=new WAA({storageDir:A.storageDir}),this.authCodeStore=new XAA({storageDir:A.storageDir}),this.sessionStore=new r0A({storageDir:A.storageDir}),this.passkeyService=new u0A({storageDir:A.storageDir,...A.logger?{logger:A.logger}:{}}),this.setupFlow=new NEA({setupStateStore:new cVA({storageDir:A.storageDir}),passkeyService:this.passkeyService,setupTokenTtlSeconds:A.setupTokenTtlSeconds??Yu}),this.oauthEndpoints=new FEA({clientStore:this.clientStore,authCodeStore:this.authCodeStore,refreshTokenStore:new l0A({storageDir:A.storageDir}),sessionStore:this.sessionStore,keyStore:this.keyStore}),this.webauthnEndpoints=new ZEA({passkeyService:this.passkeyService,sessionStore:this.sessionStore,setupFlow:this.setupFlow}),this.logger=A.logger}getIssuer(){return this.issuer}async initialize(){if(await this.keyStore.getPrivateJwk(),this.logger?.debug("Auth service signing key loaded"),!await this.hasPasskeyCredentials()){await this.setupFlow.ensureSetupToken();let A=this.getSetupUrl();if(A)if(lk(this.issuer))this.logger?.warn(`Passkey setup required: ${A}`);else this.logger?.warn("Passkey setup required. Ask through an anchor-visible interface for the setup URL.")}}async hasPasskeyCredentials(){return this.passkeyService.hasCredentials()}async getJwks(){return{keys:[await this.keyStore.getPublicJwk()]}}getAuthorizationServerMetadata(A=this.issuer){let Q=_J(A);return{issuer:Q,authorization_endpoint:iW(Q,"/authorize"),token_endpoint:iW(Q,"/token"),registration_endpoint:iW(Q,"/register"),revocation_endpoint:iW(Q,"/revoke"),jwks_uri:iW(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:[_J(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 Uu(A)}async verifyBearerToken(A,Q={}){let B=DEA(A);if(!B)return;let w=Q.issuer?_J(Q.issuer):this.resolveRequestIssuer(A);return IEA(B,await this.getJwks(),{issuer:w,...Q.audience?{audience:Q.audience}:{}})}getSetupUrl(A=this.issuer){return this.setupFlow.getSetupUrl(A)}async getOperatorSetupRequired(A=this.issuer){return this.setupFlow.getOperatorSetupRequired(A)}async hasSetupEmailDelivery(A,Q){return this.setupFlow.hasSetupEmailDelivery(A,Q)}async recordSetupEmailDelivery(A,Q,B={}){await this.setupFlow.recordSetupEmailDelivery(A,Q,B)}async handleRequest(A){let Q;try{Q=this.resolveRequestIssuer(A)}catch(w){return this.logger?.warn("Rejected OAuth request from untrusted issuer",{error:w instanceof Error?w.message:String(w)}),new Response("Untrusted OAuth issuer",{status:400})}let B=new URL(A.url).pathname;if(A.method==="OPTIONS"&&aV0(B))return tV0();if(A.method==="GET"){if(B==="/.well-known/oauth-authorization-server")return b3(aI(this.getAuthorizationServerMetadata(Q)));if(B==="/.well-known/jwks.json")return b3(aI(await this.getJwks()));if(B==="/.well-known/oauth-protected-resource")return b3(aI(this.getProtectedResourceMetadata(Q,Q)))}if(A.method==="GET"&&B==="/setup")return this.setupFlow.handleSetupPage(A);if(A.method==="GET"&&B==="/login")return this.handleLoginPage(A);if((A.method==="GET"||A.method==="POST")&&B==="/logout")return this.handleLogout(A);if(A.method==="POST"&&B==="/webauthn/register/options")return this.webauthnEndpoints.handleRegistrationOptions(A);if(A.method==="POST"&&B==="/webauthn/register/verify")return this.webauthnEndpoints.handleRegistrationVerify(A);if(A.method==="POST"&&B==="/webauthn/auth/options")return this.webauthnEndpoints.handleAuthenticationOptions(A);if(A.method==="POST"&&B==="/webauthn/auth/verify")return this.webauthnEndpoints.handleAuthenticationVerify(A);if(A.method==="GET"&&B==="/authorize")return this.oauthEndpoints.handleAuthorizePage(A);if(A.method==="POST"&&B==="/authorize")return this.oauthEndpoints.handleAuthorizeApproval(A);if(A.method==="POST"&&B==="/register")return b3(await this.oauthEndpoints.handleClientRegistration(A));if(A.method==="POST"&&B==="/token")return b3(await this.oauthEndpoints.handleTokenRequest(A,Q));if(A.method==="POST"&&B==="/revoke")return b3(await this.oauthEndpoints.handleRevokeRequest(A));return new Response("Not Found",{status:404})}async handleWellKnownRequest(A){return this.handleRequest(A)}resolveRequestIssuer(A){let Q=pk(A,this.issuer);if(this.trustedIssuers.has(Q)||this.allowLocalhostIssuers&&lk(Q))return Q;throw Error(`Request issuer ${Q} is not in trusted issuers`)}handleLoginPage(A){let Q=WEA(new URL(A.url).searchParams.get("return_to"));return ak(HEA(Q))}async handleLogout(A){await this.sessionStore.revokeSessionFromRequest(A);let Q=WEA(new URL(A.url).searchParams.get("return_to"));return new Response(null,{status:302,headers:{Location:Q,"Set-Cookie":iVA($u(A)),"Cache-Control":"no-store"}})}}WA();var e0A="email:send",fE0=H.object({to:H.string().email(),subject:H.string().min(1),text:H.string().min(1),html:H.string().min(1).optional(),sensitivity:H.enum(["normal","secret"]).default("normal")}).strict();aA();WA();var IE0={name:"@brains/notifications",private:!0,version:"0.2.0-alpha.125",description:"Generic notification routing for transactional and administrative messages",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/email-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var zEA="notifications:send",lW2=H.object({}),pW2=H.discriminatedUnion("type",[H.object({type:H.literal("email"),address:H.string().email()}).strict()]),iW2=H.object({recipient:pW2,title:H.string().min(1),body:H.string().min(1),html:H.string().min(1).optional(),sensitivity:H.enum(["normal","secret"]).default("normal")}).strict(),DE0=H.discriminatedUnion("status",[H.object({status:H.literal("sent"),deliveryId:H.string().optional()}).strict(),H.object({status:H.literal("failed")}).strict()]);class UE0 extends YB{constructor(A={}){super("notifications",IE0,A,lW2)}async onRegister(A){A.messaging.subscribe(zEA,async(Q)=>{let B=iW2.parse(Q.payload),w={to:B.recipient.address,subject:B.title,text:B.body,...B.html?{html:B.html}:{},sensitivity:B.sensitivity},$=await A.messaging.send({type:e0A,payload:w});if(!("success"in $)||!$.success||!$.data)return{success:!1,error:"Notification delivery failed"};let f=$.data;if(f.status!=="sent")return{success:!1,error:"Notification delivery failed"};return{success:!0,data:f.id?{status:"sent",deliveryId:f.id}:{status:"sent"}}})}}function A1A(A={}){return new UE0(A)}aA();WA();var YE0={name:"@brains/auth-service",private:!0,version:"0.2.0-alpha.125",description:"Embedded OAuth/OIDC auth service for brain operator authentication",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/notifications":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@simplewebauthn/server":"^13.3.0",jose:"^6.2.3"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},files:["src"]};var dW2=H.union([H.string().email(),H.object({to:H.string().email(),subject:H.string().min(1),body:H.string().min(1)}).strict()]),nW2=H.object({issuer:H.string().optional(),trustedIssuers:H.array(H.string()).default([]),allowLocalhostIssuers:H.boolean().optional(),storageDir:H.string().default("./data/auth"),setupTokenTtlSeconds:H.number().int().positive().default(Yu),setupEmail:dW2.optional()}),oW2=H.object({}),Q1A;function yU(){return Q1A}class qEA extends YB{service;constructor(A={}){super("auth-service",YE0,A,nW2)}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 t0A({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(),Q1A=this.service}async onReady(A){await this.requestSetupEmailIfNeeded(A)}async onShutdown(){if(Q1A===this.service)Q1A=void 0;this.service=void 0}async getTools(){return[oQ(this.id,"get_passkey_setup_url","Get the first-passkey setup URL when operator setup is required. Anchor-only.",oW2,async()=>{let A=this.getService();if(await A.hasPasskeyCredentials())return Y8({status:"complete"});let Q=await A.getOperatorSetupRequired();if(Q)return Y8({status:"setup_required",setupUrl:Q.setupUrl,expiresAt:Q.expiresAt});return Y8({status:"unavailable",reason:"Passkey setup URL is not available."})},{visibility:"anchor"})]}getWebRoutes(){let A=(Q)=>this.getService().handleRequest(Q);return[{path:"/.well-known/oauth-authorization-server",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-authorization-server",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"GET",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"OPTIONS",public:!0,handler:A},{path:"/setup",method:"GET",public:!0,handler:A},{path:"/login",method:"GET",public:!0,handler:A},{path:"/logout",method:"GET",public:!0,handler:A},{path:"/logout",method:"POST",public:!0,handler:A},{path:"/authorize",method:"GET",public:!0,handler:A},{path:"/authorize",method:"POST",public:!0,handler:A},{path:"/register",method:"POST",public:!0,handler:A},{path:"/register",method:"OPTIONS",public:!0,handler:A},{path:"/token",method:"POST",public:!0,handler:A},{path:"/token",method:"OPTIONS",public:!0,handler:A},{path:"/revoke",method:"POST",public:!0,handler:A},{path:"/revoke",method:"OPTIONS",public:!0,handler:A},{path:"/webauthn/register/options",method:"POST",public:!0,handler:A},{path:"/webauthn/register/verify",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/options",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/verify",method:"POST",public:!0,handler:A}]}getService(){if(!this.service)throw Error("AuthServicePlugin has not been registered");return this.service}async requestSetupEmailIfNeeded(A){if(!this.config.setupEmail)return;let Q=this.getService();if(await Q.hasPasskeyCredentials())return;let B=await Q.getOperatorSetupRequired();if(!B)return;let w=sW2(this.config.setupEmail,B);if(await Q.hasSetupEmailDelivery(B.setupTokenId,w.to))return;let $=await A.messaging.send({type:zEA,payload:{recipient:{type:"email",address:w.to},title:w.subject,body:w.body,sensitivity:"secret"}});if(!("success"in $)||!$.success||!$.data){A.logger.warn("Passkey setup email delivery was not confirmed");return}let f=DE0.safeParse($.data);if(!f.success||f.data.status!=="sent"){A.logger.warn("Passkey setup email delivery was not confirmed");return}await Q.recordSetupEmailDelivery(B.setupTokenId,w.to,f.data.deliveryId?{deliveryId:f.data.deliveryId}:{})}}function sW2(A,Q){if(typeof A==="string"){let B=new Date(Q.expiresAt*1000).toISOString(),w=new URL(Q.setupUrl).origin;return{to:A,subject:"Set up your brain passkey",body:["Set up your brain passkey using this single-use link:","",Q.setupUrl,"",`This link expires at ${B}.`,`Dashboard: ${w}/`,`MCP endpoint: ${w}/mcp`,"The first successful passkey registration completes setup and closes this link."].join(`
|
|
2402
|
-
`)}}return{to:A.to,subject:JE0(A.subject,Q),body:JE0(A.body,Q)}}function JE0(A,Q){let B=new Date(Q.expiresAt*1000).toISOString(),w=new URL(Q.setupUrl).origin;return A.replaceAll("{{setupUrl}}",Q.setupUrl).replaceAll("{{expiresAt}}",B).replaceAll("{{origin}}",w)}function Ju(A){return new qEA(A)}WA();var LEA=H.object({transport:H.enum(["stdio","http"]).default("http"),httpPort:H.number().describe("Port for HTTP transport (only used when transport is 'http')").default(3333),authToken:H.string().describe("Bearer token for HTTP transport authentication").optional()});function XE0(A,Q){return[]}aA();function VEA(A,Q){A.messaging.subscribe("job-progress",async(B)=>{let w=ER.safeParse(B.payload);if(!w.success)return Q.warn("Received invalid job-progress message",{error:w.error.message}),{success:!1};let $=w.data,f=$.type,I=$.status,D=$.id;if(Q.debug(`${f} ${D} - ${I}:`,{id:$.id,message:$.message,progress:$.progress,metadata:$.metadata}),$.batchDetails)Q.debug(`Batch details for ${D}:`,{totalOperations:$.batchDetails.totalOperations,completedOperations:$.batchDetails.completedOperations,failedOperations:$.batchDetails.failedOperations,currentOperation:$.batchDetails.currentOperation,errors:$.batchDetails.errors});if($.jobDetails)Q.debug(`Job details for ${D}:`,{jobType:$.jobDetails.jobType,priority:$.jobDetails.priority,retryCount:$.jobDetails.retryCount});return{success:!0}}),Q.debug("Subscribed to job progress events")}var WE0={name:"@brains/mcp",private:!0,version:"0.2.0-alpha.125",type:"module",main:"./src/index.ts",module:"./src/index.ts",types:"./src/index.ts",files:["src"],scripts:{typecheck:"tsc --noEmit",lint:"eslint --max-warnings 0 .","lint:fix":"eslint --fix .",test:"bun test"},dependencies:{"@brains/auth-service":"workspace:*","@brains/mcp-service":"workspace:*","@brains/plugins":"workspace:*","@modelcontextprotocol/sdk":"^1.24.0",cors:"^2.8.5",express:"^4.18.0","express-async-handler":"^1.2.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/cors":"^2.8.17","@types/express":"^4.17.21",typescript:"^5.3.3"}};class P3 extends IW{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",WE0,Q,LEA)}async getTools(){return XE0(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"});VEA(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=yU();return this.httpServer=VK.createFresh({port:this.config.httpPort,logger:this.logger,auth:this.config.authToken?{token:this.config.authToken}:A?{requiredScopes:["mcp"],verifyBearerToken:async(Q)=>A.verifyBearerToken(Q)}:{disabled:!0}}),this.httpServer}getWebRoutes(){if(this.config.transport!=="http")return[];let A=(Q)=>this.getOrCreateHttpServer().handleRequest(Q);return[{path:"/status",method:"GET",public:!0,handler:A},{path:"/mcp",method:"GET",public:!0,handler:A},{path:"/mcp",method:"POST",public:!0,handler:A},{path:"/mcp",method:"DELETE",public:!0,handler:A},{path:"/mcp",method:"OPTIONS",public:!0,handler:A}]}createDaemon(){return{start:async()=>{await this.startServer()},stop:async()=>{await this.stopServer()},healthCheck:async()=>{let A=this.isServerRunning(),Q="MCP server not running";if(A)if(this.config.transport==="http")Q=`MCP HTTP: ${this.domain?`https://${this.domain}/mcp`:"http://localhost:8080/mcp"}`;else Q="MCP stdio server running";return{status:A?"healthy":"error",message:Q,lastCheck:new Date,details:{transport:this.config.transport,url:this.config.transport==="http"?this.domain?`https://${this.domain}/mcp`:"http://localhost:8080/mcp":void 0,running:A}}}}}isServerRunning(){if(this.config.transport==="stdio")return this.stdioServer!==void 0&&this.mcpTransport!==void 0;else return this.httpServer!==void 0&&this.mcpTransport!==void 0}async startServer(){if(!this.context)throw Error("Context not initialized");let A=this.context;this.mcpTransport=A.mcpTransport;let Q=this.config.transport==="stdio"?"stdio":"http",B=this.context.permissions.getUserLevel("mcp",Q);if(this.config.transport==="http"&&(this.config.authToken||yU()))B="anchor",this.logger.debug("HTTP authentication configured - authenticated users will have anchor permissions");if(this.mcpTransport.setPermissionLevel(B),this.logger.debug(`Starting MCP ${this.config.transport} transport with ${B} permissions`),this.config.transport==="stdio"){this.stdioServer=qJ.createFresh();let w=this.mcpTransport.getMcpServer();this.stdioServer.connectMCPServer(w),await this.stdioServer.start(),this.logger.debug("MCP STDIO transport started")}else{this.httpServer=this.getOrCreateHttpServer();let w=this.mcpTransport.getMcpServer();this.httpServer.connectMCPServer(w,this.mcpTransport),this.httpServer.connectAgentService(A.agent),this.logger.debug("MCP HTTP transport mounted on shared webserver host")}}async stopServer(){if(this.logger.debug(`Stopping MCP ${this.config.transport} transport`),this.stdioServer)this.stdioServer.stop(),this.stdioServer=void 0;if(this.httpServer)await this.httpServer.stop(),this.httpServer=void 0;this.mcpTransport=void 0}async handleProgressEvent(A,Q){}async onShutdown(){qJ.resetInstance(),VK.resetInstance()}}aA();WA();var $D=U1(BA1(),1);WA();aA();var wkA=H.object({botToken:H.string().min(1).describe("Discord bot token"),allowedChannels:H.array(H.string()).default([]),requireMention:H.boolean().default(!0),allowDMs:H.boolean().default(!0),showTypingIndicator:H.boolean().default(!0),statusMessage:H.string().default("Mention me to chat"),useThreads:H.boolean().default(!0),threadAutoArchive:H.union([H.literal(60),H.literal(1440),H.literal(4320),H.literal(10080)]).default(1440),...lx.shape,captureUrlEmoji:H.string().default("\uD83D\uDD16")});var wA1={name:"@brains/discord",private:!0,version:"0.2.0-alpha.125",description:"Discord interface for Brains",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",test:"bun test"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*","discord.js":"^14.14.1"},devDependencies:{"@brains/core":"workspace:*","@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest"}};var $BA=2000,Wn2=8000,Hn2=100;function fBA(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class Jz extends eG{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",wA1,A,wkA);this.fetchText=Q.fetchText??Yo}async onRegister(A){await super.onRegister(A),this.client=new $D.Client({intents:[$D.GatewayIntentBits.Guilds,$D.GatewayIntentBits.GuildMessages,$D.GatewayIntentBits.MessageContent,$D.GatewayIntentBits.DirectMessages],partials:[$D.Partials.Channel]}),this.client.on($D.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.on($D.Events.InteractionCreate,(Q)=>{this.handleInteraction(Q)}),this.client.once($D.Events.ClientReady,()=>{this.logger.info("Discord bot connected",{tag:this.client?.user?.tag})})}createDaemon(){return{start:async()=>{if(!this.client)throw Error("Discord client not initialized");await this.client.login(this.config.botToken)},stop:async()=>{for(let A of this.typingIntervals.values())clearInterval(A);if(this.typingIntervals.clear(),this.client)await this.client.destroy(),this.client=null},healthCheck:async()=>({status:this.client?.user?"healthy":"error",message:this.client?.user?`Connected as ${this.client.user.tag}`:"Not connected",lastCheck:new Date})}}sendMessageToChannel({channelId:A,message:Q}){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!fBA(B))return;let w=sT(Q,$BA);for(let $ of w)B.send($).catch((f)=>this.logger.error("Failed to send message",{error:f}))}async sendMessageWithId({channelId:A,message:Q,approvalCard:B,approvalCards:w}){let $=w??(B?[B]:[]),f=$.length>0?this.buildApprovalMessagePayload(Q,$):Q;return this.sendPayloadWithId(A,f)}async sendPayloadWithId(A,Q){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!fBA(B))return;if(typeof Q!=="string")return(await B.send(Q)).id;let w=sT(Q,$BA),$;for(let f of w)$=(await B.send(f)).id;return $}async editMessage({channelId:A,messageId:Q,newMessage:B}){if(!A||!this.client)return!1;let w=this.client.channels.cache.get(A);if(!fBA(w))return!1;try{return await(await w.messages.fetch(Q)).edit(B.slice(0,$BA)),!0}catch{return!1}}supportsMessageEditing(){return!0}async handleMessage(A){if(A.author.id===this.client?.user?.id)return;if(!this.context)return;let Q=!A.guild,B=A.channel.isThread();if(Q&&!this.config.allowDMs)return;let w=!!this.client?.user&&A.mentions.has(this.client.user,{ignoreEveryone:!0});if(A.author.bot&&!w)return;let $=B&&"ownerId"in A.channel&&A.channel.ownerId===this.client?.user?.id,f=this.getSpaceChannelId(A),I=!Q&&this.isConfiguredSpace(f),D={channelId:f,isBot:A.author.bot};if(this.config.allowedChannels.length>0&&!Q&&!this.isAllowedChannel(A.channel.id,f))return;let U=Q||$||!this.config.requireMention||w;if(I&&(!U||this.willRouteUseNonSpaceConversation(A)))await this.capturePassiveSpaceMessage(A,f).catch((X)=>this.logger.error("Passive Discord space capture failed",{error:X,channelId:f}));if(!U){if(this.config.captureUrls){let X=this.extractCaptureableUrls(A.content,this.config.blockedUrlDomains);if(X.length>0){await A.react(this.config.captureUrlEmoji).catch((G)=>this.logger.debug("React failed",{error:G}));for(let G of X)await this.captureUrlViaAgent(G,A.channel.id,A.author.id,"discord",D).catch((Z)=>this.logger.error("URL capture failed",{error:Z,url:G}))}}return}let Y=this.stripMention(A.content);if(A.attachments.size>0){let X=this.context.permissions.getUserLevel("discord",A.author.id,D);if(X==="anchor"||X==="trusted")for(let Z of A.attachments.values()){let N=Z.name,V=Z.contentType??void 0,L=Z.size;if(!this.isUploadableTextFile(N,V))continue;if(!this.isFileSizeAllowed(L))continue;try{let M=await this.fetchText(Z.url);Y+=`
|
|
2401
|
+
</html>`}function Uu(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(HEA(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function rW(A){return A.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""")}import{randomUUID as hW2}from"crypto";function wE0(A){return Buffer.from(JSON.stringify(A)).toString("base64url")}function gW2(A){let Q=new Uint8Array(A);if(Q.length===64)return Q;if(Q[0]!==48)return Q;let B=2;if(Q[1]&&Q[1]>128)B+=Q[1]-128;if(Q[B]!==2)throw Error("Invalid DER ECDSA signature");let w=Q[B+1];if(w===void 0)throw Error("Invalid DER ECDSA signature");let $=B+2,f=Q.slice($,$+w);if(B=$+w,Q[B]!==2)throw Error("Invalid DER ECDSA signature");let I=Q[B+1];if(I===void 0)throw Error("Invalid DER ECDSA signature");let D=B+2,U=Q.slice(D,D+I);return new Uint8Array([...$E0(f),...$E0(U)])}function $E0(A){let Q=A;while(Q.length>32&&Q[0]===0)Q=Q.slice(1);if(Q.length>32)throw Error("Invalid P-256 signature component length");if(Q.length===32)return Q;let B=new Uint8Array(32);return B.set(Q,32-Q.length),B}async function KEA(A,Q){let B={typ:"JWT",alg:"ES256",kid:A.kid},w=`${wE0(B)}.${wE0(Q)}`,$=await crypto.subtle.importKey("jwk",A,{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),f=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},$,new TextEncoder().encode(w));return`${w}.${Buffer.from(gW2(f)).toString("base64url")}`}var mW2=600;class FEA{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 Uu(A);let B=await this.validateAuthorizationRequest(new URL(A.url).searchParams);if(!B.success)return new Response(B.error,{status:400});let w=this.createAuthorizationApprovalToken(Q,B.params);return ak(BE0(B.params,w))}async handleAuthorizeApproval(A){let Q=await this.sessionStore.getSessionFromRequest(A);if(!Q)return Uu(A);let B=await A.formData(),w=await this.validateAuthorizationRequest(new URLSearchParams(YEA(B)));if(!w.success)return new Response(w.error,{status:400});let $=B.get("approval_token"),f=typeof $==="string"?$:void 0;if(!f||!this.consumeAuthorizationApprovalToken(f,Q,w.params))return new Response("Invalid authorization approval token",{status:400});let I=await this.authCodeStore.createCode({clientId:w.params.clientId,redirectUri:w.params.redirectUri,codeChallenge:w.params.codeChallenge,...w.params.scope?{scope:w.params.scope}:{},subject:Q.subject}),D=new URL(w.params.redirectUri);if(D.searchParams.set("code",I.code),w.params.state)D.searchParams.set("state",w.params.state);return Response.redirect(D.toString(),302)}createAuthorizationApprovalToken(A,Q){this.pruneExpiredAuthorizationApprovalTokens();let B=`oat_${hW2()}`;return this.authorizationApprovalTokens.set(B,{token:B,sessionId:A.id,clientId:Q.clientId,redirectUri:Q.redirectUri,codeChallenge:Q.codeChallenge,...Q.scope?{scope:Q.scope}:{},...Q.state?{state:Q.state}:{},expiresAt:Math.floor(Date.now()/1000)+mW2}),B}consumeAuthorizationApprovalToken(A,Q,B){this.pruneExpiredAuthorizationApprovalTokens();let w=this.authorizationApprovalTokens.get(A);if(!w)return!1;return this.authorizationApprovalTokens.delete(A),w.sessionId===Q.id&&w.clientId===B.clientId&&w.redirectUri===B.redirectUri&&w.codeChallenge===B.codeChallenge&&w.scope===B.scope&&w.state===B.state}pruneExpiredAuthorizationApprovalTokens(){let A=Math.floor(Date.now()/1000);for(let[Q,B]of this.authorizationApprovalTokens.entries())if(B.expiresAt<=A)this.authorizationApprovalTokens.delete(Q)}async validateAuthorizationRequest(A){let Q=A.get("response_type"),B=A.get("client_id"),w=A.get("redirect_uri"),$=A.get("code_challenge"),f=A.get("code_challenge_method"),I=A.get("scope")??void 0,D=A.get("state")??void 0;if(Q!=="code")return{success:!1,error:"Unsupported response_type"};if(!B)return{success:!1,error:"Missing client_id"};if(!w)return{success:!1,error:"Missing redirect_uri"};if(!$)return{success:!1,error:"Missing code_challenge"};if(f!=="S256")return{success:!1,error:"Unsupported code_challenge_method"};let U=await this.clientStore.getClient(B);if(!U)return{success:!1,error:"Unknown client_id"};if(!lzA(U.redirect_uris,w))return{success:!1,error:"Unregistered redirect_uri"};let Y=I??U.scope;return{success:!0,params:{clientId:B,redirectUri:w,codeChallenge:$,...Y?{scope:Y}:{},...D?{state:D}:{},clientName:U.client_name??U.client_id}}}async handleClientRegistration(A){let Q;try{Q=await A.json()}catch{return q6("invalid_client_metadata","Request body must be JSON")}try{let B=await this.clientStore.registerClient(Q);return aI(B,201)}catch(B){if(B instanceof qh)return q6("invalid_client_metadata",B.message);throw B}}async handleTokenRequest(A,Q){let B=await UEA(A),w=B.get("grant_type"),$=XEA(A,B),f=$.clientId??B.get("client_id");if($.error)return q6("invalid_client",$.error);if(!f)return q6("invalid_request","client_id is required");let I=await this.clientStore.getClient(f),D=JEA(I,$);if(D)return q6("invalid_client",D);if(w==="authorization_code")return this.handleAuthorizationCodeGrant(B,f,Q);if(w==="refresh_token")return this.handleRefreshTokenGrant(B,f,Q);return q6("unsupported_grant_type","Only authorization_code and refresh_token are supported")}async handleAuthorizationCodeGrant(A,Q,B){let w=A.get("code"),$=A.get("redirect_uri"),f=A.get("code_verifier");if(!w||!$||!f)return q6("invalid_request","code, redirect_uri, and code_verifier are required");let I=await this.clientStore.getClient(Q);if(!I||!lzA(I.redirect_uris,$))return q6("invalid_grant","Unregistered redirect_uri");try{let D=await this.authCodeStore.consumeCode({code:w,clientId:Q,redirectUri:$,codeVerifier:f});return await this.createTokenResponse({issuer:B,clientId:Q,subject:D.subject,...D.scope?{scope:D.scope}:{}})}catch(D){if(D instanceof LJ)return q6("invalid_grant",D.message);throw D}}async handleRefreshTokenGrant(A,Q,B){let w=A.get("refresh_token");if(!w)return q6("invalid_request","refresh_token is required");try{let $=await this.refreshTokenStore.rotateToken(w,Q);return await this.createTokenResponse({issuer:B,clientId:Q,subject:$.consumed.subject,...$.consumed.scope?{scope:$.consumed.scope}:{},refreshToken:$.replacement.token})}catch($){if($ instanceof rK)return q6("invalid_grant",$.message);throw $}}async createTokenResponse(A){let Q=Math.floor(Date.now()/1000),B=900,w=await KEA(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 aI({access_token:w,token_type:"Bearer",expires_in:900,...A.scope?{scope:A.scope}:{},refresh_token:$})}async handleRevokeRequest(A){let Q=await UEA(A),B=XEA(A,Q),w=B.clientId??Q.get("client_id")??void 0,$=Q.get("token");if(B.error)return q6("invalid_client",B.error);if(!$)return q6("invalid_request","token is required");if(w){let f=await this.clientStore.getClient(w),I=JEA(f,B);if(I)return q6("invalid_client",I)}return await this.refreshTokenStore.revokeToken($,w),new Response(null,{status:200})}}class ZEA{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 q6("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return q6("access_denied","Invalid setup token");let Q=await this.passkeyService.generateRegistrationOptions(a0A(A));return aI(Q)}async handleRegistrationVerify(A){if(await this.passkeyService.hasCredentials())return q6("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return q6("access_denied","Invalid setup token");let Q=await this.passkeyService.verifyRegistrationResponse(await A.json(),a0A(A));if(!Q.verified)return q6("access_denied","Passkey registration failed");await this.setupFlow.clearSetupState();let B=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:$u(A)});return aI({verified:!0},200,{"Set-Cookie":B.cookie})}async handleAuthenticationOptions(A){if(!await this.passkeyService.hasCredentials())return q6("access_denied","No passkey registered");let Q=await this.passkeyService.generateAuthenticationOptions(a0A(A));return aI(Q)}async handleAuthenticationVerify(A){let Q=await this.passkeyService.verifyAuthenticationResponse(await A.json(),a0A(A));if(!Q.verified)return q6("access_denied","Passkey authentication failed");let B=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:$u(A)});return aI({verified:!0},200,{"Set-Cookie":B.cookie})}}function a0A(A){let Q=pk(A),B=new URL(Q);return{origin:B.origin,rpID:B.hostname}}import{randomUUID as uW2}from"crypto";var Yu=86400;class NEA{setupStateStore;passkeyService;setupTokenTtlSeconds;setupToken;constructor(A){this.setupStateStore=A.setupStateStore,this.passkeyService=A.passkeyService,this.setupTokenTtlSeconds=A.setupTokenTtlSeconds??Yu}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_${uW2()}`,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 B=new URL(A.url);return(B.searchParams.get("setup_token")??B.searchParams.get("token"))===Q.token}async clearSetupState(){this.setupToken=void 0,await this.setupStateStore.clearSetupState()}getSetupUrl(A){let Q=this.getValidSetupToken();if(!Q)return;return iW(A,`/setup?token=${encodeURIComponent(Q.token)}`)}async getOperatorSetupRequired(A){if(await this.passkeyService.hasCredentials())return;let Q=this.getValidSetupToken();if(!Q)return;return{setupUrl:iW(A,`/setup?token=${encodeURIComponent(Q.token)}`),expiresAt:Q.expiresAt,setupTokenId:uVA(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 ak(AE0(Q))}async hasSetupEmailDelivery(A,Q){return this.setupStateStore.hasDelivery(A,Q)}async recordSetupEmailDelivery(A,Q,B={}){await this.setupStateStore.recordDelivery(A,Q,B)}}class t0A{issuer;trustedIssuers;allowLocalhostIssuers;keyStore;clientStore;authCodeStore;sessionStore;passkeyService;setupFlow;oauthEndpoints;webauthnEndpoints;logger;constructor(A){this.issuer=_J(A.issuer),this.trustedIssuers=new Set([this.issuer,...(A.trustedIssuers??[]).map((Q)=>_J(Q))]),this.allowLocalhostIssuers=A.allowLocalhostIssuers??lk(this.issuer),this.keyStore=new HAA({storageDir:A.storageDir}),this.clientStore=new WAA({storageDir:A.storageDir}),this.authCodeStore=new XAA({storageDir:A.storageDir}),this.sessionStore=new r0A({storageDir:A.storageDir}),this.passkeyService=new u0A({storageDir:A.storageDir,...A.logger?{logger:A.logger}:{}}),this.setupFlow=new NEA({setupStateStore:new cVA({storageDir:A.storageDir}),passkeyService:this.passkeyService,setupTokenTtlSeconds:A.setupTokenTtlSeconds??Yu}),this.oauthEndpoints=new FEA({clientStore:this.clientStore,authCodeStore:this.authCodeStore,refreshTokenStore:new l0A({storageDir:A.storageDir}),sessionStore:this.sessionStore,keyStore:this.keyStore}),this.webauthnEndpoints=new ZEA({passkeyService:this.passkeyService,sessionStore:this.sessionStore,setupFlow:this.setupFlow}),this.logger=A.logger}getIssuer(){return this.issuer}async initialize(){if(await this.keyStore.getPrivateJwk(),this.logger?.debug("Auth service signing key loaded"),!await this.hasPasskeyCredentials()){await this.setupFlow.ensureSetupToken();let A=this.getSetupUrl();if(A)if(lk(this.issuer))this.logger?.warn(`Passkey setup required: ${A}`);else this.logger?.warn("Passkey setup required. Ask through an anchor-visible interface for the setup URL.")}}async hasPasskeyCredentials(){return this.passkeyService.hasCredentials()}async getJwks(){return{keys:[await this.keyStore.getPublicJwk()]}}getAuthorizationServerMetadata(A=this.issuer){let Q=_J(A);return{issuer:Q,authorization_endpoint:iW(Q,"/authorize"),token_endpoint:iW(Q,"/token"),registration_endpoint:iW(Q,"/register"),revocation_endpoint:iW(Q,"/revoke"),jwks_uri:iW(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:[_J(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 Uu(A)}async verifyBearerToken(A,Q={}){let B=DEA(A);if(!B)return;let w=Q.issuer?_J(Q.issuer):this.resolveRequestIssuer(A);return IEA(B,await this.getJwks(),{issuer:w,...Q.audience?{audience:Q.audience}:{}})}getSetupUrl(A=this.issuer){return this.setupFlow.getSetupUrl(A)}async getOperatorSetupRequired(A=this.issuer){return this.setupFlow.getOperatorSetupRequired(A)}async hasSetupEmailDelivery(A,Q){return this.setupFlow.hasSetupEmailDelivery(A,Q)}async recordSetupEmailDelivery(A,Q,B={}){await this.setupFlow.recordSetupEmailDelivery(A,Q,B)}async handleRequest(A){let Q;try{Q=this.resolveRequestIssuer(A)}catch(w){return this.logger?.warn("Rejected OAuth request from untrusted issuer",{error:w instanceof Error?w.message:String(w)}),new Response("Untrusted OAuth issuer",{status:400})}let B=new URL(A.url).pathname;if(A.method==="OPTIONS"&&aV0(B))return tV0();if(A.method==="GET"){if(B==="/.well-known/oauth-authorization-server")return b3(aI(this.getAuthorizationServerMetadata(Q)));if(B==="/.well-known/jwks.json")return b3(aI(await this.getJwks()));if(B==="/.well-known/oauth-protected-resource")return b3(aI(this.getProtectedResourceMetadata(Q,Q)))}if(A.method==="GET"&&B==="/setup")return this.setupFlow.handleSetupPage(A);if(A.method==="GET"&&B==="/login")return this.handleLoginPage(A);if((A.method==="GET"||A.method==="POST")&&B==="/logout")return this.handleLogout(A);if(A.method==="POST"&&B==="/webauthn/register/options")return this.webauthnEndpoints.handleRegistrationOptions(A);if(A.method==="POST"&&B==="/webauthn/register/verify")return this.webauthnEndpoints.handleRegistrationVerify(A);if(A.method==="POST"&&B==="/webauthn/auth/options")return this.webauthnEndpoints.handleAuthenticationOptions(A);if(A.method==="POST"&&B==="/webauthn/auth/verify")return this.webauthnEndpoints.handleAuthenticationVerify(A);if(A.method==="GET"&&B==="/authorize")return this.oauthEndpoints.handleAuthorizePage(A);if(A.method==="POST"&&B==="/authorize")return this.oauthEndpoints.handleAuthorizeApproval(A);if(A.method==="POST"&&B==="/register")return b3(await this.oauthEndpoints.handleClientRegistration(A));if(A.method==="POST"&&B==="/token")return b3(await this.oauthEndpoints.handleTokenRequest(A,Q));if(A.method==="POST"&&B==="/revoke")return b3(await this.oauthEndpoints.handleRevokeRequest(A));return new Response("Not Found",{status:404})}async handleWellKnownRequest(A){return this.handleRequest(A)}resolveRequestIssuer(A){let Q=pk(A,this.issuer);if(this.trustedIssuers.has(Q)||this.allowLocalhostIssuers&&lk(Q))return Q;throw Error(`Request issuer ${Q} is not in trusted issuers`)}handleLoginPage(A){let Q=WEA(new URL(A.url).searchParams.get("return_to"));return ak(HEA(Q))}async handleLogout(A){await this.sessionStore.revokeSessionFromRequest(A);let Q=WEA(new URL(A.url).searchParams.get("return_to"));return new Response(null,{status:302,headers:{Location:Q,"Set-Cookie":iVA($u(A)),"Cache-Control":"no-store"}})}}WA();var e0A="email:send",fE0=H.object({to:H.string().email(),subject:H.string().min(1),text:H.string().min(1),html:H.string().min(1).optional(),sensitivity:H.enum(["normal","secret"]).default("normal")}).strict();aA();WA();var IE0={name:"@brains/notifications",private:!0,version:"0.2.0-alpha.127",description:"Generic notification routing for transactional and administrative messages",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/email-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var zEA="notifications:send",lW2=H.object({}),pW2=H.discriminatedUnion("type",[H.object({type:H.literal("email"),address:H.string().email()}).strict()]),iW2=H.object({recipient:pW2,title:H.string().min(1),body:H.string().min(1),html:H.string().min(1).optional(),sensitivity:H.enum(["normal","secret"]).default("normal")}).strict(),DE0=H.discriminatedUnion("status",[H.object({status:H.literal("sent"),deliveryId:H.string().optional()}).strict(),H.object({status:H.literal("failed")}).strict()]);class UE0 extends YB{constructor(A={}){super("notifications",IE0,A,lW2)}async onRegister(A){A.messaging.subscribe(zEA,async(Q)=>{let B=iW2.parse(Q.payload),w={to:B.recipient.address,subject:B.title,text:B.body,...B.html?{html:B.html}:{},sensitivity:B.sensitivity},$=await A.messaging.send({type:e0A,payload:w});if(!("success"in $)||!$.success||!$.data)return{success:!1,error:"Notification delivery failed"};let f=$.data;if(f.status!=="sent")return{success:!1,error:"Notification delivery failed"};return{success:!0,data:f.id?{status:"sent",deliveryId:f.id}:{status:"sent"}}})}}function A1A(A={}){return new UE0(A)}aA();WA();var YE0={name:"@brains/auth-service",private:!0,version:"0.2.0-alpha.127",description:"Embedded OAuth/OIDC auth service for brain operator authentication",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/notifications":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@simplewebauthn/server":"^13.3.0",jose:"^6.2.3"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},files:["src"]};var dW2=H.union([H.string().email(),H.object({to:H.string().email(),subject:H.string().min(1),body:H.string().min(1)}).strict()]),nW2=H.object({issuer:H.string().optional(),trustedIssuers:H.array(H.string()).default([]),allowLocalhostIssuers:H.boolean().optional(),storageDir:H.string().default("./data/auth"),setupTokenTtlSeconds:H.number().int().positive().default(Yu),setupEmail:dW2.optional()}),oW2=H.object({}),Q1A;function yU(){return Q1A}class qEA extends YB{service;constructor(A={}){super("auth-service",YE0,A,nW2)}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 t0A({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(),Q1A=this.service}async onReady(A){await this.requestSetupEmailIfNeeded(A)}async onShutdown(){if(Q1A===this.service)Q1A=void 0;this.service=void 0}async getTools(){return[oQ(this.id,"get_passkey_setup_url","Get the first-passkey setup URL when operator setup is required. Anchor-only.",oW2,async()=>{let A=this.getService();if(await A.hasPasskeyCredentials())return Y8({status:"complete"});let Q=await A.getOperatorSetupRequired();if(Q)return Y8({status:"setup_required",setupUrl:Q.setupUrl,expiresAt:Q.expiresAt});return Y8({status:"unavailable",reason:"Passkey setup URL is not available."})},{visibility:"anchor"})]}getWebRoutes(){let A=(Q)=>this.getService().handleRequest(Q);return[{path:"/.well-known/oauth-authorization-server",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-authorization-server",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"GET",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"OPTIONS",public:!0,handler:A},{path:"/setup",method:"GET",public:!0,handler:A},{path:"/login",method:"GET",public:!0,handler:A},{path:"/logout",method:"GET",public:!0,handler:A},{path:"/logout",method:"POST",public:!0,handler:A},{path:"/authorize",method:"GET",public:!0,handler:A},{path:"/authorize",method:"POST",public:!0,handler:A},{path:"/register",method:"POST",public:!0,handler:A},{path:"/register",method:"OPTIONS",public:!0,handler:A},{path:"/token",method:"POST",public:!0,handler:A},{path:"/token",method:"OPTIONS",public:!0,handler:A},{path:"/revoke",method:"POST",public:!0,handler:A},{path:"/revoke",method:"OPTIONS",public:!0,handler:A},{path:"/webauthn/register/options",method:"POST",public:!0,handler:A},{path:"/webauthn/register/verify",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/options",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/verify",method:"POST",public:!0,handler:A}]}getService(){if(!this.service)throw Error("AuthServicePlugin has not been registered");return this.service}async requestSetupEmailIfNeeded(A){if(!this.config.setupEmail)return;let Q=this.getService();if(await Q.hasPasskeyCredentials())return;let B=await Q.getOperatorSetupRequired();if(!B)return;let w=sW2(this.config.setupEmail,B);if(await Q.hasSetupEmailDelivery(B.setupTokenId,w.to))return;let $=await A.messaging.send({type:zEA,payload:{recipient:{type:"email",address:w.to},title:w.subject,body:w.body,sensitivity:"secret"}});if(!("success"in $)||!$.success||!$.data){A.logger.warn("Passkey setup email delivery was not confirmed");return}let f=DE0.safeParse($.data);if(!f.success||f.data.status!=="sent"){A.logger.warn("Passkey setup email delivery was not confirmed");return}await Q.recordSetupEmailDelivery(B.setupTokenId,w.to,f.data.deliveryId?{deliveryId:f.data.deliveryId}:{})}}function sW2(A,Q){if(typeof A==="string"){let B=new Date(Q.expiresAt*1000).toISOString(),w=new URL(Q.setupUrl).origin;return{to:A,subject:"Set up your brain passkey",body:["Set up your brain passkey using this single-use link:","",Q.setupUrl,"",`This link expires at ${B}.`,`Dashboard: ${w}/`,`MCP endpoint: ${w}/mcp`,"The first successful passkey registration completes setup and closes this link."].join(`
|
|
2402
|
+
`)}}return{to:A.to,subject:JE0(A.subject,Q),body:JE0(A.body,Q)}}function JE0(A,Q){let B=new Date(Q.expiresAt*1000).toISOString(),w=new URL(Q.setupUrl).origin;return A.replaceAll("{{setupUrl}}",Q.setupUrl).replaceAll("{{expiresAt}}",B).replaceAll("{{origin}}",w)}function Ju(A){return new qEA(A)}WA();var LEA=H.object({transport:H.enum(["stdio","http"]).default("http"),httpPort:H.number().describe("Port for HTTP transport (only used when transport is 'http')").default(3333),authToken:H.string().describe("Bearer token for HTTP transport authentication").optional()});function XE0(A,Q){return[]}aA();function VEA(A,Q){A.messaging.subscribe("job-progress",async(B)=>{let w=ER.safeParse(B.payload);if(!w.success)return Q.warn("Received invalid job-progress message",{error:w.error.message}),{success:!1};let $=w.data,f=$.type,I=$.status,D=$.id;if(Q.debug(`${f} ${D} - ${I}:`,{id:$.id,message:$.message,progress:$.progress,metadata:$.metadata}),$.batchDetails)Q.debug(`Batch details for ${D}:`,{totalOperations:$.batchDetails.totalOperations,completedOperations:$.batchDetails.completedOperations,failedOperations:$.batchDetails.failedOperations,currentOperation:$.batchDetails.currentOperation,errors:$.batchDetails.errors});if($.jobDetails)Q.debug(`Job details for ${D}:`,{jobType:$.jobDetails.jobType,priority:$.jobDetails.priority,retryCount:$.jobDetails.retryCount});return{success:!0}}),Q.debug("Subscribed to job progress events")}var WE0={name:"@brains/mcp",private:!0,version:"0.2.0-alpha.127",type:"module",main:"./src/index.ts",module:"./src/index.ts",types:"./src/index.ts",files:["src"],scripts:{typecheck:"tsc --noEmit",lint:"eslint --max-warnings 0 .","lint:fix":"eslint --fix .",test:"bun test"},dependencies:{"@brains/auth-service":"workspace:*","@brains/mcp-service":"workspace:*","@brains/plugins":"workspace:*","@modelcontextprotocol/sdk":"^1.24.0",cors:"^2.8.5",express:"^4.18.0","express-async-handler":"^1.2.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/cors":"^2.8.17","@types/express":"^4.17.21",typescript:"^5.3.3"}};class P3 extends IW{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",WE0,Q,LEA)}async getTools(){return XE0(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"});VEA(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=yU();return this.httpServer=VK.createFresh({port:this.config.httpPort,logger:this.logger,auth:this.config.authToken?{token:this.config.authToken}:A?{requiredScopes:["mcp"],verifyBearerToken:async(Q)=>A.verifyBearerToken(Q)}:{disabled:!0}}),this.httpServer}getWebRoutes(){if(this.config.transport!=="http")return[];let A=(Q)=>this.getOrCreateHttpServer().handleRequest(Q);return[{path:"/status",method:"GET",public:!0,handler:A},{path:"/mcp",method:"GET",public:!0,handler:A},{path:"/mcp",method:"POST",public:!0,handler:A},{path:"/mcp",method:"DELETE",public:!0,handler:A},{path:"/mcp",method:"OPTIONS",public:!0,handler:A}]}createDaemon(){return{start:async()=>{await this.startServer()},stop:async()=>{await this.stopServer()},healthCheck:async()=>{let A=this.isServerRunning(),Q="MCP server not running";if(A)if(this.config.transport==="http")Q=`MCP HTTP: ${this.domain?`https://${this.domain}/mcp`:"http://localhost:8080/mcp"}`;else Q="MCP stdio server running";return{status:A?"healthy":"error",message:Q,lastCheck:new Date,details:{transport:this.config.transport,url:this.config.transport==="http"?this.domain?`https://${this.domain}/mcp`:"http://localhost:8080/mcp":void 0,running:A}}}}}isServerRunning(){if(this.config.transport==="stdio")return this.stdioServer!==void 0&&this.mcpTransport!==void 0;else return this.httpServer!==void 0&&this.mcpTransport!==void 0}async startServer(){if(!this.context)throw Error("Context not initialized");let A=this.context;this.mcpTransport=A.mcpTransport;let Q=this.config.transport==="stdio"?"stdio":"http",B=this.context.permissions.getUserLevel("mcp",Q);if(this.config.transport==="http"&&(this.config.authToken||yU()))B="anchor",this.logger.debug("HTTP authentication configured - authenticated users will have anchor permissions");if(this.mcpTransport.setPermissionLevel(B),this.logger.debug(`Starting MCP ${this.config.transport} transport with ${B} permissions`),this.config.transport==="stdio"){this.stdioServer=qJ.createFresh();let w=this.mcpTransport.getMcpServer();this.stdioServer.connectMCPServer(w),await this.stdioServer.start(),this.logger.debug("MCP STDIO transport started")}else{this.httpServer=this.getOrCreateHttpServer();let w=this.mcpTransport.getMcpServer();this.httpServer.connectMCPServer(w,this.mcpTransport),this.httpServer.connectAgentService(A.agent),this.logger.debug("MCP HTTP transport mounted on shared webserver host")}}async stopServer(){if(this.logger.debug(`Stopping MCP ${this.config.transport} transport`),this.stdioServer)this.stdioServer.stop(),this.stdioServer=void 0;if(this.httpServer)await this.httpServer.stop(),this.httpServer=void 0;this.mcpTransport=void 0}async handleProgressEvent(A,Q){}async onShutdown(){qJ.resetInstance(),VK.resetInstance()}}aA();WA();var $D=U1(BA1(),1);WA();aA();var wkA=H.object({botToken:H.string().min(1).describe("Discord bot token"),allowedChannels:H.array(H.string()).default([]),requireMention:H.boolean().default(!0),allowDMs:H.boolean().default(!0),showTypingIndicator:H.boolean().default(!0),statusMessage:H.string().default("Mention me to chat"),useThreads:H.boolean().default(!0),threadAutoArchive:H.union([H.literal(60),H.literal(1440),H.literal(4320),H.literal(10080)]).default(1440),...lx.shape,captureUrlEmoji:H.string().default("\uD83D\uDD16")});var wA1={name:"@brains/discord",private:!0,version:"0.2.0-alpha.127",description:"Discord interface for Brains",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",test:"bun test"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*","discord.js":"^14.14.1"},devDependencies:{"@brains/core":"workspace:*","@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest"}};var $BA=2000,Wn2=8000,Hn2=100;function fBA(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class Jz extends eG{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",wA1,A,wkA);this.fetchText=Q.fetchText??Yo}async onRegister(A){await super.onRegister(A),this.client=new $D.Client({intents:[$D.GatewayIntentBits.Guilds,$D.GatewayIntentBits.GuildMessages,$D.GatewayIntentBits.MessageContent,$D.GatewayIntentBits.DirectMessages],partials:[$D.Partials.Channel]}),this.client.on($D.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.on($D.Events.InteractionCreate,(Q)=>{this.handleInteraction(Q)}),this.client.once($D.Events.ClientReady,()=>{this.logger.info("Discord bot connected",{tag:this.client?.user?.tag})})}createDaemon(){return{start:async()=>{if(!this.client)throw Error("Discord client not initialized");await this.client.login(this.config.botToken)},stop:async()=>{for(let A of this.typingIntervals.values())clearInterval(A);if(this.typingIntervals.clear(),this.client)await this.client.destroy(),this.client=null},healthCheck:async()=>({status:this.client?.user?"healthy":"error",message:this.client?.user?`Connected as ${this.client.user.tag}`:"Not connected",lastCheck:new Date})}}sendMessageToChannel({channelId:A,message:Q}){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!fBA(B))return;let w=sT(Q,$BA);for(let $ of w)B.send($).catch((f)=>this.logger.error("Failed to send message",{error:f}))}async sendMessageWithId({channelId:A,message:Q,approvalCard:B,approvalCards:w}){let $=w??(B?[B]:[]),f=$.length>0?this.buildApprovalMessagePayload(Q,$):Q;return this.sendPayloadWithId(A,f)}async sendPayloadWithId(A,Q){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!fBA(B))return;if(typeof Q!=="string")return(await B.send(Q)).id;let w=sT(Q,$BA),$;for(let f of w)$=(await B.send(f)).id;return $}async editMessage({channelId:A,messageId:Q,newMessage:B}){if(!A||!this.client)return!1;let w=this.client.channels.cache.get(A);if(!fBA(w))return!1;try{return await(await w.messages.fetch(Q)).edit(B.slice(0,$BA)),!0}catch{return!1}}supportsMessageEditing(){return!0}async handleMessage(A){if(A.author.id===this.client?.user?.id)return;if(!this.context)return;let Q=!A.guild,B=A.channel.isThread();if(Q&&!this.config.allowDMs)return;let w=!!this.client?.user&&A.mentions.has(this.client.user,{ignoreEveryone:!0});if(A.author.bot&&!w)return;let $=B&&"ownerId"in A.channel&&A.channel.ownerId===this.client?.user?.id,f=this.getSpaceChannelId(A),I=!Q&&this.isConfiguredSpace(f),D={channelId:f,isBot:A.author.bot};if(this.config.allowedChannels.length>0&&!Q&&!this.isAllowedChannel(A.channel.id,f))return;let U=Q||$||!this.config.requireMention||w;if(I&&(!U||this.willRouteUseNonSpaceConversation(A)))await this.capturePassiveSpaceMessage(A,f).catch((X)=>this.logger.error("Passive Discord space capture failed",{error:X,channelId:f}));if(!U){if(this.config.captureUrls){let X=this.extractCaptureableUrls(A.content,this.config.blockedUrlDomains);if(X.length>0){await A.react(this.config.captureUrlEmoji).catch((G)=>this.logger.debug("React failed",{error:G}));for(let G of X)await this.captureUrlViaAgent(G,A.channel.id,A.author.id,"discord",D).catch((Z)=>this.logger.error("URL capture failed",{error:Z,url:G}))}}return}let Y=this.stripMention(A.content);if(A.attachments.size>0){let X=this.context.permissions.getUserLevel("discord",A.author.id,D);if(X==="anchor"||X==="trusted")for(let Z of A.attachments.values()){let N=Z.name,V=Z.contentType??void 0,L=Z.size;if(!this.isUploadableTextFile(N,V))continue;if(!this.isFileSizeAllowed(L))continue;try{let M=await this.fetchText(Z.url);Y+=`
|
|
2403
2403
|
|
|
2404
2404
|
`+this.formatFileUploadMessage(N,M)}catch(M){this.logger.error("Failed to download attachment",{error:M,filename:N})}}}if(Y=Y.trim(),!Y)return;let J=A.channel.id;await this.routeToAgent(Y,J,A,D)}async handleInteraction(A){if(!this.context||!A.isButton())return;let Q=this.parseApprovalButtonCustomId(A.customId);if(!Q)return;let B=`discord-${A.channelId}`;if(!this.pendingConfirmations.get(B)?.has(Q.approvalId)){await A.reply({content:"This approval is no longer pending or has changed.",ephemeral:!0}).catch((f)=>this.logger.debug("Failed to reply to stale approval button",{error:f}));return}await A.deferUpdate().catch((f)=>this.logger.debug("Failed to defer approval button",{error:f}));let $=await this.context.agent.confirmPendingAction(B,Q.confirmed,Q.approvalId,this.buildInteractionConfirmationContext(A));this.syncPendingApprovalsAfterResolution(B,Q.approvalId,$),await this.sendApprovalResultMessage({channelId:A.channelId,response:$})}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 B=this.stripMention(A.content).trim();if(!B)return;let w=`discord-${Q}`,$=this.getChannelName(A);await this.context.conversations.start({sessionId:w,interfaceType:"discord",channelId:Q,metadata:{channelName:$,interfaceType:"discord",channelId:Q}}),await this.context.conversations.addMessage({conversationId:w,role:"user",content:B,metadata:this.buildUserMessageMetadata(A,Q,$,{threadId:A.channel.isThread()?A.channel.id:void 0})})}async routeToAgent(A,Q,B,w){if(!this.context)return;let $=this.context.agent,f=Q;if(this.config.useThreads&&B.guild&&!B.channel.isThread())try{f=(await B.startThread({name:K7(A,Hn2),autoArchiveDuration:this.config.threadAutoArchive})).id}catch(Y){this.logger.error("Failed to create thread",{error:Y})}let I=`discord-${f}`,D=this.context.permissions.getUserLevel("discord",B.author.id,w),U=this.getChannelName(B);this.startProcessingInput(f);try{let Y=this.client?.channels.cache.get(f);if(fBA(Y))this.startTypingIndicator(Y);if(this.pendingConfirmations.has(I)){await this.handleConfirmationResponse(A,I,f,B,w);return}let J=await $.chat(A,I,{userPermissionLevel:D,interfaceType:"discord",channelId:f,channelName:U,...this.buildUserMessageMetadata(B,Q,U,{threadId:f!==Q||B.channel.isThread()?f:void 0})}),X=this.getPendingApprovalCards(J.cards);if(X.length>0)this.pendingConfirmations.set(I,new Set(X.map((Z)=>Z.id)));else if(J.pendingConfirmations)this.pendingConfirmations.set(I,new Set(J.pendingConfirmations.map((Z)=>Z.id)));let G=await this.sendMessageWithId({channelId:f,message:this.formatAgentResponseText(J.text,X),approvalCards:X});if(G&&J.toolResults){for(let Z of J.toolResults)if(Z.jobId)this.trackAgentResponseForJob(Z.jobId,G,f)}}catch(Y){this.logger.error("Error handling message",{error:Y,channelId:f}),this.sendMessageToChannel({channelId:f,message:`**Error:** ${Y instanceof Error?Y.message:"Unknown error"}`})}finally{this.endProcessingInput(),this.stopTypingIndicator(f)}}buildApprovalMessagePayload(A,Q){let B=Q.length>1;return{content:K7(A.trim().length>0?`${A}
|
|
2405
2405
|
|
|
@@ -2470,7 +2470,7 @@ Use the buttons below${B?" for the matching action":", or reply **yes** / **no**
|
|
|
2470
2470
|
<p>Once built, this page will be replaced with your actual website.</p>
|
|
2471
2471
|
</div>
|
|
2472
2472
|
</body>
|
|
2473
|
-
</html>`;var xA1={name:"@brains/webserver",private:!0,version:"0.2.0-alpha.
|
|
2473
|
+
</html>`;var xA1={name:"@brains/webserver",private:!0,version:"0.2.0-alpha.127",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts"},dependencies:{"@brains/plugins":"workspace:*","@hono/bun-compress":"^0.1.0",hono:"^4.7.10"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/messaging-service":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/node":"^20.0.0",eslint:"^8.56.0",typescript:"^5.3.3"}};class Xz extends IW{serverManager;siteUrl;previewUrl;constructor(A={}){super("webserver",xA1,A,NkA)}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 ZBA({logger:A.logger,productionDistDir:this.config.productionDistDir,sharedImagesDir:this.config.sharedImagesDir,productionPort:this.config.productionPort,...this.config.enablePreview&&this.config.previewDistDir&&{previewDistDir:this.config.previewDistDir},...this.config.enablePreview&&this.config.previewPort&&{previewPort:this.config.previewPort},getHealthData:()=>A.appInfo(),getWebRoutes:()=>A.webRoutes.getRoutes(),getApiRoutes:()=>A.apiRoutes.getRoutes(),messageBus:A.apiRoutes.getMessageBus()})}getServerManager(){if(!this.serverManager)throw Error("ServerManager not initialized \u2014 onRegister not called");return this.serverManager}requiresDaemonStartup(){return!0}createDaemon(){return{start:async()=>{await this.ensureDistDirectories(),await this.getServerManager().start()},stop:async()=>{await this.serverManager?.stop()},healthCheck:async()=>{let A=this.serverManager?.getStatus(),Q=A?.running??!1,B=this.siteUrl??A?.productionUrl??`http://localhost:${this.config.productionPort}`,w=this.previewUrl??A?.previewUrl??`http://localhost:${this.config.previewPort}`,$=[];if(Q){if($.push(`Production: ${B}`),A?.previewUrl)$.push(`Preview: ${w}`)}return{status:Q?"healthy":"error",message:Q?$.join(", "):"Webserver not running",lastCheck:new Date,details:{preview:!!A?.previewUrl,production:Q,previewUrl:A?.previewUrl?w:void 0,productionUrl:Q?B:void 0}}}}}async handleProgressEvent(A,Q){}async ensureDistDirectories(){let{mkdir:A,writeFile:Q}=await import("fs/promises");if(this.config.enablePreview&&this.config.previewDistDir&&!SA1(this.config.previewDistDir))await A(this.config.previewDistDir,{recursive:!0}),await Q(gA1(this.config.previewDistDir,"index.html"),zkA),this.logger.debug(`Created preview directory at ${this.config.previewDistDir}`);if(!SA1(this.config.productionDistDir))await A(this.config.productionDistDir,{recursive:!0}),await Q(gA1(this.config.productionDistDir,"index.html"),zkA),this.logger.debug(`Created production directory at ${this.config.productionDistDir}`)}}aA();var H01="vercel.ai.error",Bo2=Symbol.for(H01),hA1,mA1,bB=class A extends(mA1=Error,hA1=Bo2,mA1){constructor({name:Q,message:B,cause:w}){super(B);this[hA1]=!0,this.name=Q,this.cause=w}static isInstance(Q){return A.hasMarker(Q,H01)}static hasMarker(Q,B){let w=Symbol.for(B);return Q!=null&&typeof Q==="object"&&w in Q&&typeof Q[w]==="boolean"&&Q[w]===!0}},G01="AI_APICallError",K01=`vercel.ai.error.${G01}`,wo2=Symbol.for(K01),uA1,cA1,TNw=class extends(cA1=bB,uA1=wo2,cA1){constructor({message:A,url:Q,requestBodyValues:B,statusCode:w,responseHeaders:$,responseBody:f,cause:I,isRetryable:D=w!=null&&(w===408||w===409||w===429||w>=500),data:U}){super({name:G01,message:A,cause:I});this[uA1]=!0,this.url=Q,this.requestBodyValues=B,this.statusCode=w,this.responseHeaders=$,this.responseBody=f,this.isRetryable=D,this.data=U}static isInstance(A){return bB.hasMarker(A,K01)}},F01="AI_EmptyResponseBodyError",Z01=`vercel.ai.error.${F01}`,$o2=Symbol.for(Z01),lA1,pA1,xNw=class extends(pA1=bB,lA1=$o2,pA1){constructor({message:A="Empty response body"}={}){super({name:F01,message:A});this[lA1]=!0}static isInstance(A){return bB.hasMarker(A,Z01)}};function N01(A){if(A==null)return"unknown error";if(typeof A==="string")return A;if(A instanceof Error)return A.message;return JSON.stringify(A)}var z01="AI_InvalidArgumentError",q01=`vercel.ai.error.${z01}`,fo2=Symbol.for(q01),iA1,rA1,L01=class extends(rA1=bB,iA1=fo2,rA1){constructor({message:A,cause:Q,argument:B}){super({name:z01,message:A,cause:Q});this[iA1]=!0,this.argument=B}static isInstance(A){return bB.hasMarker(A,q01)}},V01="AI_InvalidPromptError",E01=`vercel.ai.error.${V01}`,Io2=Symbol.for(E01),dA1,nA1,SNw=class extends(nA1=bB,dA1=Io2,nA1){constructor({prompt:A,message:Q,cause:B}){super({name:V01,message:`Invalid prompt: ${Q}`,cause:B});this[dA1]=!0,this.prompt=A}static isInstance(A){return bB.hasMarker(A,E01)}},M01="AI_InvalidResponseDataError",C01=`vercel.ai.error.${M01}`,Do2=Symbol.for(C01),oA1,sA1,gNw=class extends(sA1=bB,oA1=Do2,sA1){constructor({data:A,message:Q=`Invalid response data: ${JSON.stringify(A)}.`}){super({name:M01,message:Q});this[oA1]=!0,this.data=A}static isInstance(A){return bB.hasMarker(A,C01)}},O01="AI_JSONParseError",R01=`vercel.ai.error.${O01}`,Uo2=Symbol.for(R01),aA1,tA1,qkA=class extends(tA1=bB,aA1=Uo2,tA1){constructor({text:A,cause:Q}){super({name:O01,message:`JSON parsing failed: Text: ${A}.
|
|
2474
2474
|
Error message: ${N01(Q)}`,cause:Q});this[aA1]=!0,this.text=A}static isInstance(A){return bB.hasMarker(A,R01)}},b01="AI_LoadAPIKeyError",P01=`vercel.ai.error.${b01}`,Yo2=Symbol.for(P01),eA1,A01,hNw=class extends(A01=bB,eA1=Yo2,A01){constructor({message:A}){super({name:b01,message:A});this[eA1]=!0}static isInstance(A){return bB.hasMarker(A,P01)}},k01="AI_LoadSettingError",j01=`vercel.ai.error.${k01}`,Jo2=Symbol.for(j01),Q01,B01,mNw=class extends(B01=bB,Q01=Jo2,B01){constructor({message:A}){super({name:k01,message:A});this[Q01]=!0}static isInstance(A){return bB.hasMarker(A,j01)}},_01="AI_NoContentGeneratedError",v01=`vercel.ai.error.${_01}`,Xo2=Symbol.for(v01),w01,$01,uNw=class extends($01=bB,w01=Xo2,$01){constructor({message:A="No content generated."}={}){super({name:_01,message:A});this[w01]=!0}static isInstance(A){return bB.hasMarker(A,v01)}},y01="AI_NoSuchModelError",T01=`vercel.ai.error.${y01}`,Wo2=Symbol.for(T01),f01,I01,cNw=class extends(I01=bB,f01=Wo2,I01){constructor({errorName:A=y01,modelId:Q,modelType:B,message:w=`No such ${B}: ${Q}`}){super({name:A,message:w});this[f01]=!0,this.modelId=Q,this.modelType=B}static isInstance(A){return bB.hasMarker(A,T01)}},x01="AI_TooManyEmbeddingValuesForCallError",S01=`vercel.ai.error.${x01}`,Ho2=Symbol.for(S01),D01,U01,lNw=class extends(U01=bB,D01=Ho2,U01){constructor(A){super({name:x01,message:`Too many values for a single embedding call. The ${A.provider} model "${A.modelId}" can only embed up to ${A.maxEmbeddingsPerCall} values per call, but ${A.values.length} values were provided.`});this[D01]=!0,this.provider=A.provider,this.modelId=A.modelId,this.maxEmbeddingsPerCall=A.maxEmbeddingsPerCall,this.values=A.values}static isInstance(A){return bB.hasMarker(A,S01)}},g01="AI_TypeValidationError",h01=`vercel.ai.error.${g01}`,Go2=Symbol.for(h01),Y01,J01,DH=class A extends(J01=bB,Y01=Go2,J01){constructor({value:Q,cause:B,context:w}){let $="Type validation failed";if(w==null?void 0:w.field)$+=` for ${w.field}`;if((w==null?void 0:w.entityName)||(w==null?void 0:w.entityId)){$+=" (";let f=[];if(w.entityName)f.push(w.entityName);if(w.entityId)f.push(`id: "${w.entityId}"`);$+=f.join(", "),$+=")"}super({name:g01,message:`${$}: Value: ${JSON.stringify(Q)}.
|
|
2475
2475
|
Error message: ${N01(B)}`,cause:B});this[Y01]=!0,this.value=Q,this.context=w}static isInstance(Q){return bB.hasMarker(Q,h01)}static wrap({value:Q,cause:B,context:w}){var $,f,I;if(A.isInstance(B)&&B.value===Q&&(($=B.context)==null?void 0:$.field)===(w==null?void 0:w.field)&&((f=B.context)==null?void 0:f.entityName)===(w==null?void 0:w.entityName)&&((I=B.context)==null?void 0:I.entityId)===(w==null?void 0:w.entityId))return B;return new A({value:Q,cause:B,context:w})}},m01="AI_UnsupportedFunctionalityError",u01=`vercel.ai.error.${m01}`,Ko2=Symbol.for(u01),X01,W01,pNw=class extends(W01=bB,X01=Ko2,W01){constructor({functionality:A,message:Q=`'${A}' functionality not supported.`}){super({name:m01,message:Q});this[X01]=!0,this.functionality=A}static isInstance(A){return bB.hasMarker(A,u01)}};G1();WW();WW();WW();var d01="AI_DownloadError",n01=`vercel.ai.error.${d01}`,Fo2=Symbol.for(n01),c01,l01,pU=class extends(l01=bB,c01=Fo2,l01){constructor({url:A,statusCode:Q,statusText:B,cause:w,message:$=w==null?`Failed to download ${A}: ${Q} ${B}`:`Failed to download ${A}: ${w}`}){super({name:d01,message:$,cause:w});this[c01]=!0,this.url=A,this.statusCode=Q,this.statusText=B}static isInstance(A){return bB.hasMarker(A,n01)}},OkA=2147483648;async function o01({response:A,url:Q,maxBytes:B=OkA}){let w=A.headers.get("content-length");if(w!=null){let J=parseInt(w,10);if(!isNaN(J)&&J>B)throw new pU({url:Q,message:`Download of ${Q} exceeded maximum size of ${B} bytes (Content-Length: ${J}).`})}let $=A.body;if($==null)return new Uint8Array(0);let f=$.getReader(),I=[],D=0;try{while(!0){let{done:J,value:X}=await f.read();if(J)break;if(D+=X.length,D>B)throw new pU({url:Q,message:`Download of ${Q} exceeded maximum size of ${B} bytes.`});I.push(X)}}finally{try{await f.cancel()}finally{f.releaseLock()}}let U=new Uint8Array(D),Y=0;for(let J of I)U.set(J,Y),Y+=J.length;return U}function RkA(A){let Q;try{Q=new URL(A)}catch(w){throw new pU({url:A,message:`Invalid URL: ${A}`})}if(Q.protocol==="data:")return;if(Q.protocol!=="http:"&&Q.protocol!=="https:")throw new pU({url:A,message:`URL scheme must be http, https, or data, got ${Q.protocol}`});let B=Q.hostname;if(!B)throw new pU({url:A,message:"URL must have a hostname"});if(B==="localhost"||B.endsWith(".local")||B.endsWith(".localhost"))throw new pU({url:A,message:`URL with hostname ${B} is not allowed`});if(B.startsWith("[")&&B.endsWith("]")){let w=B.slice(1,-1);if(Zo2(w))throw new pU({url:A,message:`URL with IPv6 address ${B} is not allowed`});return}if(s01(B)){if(EkA(B))throw new pU({url:A,message:`URL with IP address ${B} is not allowed`});return}}function s01(A){let Q=A.split(".");if(Q.length!==4)return!1;return Q.every((B)=>{let w=Number(B);return Number.isInteger(w)&&w>=0&&w<=255&&String(w)===B})}function EkA(A){let Q=A.split(".").map(Number),[B,w]=Q;if(B===0)return!0;if(B===10)return!0;if(B===127)return!0;if(B===169&&w===254)return!0;if(B===172&&w>=16&&w<=31)return!0;if(B===192&&w===168)return!0;return!1}function Zo2(A){let Q=A.toLowerCase();if(Q==="::1")return!0;if(Q==="::")return!0;if(Q.startsWith("::ffff:")){let B=Q.slice(7);if(s01(B))return EkA(B);let w=B.split(":");if(w.length===2){let $=parseInt(w[0],16),f=parseInt(w[1],16);if(!isNaN($)&&!isNaN(f)){let I=$>>8&255,D=$&255,U=f>>8&255,Y=f&255;return EkA(`${I}.${D}.${U}.${Y}`)}}}if(Q.startsWith("fc")||Q.startsWith("fd"))return!0;if(Q.startsWith("fe80"))return!0;return!1}var JF=({prefix:A,size:Q=16,alphabet:B="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",separator:w="-"}={})=>{let $=()=>{let f=B.length,I=Array(Q);for(let D=0;D<Q;D++)I[D]=B[Math.random()*f|0];return I.join("")};if(A==null)return $;if(B.includes(w))throw new L01({argument:"separator",message:`The separator "${w}" must not be part of the alphabet "${B}".`});return()=>`${A}${w}${$()}`},a01=JF();function bkA(A){if(A==null)return"unknown error";if(typeof A==="string")return A;if(A instanceof Error)return A.message;return JSON.stringify(A)}function t01(A=globalThis){var Q,B,w;if(A.window)return"runtime/browser";if((Q=A.navigator)==null?void 0:Q.userAgent)return`runtime/${A.navigator.userAgent.toLowerCase()}`;if((w=(B=A.process)==null?void 0:B.versions)==null?void 0:w.node)return`runtime/node.js/${A.process.version.substring(0)}`;if(A.EdgeRuntime)return"runtime/vercel-edge";return"runtime/unknown"}function No2(A){if(A==null)return{};let Q={};if(A instanceof Headers)A.forEach((B,w)=>{Q[w.toLowerCase()]=B});else{if(!Array.isArray(A))A=Object.entries(A);for(let[B,w]of A)if(w!=null)Q[B.toLowerCase()]=w}return Q}function NBA(A,...Q){let B=new Headers(No2(A)),w=B.get("user-agent")||"";return B.set("user-agent",[w,...Q].filter(Boolean).join(" ")),Object.fromEntries(B.entries())}var zo2=/"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/,qo2=/"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;function p01(A){let Q=JSON.parse(A);if(Q===null||typeof Q!=="object")return Q;if(zo2.test(A)===!1&&qo2.test(A)===!1)return Q;return Lo2(Q)}function Lo2(A){let Q=[A];while(Q.length){let B=Q;Q=[];for(let w of B){if(Object.prototype.hasOwnProperty.call(w,"__proto__"))throw SyntaxError("Object contains forbidden prototype property");if(Object.prototype.hasOwnProperty.call(w,"constructor")&&w.constructor!==null&&typeof w.constructor==="object"&&Object.prototype.hasOwnProperty.call(w.constructor,"prototype"))throw SyntaxError("Object contains forbidden prototype property");for(let $ in w){let f=w[$];if(f&&typeof f==="object")Q.push(f)}}}return A}function Vo2(A){let{stackTraceLimit:Q}=Error;try{Error.stackTraceLimit=0}catch(B){return p01(A)}try{return p01(A)}finally{Error.stackTraceLimit=Q}}function PkA(A){if(A.type==="object"||Array.isArray(A.type)&&A.type.includes("object")){A.additionalProperties=!1;let{properties:B}=A;if(B!=null)for(let w of Object.keys(B))B[w]=XM(B[w])}if(A.items!=null)A.items=Array.isArray(A.items)?A.items.map(XM):XM(A.items);if(A.anyOf!=null)A.anyOf=A.anyOf.map(XM);if(A.allOf!=null)A.allOf=A.allOf.map(XM);if(A.oneOf!=null)A.oneOf=A.oneOf.map(XM);let{definitions:Q}=A;if(Q!=null)for(let B of Object.keys(Q))Q[B]=XM(Q[B]);return A}function XM(A){if(typeof A==="boolean")return A;return PkA(A)}var Eo2=Symbol("Let zodToJsonSchema decide on which parser to use"),i01={name:void 0,$refStrategy:"root",basePath:["#"],effectStrategy:"input",pipeStrategy:"all",dateStrategy:"format:date-time",mapStrategy:"entries",removeAdditionalStrategy:"passthrough",allowedAdditionalProperties:!0,rejectedAdditionalProperties:!1,definitionPath:"definitions",strictUnions:!1,definitions:{},errorMessages:!1,patternStrategy:"escape",applyRegexFlags:!1,emailStrategy:"format:email",base64Strategy:"contentEncoding:base64",nameStrategy:"ref"},Mo2=(A)=>typeof A==="string"?{...i01,name:A}:{...i01,...A};function fD(){return{}}function Co2(A,Q){var B,w,$;let f={type:"array"};if(((B=A.type)==null?void 0:B._def)&&(($=(w=A.type)==null?void 0:w._def)==null?void 0:$.typeName)!==W0.ZodAny)f.items=jw(A.type._def,{...Q,currentPath:[...Q.currentPath,"items"]});if(A.minLength)f.minItems=A.minLength.value;if(A.maxLength)f.maxItems=A.maxLength.value;if(A.exactLength)f.minItems=A.exactLength.value,f.maxItems=A.exactLength.value;return f}function Oo2(A){let Q={type:"integer",format:"int64"};if(!A.checks)return Q;for(let B of A.checks)switch(B.kind){case"min":if(B.inclusive)Q.minimum=B.value;else Q.exclusiveMinimum=B.value;break;case"max":if(B.inclusive)Q.maximum=B.value;else Q.exclusiveMaximum=B.value;break;case"multipleOf":Q.multipleOf=B.value;break}return Q}function Ro2(){return{type:"boolean"}}function e01(A,Q){return jw(A.type._def,Q)}var bo2=(A,Q)=>{return jw(A.innerType._def,Q)};function A11(A,Q,B){let w=B!=null?B:Q.dateStrategy;if(Array.isArray(w))return{anyOf:w.map(($,f)=>A11(A,Q,$))};switch(w){case"string":case"format:date-time":return{type:"string",format:"date-time"};case"format:date":return{type:"string",format:"date"};case"integer":return Po2(A)}}var Po2=(A)=>{let Q={type:"integer",format:"unix-time"};for(let B of A.checks)switch(B.kind){case"min":Q.minimum=B.value;break;case"max":Q.maximum=B.value;break}return Q};function ko2(A,Q){return{...jw(A.innerType._def,Q),default:A.defaultValue()}}function jo2(A,Q){return Q.effectStrategy==="input"?jw(A.schema._def,Q):fD()}function _o2(A){return{type:"string",enum:Array.from(A.values)}}var vo2=(A)=>{if("type"in A&&A.type==="string")return!1;return"allOf"in A};function yo2(A,Q){let B=[jw(A.left._def,{...Q,currentPath:[...Q.currentPath,"allOf","0"]}),jw(A.right._def,{...Q,currentPath:[...Q.currentPath,"allOf","1"]})].filter(($)=>!!$),w=[];return B.forEach(($)=>{if(vo2($))w.push(...$.allOf);else{let f=$;if("additionalProperties"in $&&$.additionalProperties===!1){let{additionalProperties:I,...D}=$;f=D}w.push(f)}}),w.length?{allOf:w}:void 0}function To2(A){let Q=typeof A.value;if(Q!=="bigint"&&Q!=="number"&&Q!=="boolean"&&Q!=="string")return{type:Array.isArray(A.value)?"array":"object"};return{type:Q==="bigint"?"integer":Q,const:A.value}}var LkA=void 0,iJ={cuid:/^[cC][^\s-]{8,}$/,cuid2:/^[0-9a-z]+$/,ulid:/^[0-9A-HJKMNP-TV-Z]{26}$/,email:/^(?!\.)(?!.*\.\.)([a-zA-Z0-9_'+\-\.]*)[a-zA-Z0-9_+-]@([a-zA-Z0-9][a-zA-Z0-9\-]*\.)+[a-zA-Z]{2,}$/,emoji:()=>{if(LkA===void 0)LkA=RegExp("^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$","u");return LkA},uuid:/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/,ipv4:/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,ipv4Cidr:/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/,ipv6:/^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/,ipv6Cidr:/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,base64:/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,base64url:/^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/,nanoid:/^[a-zA-Z0-9_-]{21}$/,jwt:/^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/};function Q11(A,Q){let B={type:"string"};if(A.checks)for(let w of A.checks)switch(w.kind){case"min":B.minLength=typeof B.minLength==="number"?Math.max(B.minLength,w.value):w.value;break;case"max":B.maxLength=typeof B.maxLength==="number"?Math.min(B.maxLength,w.value):w.value;break;case"email":switch(Q.emailStrategy){case"format:email":rJ(B,"email",w.message,Q);break;case"format:idn-email":rJ(B,"idn-email",w.message,Q);break;case"pattern:zod":S4(B,iJ.email,w.message,Q);break}break;case"url":rJ(B,"uri",w.message,Q);break;case"uuid":rJ(B,"uuid",w.message,Q);break;case"regex":S4(B,w.regex,w.message,Q);break;case"cuid":S4(B,iJ.cuid,w.message,Q);break;case"cuid2":S4(B,iJ.cuid2,w.message,Q);break;case"startsWith":S4(B,RegExp(`^${VkA(w.value,Q)}`),w.message,Q);break;case"endsWith":S4(B,RegExp(`${VkA(w.value,Q)}$`),w.message,Q);break;case"datetime":rJ(B,"date-time",w.message,Q);break;case"date":rJ(B,"date",w.message,Q);break;case"time":rJ(B,"time",w.message,Q);break;case"duration":rJ(B,"duration",w.message,Q);break;case"length":B.minLength=typeof B.minLength==="number"?Math.max(B.minLength,w.value):w.value,B.maxLength=typeof B.maxLength==="number"?Math.min(B.maxLength,w.value):w.value;break;case"includes":{S4(B,RegExp(VkA(w.value,Q)),w.message,Q);break}case"ip":{if(w.version!=="v6")rJ(B,"ipv4",w.message,Q);if(w.version!=="v4")rJ(B,"ipv6",w.message,Q);break}case"base64url":S4(B,iJ.base64url,w.message,Q);break;case"jwt":S4(B,iJ.jwt,w.message,Q);break;case"cidr":{if(w.version!=="v6")S4(B,iJ.ipv4Cidr,w.message,Q);if(w.version!=="v4")S4(B,iJ.ipv6Cidr,w.message,Q);break}case"emoji":S4(B,iJ.emoji(),w.message,Q);break;case"ulid":{S4(B,iJ.ulid,w.message,Q);break}case"base64":{switch(Q.base64Strategy){case"format:binary":{rJ(B,"binary",w.message,Q);break}case"contentEncoding:base64":{B.contentEncoding="base64";break}case"pattern:zod":{S4(B,iJ.base64,w.message,Q);break}}break}case"nanoid":S4(B,iJ.nanoid,w.message,Q);case"toLowerCase":case"toUpperCase":case"trim":break;default:}return B}function VkA(A,Q){return Q.patternStrategy==="escape"?So2(A):A}var xo2=new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");function So2(A){let Q="";for(let B=0;B<A.length;B++){if(!xo2.has(A[B]))Q+="\\";Q+=A[B]}return Q}function rJ(A,Q,B,w){var $;if(A.format||(($=A.anyOf)==null?void 0:$.some((f)=>f.format))){if(!A.anyOf)A.anyOf=[];if(A.format)A.anyOf.push({format:A.format}),delete A.format;A.anyOf.push({format:Q,...B&&w.errorMessages&&{errorMessage:{format:B}}})}else A.format=Q}function S4(A,Q,B,w){var $;if(A.pattern||(($=A.allOf)==null?void 0:$.some((f)=>f.pattern))){if(!A.allOf)A.allOf=[];if(A.pattern)A.allOf.push({pattern:A.pattern}),delete A.pattern;A.allOf.push({pattern:r01(Q,w),...B&&w.errorMessages&&{errorMessage:{pattern:B}}})}else A.pattern=r01(Q,w)}function r01(A,Q){var B;if(!Q.applyRegexFlags||!A.flags)return A.source;let w={i:A.flags.includes("i"),m:A.flags.includes("m"),s:A.flags.includes("s")},$=w.i?A.source.toLowerCase():A.source,f="",I=!1,D=!1,U=!1;for(let Y=0;Y<$.length;Y++){if(I){f+=$[Y],I=!1;continue}if(w.i){if(D){if($[Y].match(/[a-z]/)){if(U)f+=$[Y],f+=`${$[Y-2]}-${$[Y]}`.toUpperCase(),U=!1;else if($[Y+1]==="-"&&((B=$[Y+2])==null?void 0:B.match(/[a-z]/)))f+=$[Y],U=!0;else f+=`${$[Y]}${$[Y].toUpperCase()}`;continue}}else if($[Y].match(/[a-z]/)){f+=`[${$[Y]}${$[Y].toUpperCase()}]`;continue}}if(w.m){if($[Y]==="^"){f+=`(^|(?<=[\r
|
|
2476
2476
|
]))`;continue}else if($[Y]==="$"){f+=`($|(?=[\r
|
|
@@ -2480,7 +2480,7 @@ Error message: ${N01(B)}`,cause:B});this[Y01]=!0,this.value=Q,this.context=w}sta
|
|
|
2480
2480
|
|
|
2481
2481
|
`)},flush(A){A.enqueue(`data: [DONE]
|
|
2482
2482
|
|
|
2483
|
-
`)}})}},At2={"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive","x-vercel-ai-ui-message-stream":"v1","x-accel-buffering":"no"};function F11({status:A,statusText:Q,headers:B,stream:w,consumeSseStream:$}){let f=w.pipeThrough(new ea2);if($){let[I,D]=f.tee();f=I,$({stream:D})}return new Response(f.pipeThrough(new TextEncoderStream),{status:A,statusText:Q,headers:ta2(B,At2)})}var Al=K.record(K.string(),WM.optional()),v3w=zBA(()=>ec(K.union([K.strictObject({type:K.literal("text-start"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("text-delta"),id:K.string(),delta:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("text-end"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("error"),errorText:K.string()}),K.strictObject({type:K.literal("tool-input-start"),toolCallId:K.string(),toolName:K.string(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:Al.optional(),dynamic:K.boolean().optional(),title:K.string().optional()}),K.strictObject({type:K.literal("tool-input-delta"),toolCallId:K.string(),inputTextDelta:K.string()}),K.strictObject({type:K.literal("tool-input-available"),toolCallId:K.string(),toolName:K.string(),input:K.unknown(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:Al.optional(),dynamic:K.boolean().optional(),title:K.string().optional()}),K.strictObject({type:K.literal("tool-input-error"),toolCallId:K.string(),toolName:K.string(),input:K.unknown(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:Al.optional(),dynamic:K.boolean().optional(),errorText:K.string(),title:K.string().optional()}),K.strictObject({type:K.literal("tool-approval-request"),approvalId:K.string(),toolCallId:K.string()}),K.strictObject({type:K.literal("tool-output-available"),toolCallId:K.string(),output:K.unknown(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:Al.optional(),dynamic:K.boolean().optional(),preliminary:K.boolean().optional()}),K.strictObject({type:K.literal("tool-output-error"),toolCallId:K.string(),errorText:K.string(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:Al.optional(),dynamic:K.boolean().optional()}),K.strictObject({type:K.literal("tool-output-denied"),toolCallId:K.string()}),K.strictObject({type:K.literal("reasoning-start"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("reasoning-delta"),id:K.string(),delta:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("reasoning-end"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("source-url"),sourceId:K.string(),url:K.string(),title:K.string().optional(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("source-document"),sourceId:K.string(),mediaType:K.string(),title:K.string(),filename:K.string().optional(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("file"),url:K.string(),mediaType:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.custom((A)=>typeof A==="string"&&A.startsWith("data-"),{message:'Type must start with "data-"'}),id:K.string().optional(),data:K.unknown(),transient:K.boolean().optional()}),K.strictObject({type:K.literal("start-step")}),K.strictObject({type:K.literal("finish-step")}),K.strictObject({type:K.literal("start"),messageId:K.string().optional(),messageMetadata:K.unknown().optional()}),K.strictObject({type:K.literal("finish"),finishReason:K.enum(["stop","length","content-filter","tool-calls","error","other"]).optional(),messageMetadata:K.unknown().optional()}),K.strictObject({type:K.literal("abort"),reason:K.string().optional()}),K.strictObject({type:K.literal("message-metadata"),messageMetadata:K.unknown()})])));function Qt2(A){return A.type.startsWith("data-")}function jkA(A){return A.type.startsWith("tool-")}function Bt2(A){return A.type==="dynamic-tool"}function w11(A){return jkA(A)||Bt2(A)}function $11(A){return A.type.split("-").slice(1).join("-")}function wt2({lastMessage:A,messageId:Q}){return{message:(A==null?void 0:A.role)==="assistant"?A:{id:Q,metadata:void 0,role:"assistant",parts:[]},activeTextParts:{},activeReasoningParts:{},partialToolCalls:{}}}function $t2({stream:A,messageMetadataSchema:Q,dataPartSchemas:B,runUpdateMessageJob:w,onError:$,onToolCall:f,onData:I}){return A.pipeThrough(new TransformStream({async transform(D,U){await w(async({state:Y,write:J})=>{var X,G,Z,N;function V(E){let T=Y.message.parts.filter(w11).find((y)=>y.toolCallId===E);if(T==null)throw new $_({chunkType:"tool-invocation",chunkId:E,message:`No tool invocation found for tool call ID "${E}".`});return T}function L(E){var S;let T=Y.message.parts.find((x)=>jkA(x)&&x.toolCallId===E.toolCallId),y=E,_=T;if(T!=null){if(T.state=E.state,_.input=y.input,_.output=y.output,_.errorText=y.errorText,_.rawInput=y.rawInput,_.preliminary=y.preliminary,E.title!==void 0)_.title=E.title;if(E.toolMetadata!==void 0)_.toolMetadata=E.toolMetadata;_.providerExecuted=(S=y.providerExecuted)!=null?S:T.providerExecuted;let x=y.providerMetadata;if(x!=null)if(E.state==="output-available"||E.state==="output-error"){let g=T;g.resultProviderMetadata=x}else T.callProviderMetadata=x}else Y.message.parts.push({type:`tool-${E.toolName}`,toolCallId:E.toolCallId,state:E.state,title:E.title,...E.toolMetadata!==void 0?{toolMetadata:E.toolMetadata}:{},input:y.input,output:y.output,rawInput:y.rawInput,errorText:y.errorText,providerExecuted:y.providerExecuted,preliminary:y.preliminary,...y.providerMetadata!=null&&(E.state==="output-available"||E.state==="output-error")?{resultProviderMetadata:y.providerMetadata}:{},...y.providerMetadata!=null&&!(E.state==="output-available"||E.state==="output-error")?{callProviderMetadata:y.providerMetadata}:{}})}function M(E){var S,T;let y=Y.message.parts.find((g)=>g.type==="dynamic-tool"&&g.toolCallId===E.toolCallId),_=E,x=y;if(y!=null){if(y.state=E.state,x.toolName=E.toolName,x.input=_.input,x.output=_.output,x.errorText=_.errorText,x.rawInput=(S=_.rawInput)!=null?S:x.rawInput,x.preliminary=_.preliminary,E.title!==void 0)x.title=E.title;if(E.toolMetadata!==void 0)x.toolMetadata=E.toolMetadata;x.providerExecuted=(T=_.providerExecuted)!=null?T:y.providerExecuted;let g=_.providerMetadata;if(g!=null)if(E.state==="output-available"||E.state==="output-error"){let n=y;n.resultProviderMetadata=g}else y.callProviderMetadata=g}else Y.message.parts.push({type:"dynamic-tool",toolName:E.toolName,toolCallId:E.toolCallId,state:E.state,input:_.input,output:_.output,errorText:_.errorText,preliminary:_.preliminary,providerExecuted:_.providerExecuted,title:E.title,...E.toolMetadata!==void 0?{toolMetadata:E.toolMetadata}:{},..._.providerMetadata!=null&&(E.state==="output-available"||E.state==="output-error")?{resultProviderMetadata:_.providerMetadata}:{},..._.providerMetadata!=null&&!(E.state==="output-available"||E.state==="output-error")?{callProviderMetadata:_.providerMetadata}:{}})}async function O(E){if(E!=null){let S=Y.message.metadata!=null?K11(Y.message.metadata,E):E;if(Q!=null)await VBA({value:S,schema:Q,context:{field:"message.metadata",entityId:Y.message.id}});Y.message.metadata=S}}switch(D.type){case"text-start":{let E={type:"text",text:"",providerMetadata:D.providerMetadata,state:"streaming"};Y.activeTextParts[D.id]=E,Y.message.parts.push(E),J();break}case"text-delta":{let E=Y.activeTextParts[D.id];if(E==null)throw new $_({chunkType:"text-delta",chunkId:D.id,message:`Received text-delta for missing text part with ID "${D.id}". Ensure a "text-start" chunk is sent before any "text-delta" chunks.`});E.text+=D.delta,E.providerMetadata=(X=D.providerMetadata)!=null?X:E.providerMetadata,J();break}case"text-end":{let E=Y.activeTextParts[D.id];if(E==null)throw new $_({chunkType:"text-end",chunkId:D.id,message:`Received text-end for missing text part with ID "${D.id}". Ensure a "text-start" chunk is sent before any "text-end" chunks.`});E.state="done",E.providerMetadata=(G=D.providerMetadata)!=null?G:E.providerMetadata,delete Y.activeTextParts[D.id],J();break}case"reasoning-start":{let E={type:"reasoning",text:"",providerMetadata:D.providerMetadata,state:"streaming"};Y.activeReasoningParts[D.id]=E,Y.message.parts.push(E),J();break}case"reasoning-delta":{let E=Y.activeReasoningParts[D.id];if(E==null)throw new $_({chunkType:"reasoning-delta",chunkId:D.id,message:`Received reasoning-delta for missing reasoning part with ID "${D.id}". Ensure a "reasoning-start" chunk is sent before any "reasoning-delta" chunks.`});E.text+=D.delta,E.providerMetadata=(Z=D.providerMetadata)!=null?Z:E.providerMetadata,J();break}case"reasoning-end":{let E=Y.activeReasoningParts[D.id];if(E==null)throw new $_({chunkType:"reasoning-end",chunkId:D.id,message:`Received reasoning-end for missing reasoning part with ID "${D.id}". Ensure a "reasoning-start" chunk is sent before any "reasoning-end" chunks.`});E.providerMetadata=(N=D.providerMetadata)!=null?N:E.providerMetadata,E.state="done",delete Y.activeReasoningParts[D.id],J();break}case"file":{Y.message.parts.push({type:"file",mediaType:D.mediaType,url:D.url,...D.providerMetadata!=null?{providerMetadata:D.providerMetadata}:{}}),J();break}case"source-url":{Y.message.parts.push({type:"source-url",sourceId:D.sourceId,url:D.url,title:D.title,providerMetadata:D.providerMetadata}),J();break}case"source-document":{Y.message.parts.push({type:"source-document",sourceId:D.sourceId,mediaType:D.mediaType,title:D.title,filename:D.filename,providerMetadata:D.providerMetadata}),J();break}case"tool-input-start":{let E=Y.message.parts.filter(jkA);if(Y.partialToolCalls[D.toolCallId]={text:"",toolName:D.toolName,index:E.length,dynamic:D.dynamic,title:D.title,toolMetadata:D.toolMetadata},D.dynamic)M({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-streaming",input:void 0,providerExecuted:D.providerExecuted,title:D.title,toolMetadata:D.toolMetadata,providerMetadata:D.providerMetadata});else L({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-streaming",input:void 0,providerExecuted:D.providerExecuted,title:D.title,toolMetadata:D.toolMetadata,providerMetadata:D.providerMetadata});J();break}case"tool-input-delta":{let E=Y.partialToolCalls[D.toolCallId];if(E==null)throw new $_({chunkType:"tool-input-delta",chunkId:D.toolCallId,message:`Received tool-input-delta for missing tool call with ID "${D.toolCallId}". Ensure a "tool-input-start" chunk is sent before any "tool-input-delta" chunks.`});E.text+=D.inputTextDelta;let{value:S}=await Ql(E.text);if(E.dynamic)M({toolCallId:D.toolCallId,toolName:E.toolName,state:"input-streaming",input:S,title:E.title,toolMetadata:E.toolMetadata});else L({toolCallId:D.toolCallId,toolName:E.toolName,state:"input-streaming",input:S,title:E.title,toolMetadata:E.toolMetadata});J();break}case"tool-input-available":{if(D.dynamic)M({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-available",input:D.input,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:D.title,toolMetadata:D.toolMetadata});else L({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-available",input:D.input,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:D.title,toolMetadata:D.toolMetadata});if(J(),f&&!D.providerExecuted)await f({toolCall:D});break}case"tool-input-error":{let E=Y.message.parts.filter(w11).find((T)=>T.toolCallId===D.toolCallId);if(E!=null?E.type==="dynamic-tool":!!D.dynamic)M({toolCallId:D.toolCallId,toolName:D.toolName,state:"output-error",input:D.input,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,toolMetadata:D.toolMetadata});else L({toolCallId:D.toolCallId,toolName:D.toolName,state:"output-error",input:void 0,rawInput:D.input,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,toolMetadata:D.toolMetadata});J();break}case"tool-approval-request":{let E=V(D.toolCallId);E.state="approval-requested",E.approval={id:D.approvalId},J();break}case"tool-output-denied":{let E=V(D.toolCallId);E.state="output-denied",J();break}case"tool-output-available":{let E=V(D.toolCallId);if(E.type==="dynamic-tool")M({toolCallId:D.toolCallId,toolName:E.toolName,state:"output-available",input:E.input,output:D.output,preliminary:D.preliminary,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});else L({toolCallId:D.toolCallId,toolName:$11(E),state:"output-available",input:E.input,output:D.output,providerExecuted:D.providerExecuted,preliminary:D.preliminary,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});J();break}case"tool-output-error":{let E=V(D.toolCallId);if(E.type==="dynamic-tool")M({toolCallId:D.toolCallId,toolName:E.toolName,state:"output-error",input:E.input,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});else L({toolCallId:D.toolCallId,toolName:$11(E),state:"output-error",input:E.input,rawInput:E.rawInput,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});J();break}case"start-step":{Y.message.parts.push({type:"step-start"});break}case"finish-step":{Y.activeTextParts={},Y.activeReasoningParts={};break}case"start":{if(D.messageId!=null)Y.message.id=D.messageId;if(await O(D.messageMetadata),D.messageId!=null||D.messageMetadata!=null)J();break}case"finish":{if(D.finishReason!=null)Y.finishReason=D.finishReason;if(await O(D.messageMetadata),D.messageMetadata!=null)J();break}case"message-metadata":{if(await O(D.messageMetadata),D.messageMetadata!=null)J();break}case"error":{$==null||$(Error(D.errorText));break}default:if(Qt2(D)){if((B==null?void 0:B[D.type])!=null){let T=Y.message.parts.findIndex((_)=>("id"in _)&&("data"in _)&&_.id===D.id&&_.type===D.type),y=T>=0?T:Y.message.parts.length;await VBA({value:D.data,schema:B[D.type],context:{field:`message.parts[${y}].data`,entityName:D.type,entityId:D.id}})}let E=D;if(E.transient){I==null||I(E);break}let S=E.id!=null?Y.message.parts.find((T)=>E.type===T.type&&E.id===T.id):void 0;if(S!=null)S.data=E.data;else Y.message.parts.push(E);I==null||I(E),J()}}U.enqueue(D)})}}))}function ft2({messageId:A,originalMessages:Q=[],onStepFinish:B,onFinish:w,onError:$,stream:f}){let I=Q==null?void 0:Q[Q.length-1];if((I==null?void 0:I.role)!=="assistant")I=void 0;else A=I.id;let D=!1,U=f.pipeThrough(new TransformStream({transform(N,V){if(N.type==="start"){let L=N;if(L.messageId==null&&A!=null)L.messageId=A}if(N.type==="abort")D=!0;V.enqueue(N)}}));if(w==null&&B==null)return U;let Y=wt2({lastMessage:I?structuredClone(I):void 0,messageId:A!=null?A:""}),J=async(N)=>{await N({state:Y,write:()=>{}})},X=!1,G=async()=>{if(X||!w)return;X=!0;let N=Y.message.id===(I==null?void 0:I.id);await w({isAborted:D,isContinuation:N,responseMessage:Y.message,messages:[...N?Q.slice(0,-1):Q,Y.message],finishReason:Y.finishReason})},Z=async()=>{if(!B)return;let N=Y.message.id===(I==null?void 0:I.id);try{await B({isContinuation:N,responseMessage:structuredClone(Y.message),messages:[...N?Q.slice(0,-1):Q,structuredClone(Y.message)]})}catch(V){$(V)}};return $t2({stream:U,runUpdateMessageJob:J,onError:$}).pipeThrough(new TransformStream({async transform(N,V){if(N.type==="finish-step")await Z();V.enqueue(N)},async cancel(){await G()},async flush(){await G()}}))}var y3w=JF({prefix:"aitxt",size:24});function Z11({execute:A,onError:Q=bkA,originalMessages:B,onStepFinish:w,onFinish:$,generateId:f=a01}){let I,D=[],U=new ReadableStream({start(X){I=X}});function Y(X){try{I.enqueue(X)}catch(G){}}try{let X=A({writer:{write(G){Y(G)},merge(G){D.push((async()=>{let Z=G.getReader();while(!0){let{done:N,value:V}=await Z.read();if(N)break;Y(V)}})().catch((Z)=>{Y({type:"error",errorText:Q(Z)})}))},onError:Q}});if(X)D.push(X.catch((G)=>{Y({type:"error",errorText:Q(G)})}))}catch(X){Y({type:"error",errorText:Q(X)})}return new Promise(async(X)=>{while(D.length>0)await D.shift();X()}).finally(()=>{try{I.close()}catch(X){}}),ft2({stream:U,messageId:f(),originalMessages:B,onStepFinish:w,onFinish:$,onError:Q})}var yf=K.record(K.string(),WM.optional()),g3w=zBA(()=>ec(K.array(K.object({id:K.string(),role:K.enum(["system","user","assistant"]),metadata:K.unknown().optional(),parts:K.array(K.union([K.object({type:K.literal("text"),text:K.string(),state:K.enum(["streaming","done"]).optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("reasoning"),text:K.string(),state:K.enum(["streaming","done"]).optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("source-url"),sourceId:K.string(),url:K.string(),title:K.string().optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("source-document"),sourceId:K.string(),mediaType:K.string(),title:K.string(),filename:K.string().optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("file"),mediaType:K.string(),filename:K.string().optional(),url:K.string(),providerMetadata:N2.optional()}),K.object({type:K.literal("step-start")}),K.object({type:K.string().startsWith("data-"),id:K.string().optional(),data:K.unknown()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("input-streaming"),input:K.unknown().optional(),providerExecuted:K.boolean().optional(),callProviderMetadata:N2.optional(),output:K.never().optional(),errorText:K.never().optional(),approval:K.never().optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("input-available"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.never().optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("approval-requested"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.never().optional(),reason:K.never().optional()})}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("approval-responded"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.boolean(),reason:K.string().optional()})}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("output-available"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.unknown(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),preliminary:K.boolean().optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("output-error"),input:K.unknown().optional(),rawInput:K.unknown().optional(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.string(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("output-denied"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!1),reason:K.string().optional()})}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("input-streaming"),providerExecuted:K.boolean().optional(),callProviderMetadata:N2.optional(),input:K.unknown().optional(),output:K.never().optional(),errorText:K.never().optional(),approval:K.never().optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("input-available"),providerExecuted:K.boolean().optional(),input:K.unknown(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.never().optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("approval-requested"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.never().optional(),reason:K.never().optional()})}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("approval-responded"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.boolean(),reason:K.string().optional()})}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("output-available"),providerExecuted:K.boolean().optional(),input:K.unknown(),output:K.unknown(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),preliminary:K.boolean().optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("output-error"),providerExecuted:K.boolean().optional(),input:K.unknown().optional(),rawInput:K.unknown().optional(),output:K.never().optional(),errorText:K.string(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("output-denied"),providerExecuted:K.boolean().optional(),input:K.unknown(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!1),reason:K.string().optional()})})])).nonempty("Message must contain at least one part")})).nonempty("Messages array must not be empty")));var m3w=JF({prefix:"aiobj",size:24});function N11(A){return({url:Q,abortSignal:B})=>ya2({url:Q,maxBytes:A==null?void 0:A.maxBytes,abortSignal:B})}var c3w=JF({prefix:"aiobj",size:24});var l3w=N11();var It2="AI_NoSuchProviderError",Dt2=`vercel.ai.error.${It2}`,Ut2=Symbol.for(Dt2),Yt2;Yt2=Ut2;var p3w=N11();var z11={name:"@brains/web-chat",private:!0,version:"0.2.0-alpha.125",description:"Web chat interface for Brains",type:"module",exports:{".":"./src/index.ts"},files:["src","dist","package.json"],scripts:{build:"bun scripts/build-ui.ts","build:ui":"bun scripts/build-ui.ts",typecheck:"tsc --noEmit && tsc --noEmit -p ui-react/tsconfig.json",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix",test:"bun test"},dependencies:{"@ai-sdk/react":"^3.0.116","@brains/auth-service":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@streamdown/cjk":"^1.0.3","@streamdown/code":"^1.1.1","@streamdown/math":"^1.0.2","@streamdown/mermaid":"^1.0.2",ai:"^6.0.86","class-variance-authority":"^0.7.0",cmdk:"^1.1.1","lucide-react":"^1.16.0",nanoid:"^5.0.4","radix-ui":"^1.4.3",react:"^19.2.6","react-dom":"^19.2.6",shiki:"^4.1.0",streamdown:"^2.5.0","use-stick-to-bottom":"^1.1.4"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/react":"^19.0.3","@types/react-dom":"^19.0.3",typescript:"^5.3.3",vite:"^7.2.4"}};async function q11(A,Q){if(!await Q.resolveOperatorSession(A))return Q.createOperatorLoginRequiredResponse(A);let B=new URL(A.url),w=B.searchParams.get("id")?.trim();if(!w)return new Response("Missing document id",{status:400});let $=await Q.entityService.getEntity({entityType:"document",id:w});if(!$)return new Response("Document not found",{status:404});let f=Xt2($.content);if(!f)return new Response("Document content is not a PDF",{status:415});let I=Ht2($.metadata,w);return V11({requestUrl:B,data:f.data,mediaType:f.mimeType,filename:I})}async function L11(A,Q){if(!await Q.resolveOperatorSession(A))return Q.createOperatorLoginRequiredResponse(A);let B=new URL(A.url),w=B.searchParams.get("id")?.trim();if(!w)return new Response("Missing image id",{status:400});let $=await Q.entityService.getEntity({entityType:"image",id:w});if(!$)return new Response("Image not found",{status:404});let f=Wt2($.content);if(!f)return new Response("Image content is not an image",{status:415});let I=Gt2($.metadata,w,f.mimeType);return V11({requestUrl:B,data:f.data,mediaType:f.mimeType,filename:I})}function V11(A){let Q=new Headers({"Content-Type":A.mediaType,"Content-Length":String(A.data.byteLength),"Content-Disposition":`${A.requestUrl.searchParams.has("download")?"attachment":"inline"}; filename="${Kt2(A.filename)}"`});return new Response(A.data,{headers:Q})}function E11(A,Q){let B=A.match(/^data:([^;]+);base64,(.+)$/i);if(!B)return null;let[,w,$]=B;if(!w||!$||!Q.test(w))return null;let f=Buffer.from($,"base64"),I=f.buffer.slice(f.byteOffset,f.byteOffset+f.byteLength);return{mimeType:w,data:I}}function Xt2(A){let Q=E11(A,/^application\/pdf$/i);if(Q?.mimeType.toLowerCase()!=="application/pdf")return null;return{mimeType:"application/pdf",data:Q.data}}function Wt2(A){return E11(A,/^image\/[a-z0-9.+-]+$/i)}function Ht2(A,Q){let B=A?.filename;return typeof B==="string"&&B.length>0?B:`${Q}.pdf`}function Gt2(A,Q,B){let w=A?.filename;if(typeof w==="string"&&w.length>0)return w;let $=A?.format;if(typeof $==="string"&&$.length>0)return`${Q}.${$==="jpeg"?"jpg":$}`;let f=B.split("/")[1];return`${Q}.${f&&f.length>0?f:"png"}`}function Kt2(A){return A.replace(/["\\\r\n]/g,"_")}WA();aA();var Bl="upload",M11=lR;var Ft2={namespace:"upload",refKind:Bl,routePath:"/api/chat/uploads"};function EBA(){return Ft2}aA();var O11="upload.txt";var R11=5000000,Zt2=[".md",".txt",".markdown"],Nt2=["text/plain","text/markdown","text/x-markdown"],_kA=new Map([[".png","image/png"],[".jpg","image/jpeg"],[".jpeg","image/jpeg"],[".webp","image/webp"],[".gif","image/gif"],[".pdf","application/pdf"]]),zt2=new Set(_kA.values());function CBA(A){let Q=A.split(/[\\/]/).at(-1)?.trim()??"",B=Array.from(Q).filter((w)=>{let $=w.charCodeAt(0);return $>31&&$!==127}).join("").slice(0,160);return B.length>0?B:"upload.txt"}function b11(A,Q){let B=Q?.trim()??"";if(B.length>0)return B;let w=A.toLowerCase();if(w.endsWith(".md")||w.endsWith(".markdown"))return"text/markdown";if(w.endsWith(".txt"))return"text/plain";return"application/octet-stream"}function P11(A,Q){let B=Q?.trim()??"",w=B.split(";",1)[0]?.toLowerCase()??B;if(w.length>0&&w!=="application/octet-stream")return w;let $=b11(A,void 0);if($!=="application/octet-stream")return $;let f=A.toLowerCase();for(let[I,D]of _kA)if(f.endsWith(I))return D;return"application/octet-stream"}function k11(A,Q){if(Q&&Nt2.some((B)=>Q.toLowerCase().startsWith(B)))return!0;return Zt2.some((B)=>A.toLowerCase().endsWith(B))}function qt2(A){return A<=1e5}function Lt2(A){return A<=5000000}function Vt2(A,Q){let B=P11(A,Q);if(zt2.has(B))return!0;return _kA.has(Ct2(A))}function Et2(A){if(A.includes(0))return!1;try{return new TextDecoder("utf-8",{fatal:!0}).decode(A),!0}catch{return!1}}function Mt2(A){let Q=CBA(A.filename),B=b11(Q,A.mediaType);if(!k11(Q,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};if(!qt2(A.content.byteLength))return{ok:!1,code:"file_too_large",message:`File upload too large: ${Q}`};if(!Et2(A.content))return{ok:!1,code:"binary_content",message:`Unsupported file upload type: ${Q}`};return{ok:!0,filename:Q,mediaType:B,sizeBytes:A.content.byteLength,text:new TextDecoder("utf-8").decode(A.content).replace(/^\uFEFF/,"")}}function OBA(A){let Q=CBA(A.filename),B=P11(Q,A.mediaType);if(k11(Q,B)){let w=Mt2({filename:Q,mediaType:B,content:A.content});return w.ok?{...w,kind:"text"}:w}if(!Vt2(Q,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};if(!Lt2(A.content.byteLength))return{ok:!1,code:"file_too_large",message:`File upload too large: ${Q}`};if(!Ot2(A.content,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};return{ok:!0,kind:"file",filename:Q,mediaType:B,sizeBytes:A.content.byteLength}}function Ct2(A){let Q=A.lastIndexOf(".");return Q>=0?A.slice(Q).toLowerCase():""}function Ot2(A,Q){switch(Q){case"image/png":return C11(A,[137,80,78,71]);case"image/jpeg":return C11(A,[255,216,255]);case"image/gif":return MBA(A,"GIF87a")||MBA(A,"GIF89a");case"image/webp":return MBA(A,"RIFF")&&j11(A,"WEBP",8);case"application/pdf":return MBA(A,"%PDF-");default:return!1}}function C11(A,Q){return Q.every((B,w)=>A[w]===B)}function MBA(A,Q){return j11(A,Q,0)}function j11(A,Q,B){return Array.from(Q).every((w,$)=>A[B+$]===w.charCodeAt(0))}var Rt2="file",bt2=16384;async function _11(A,Q){if(!await Q.resolveOperatorSession(A))return new Response("Forbidden",{status:403});let B=Number(A.headers.get("content-length"));if(Number.isFinite(B)&&B>R11+bt2)return new Response("File upload too large",{status:400});let w;try{w=await A.formData()}catch{return new Response("Invalid multipart upload",{status:400})}let $=w.get(Rt2);if(!($ instanceof File))return new Response("Missing upload file",{status:400});let f=Buffer.from(await $.arrayBuffer()),I=OBA({filename:$.name,mediaType:$.type,content:f});if(!I.ok)return new Response(I.message,{status:400});let D=Q.getUploadStore(),U=await D.save({filename:I.filename,mediaType:I.mediaType,content:f});return Response.json(D.toResponseBody(U),{status:201})}async function v11(A,Q){if(!await Q.resolveOperatorSession(A))return new Response("Forbidden",{status:403});let B=new URL(A.url).searchParams.get("id")?.trim();if(!B)return new Response("Missing upload id",{status:400});let w=await x11(B,Q.getUploadStore());if(w instanceof Response)return w;let{record:$,content:f}=w,I=S11($,f);if(I instanceof Response)return I;let D=new URL(A.url).searchParams.has("download")?"attachment":"inline",U=new Uint8Array(f).buffer;return new Response(U,{headers:{"Content-Type":$.mediaType,"Content-Length":String(f.byteLength),"Content-Disposition":`${D}; filename="${jt2($.filename)}"`}})}function y11(A){let Q=CBA(A.filename??O11),B=kt2(A.url);if(!B)return new Response(`Unsupported file upload URL: ${Q}`,{status:400});let w=OBA({filename:Q,mediaType:A.mediaType,content:B.buffer});if(!w.ok)return new Response(w.message,{status:400});return g11(w,B.buffer)}async function T11(A,Q){let B=await x11(A,Q);if(B instanceof Response)return B;let{record:w,content:$}=B,f=S11(w,$);if(f instanceof Response)return f;return g11(f,$,{kind:Bl,id:A})}async function x11(A,Q){try{return await Q.read(A)}catch(B){if(B instanceof DW)return Pt2(B);throw B}}function S11(A,Q){let B=OBA({filename:A.filename,mediaType:A.mediaType,content:Q});if(!B.ok)return new Response(B.message,{status:400});return B}function g11(A,Q,B){if(A.kind==="text")return{kind:"text",filename:A.filename,mediaType:A.mediaType,content:A.text,sizeBytes:A.sizeBytes,...B!==void 0?{source:B}:{}};return{kind:"file",filename:A.filename,mediaType:A.mediaType,data:new Uint8Array(Q),sizeBytes:A.sizeBytes,...B!==void 0?{source:B}:{}}}function Pt2(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 kt2(A){let Q=/^data:[^,]*,(.*)$/s.exec(A);if(!Q)return null;let w=A.slice(5,A.indexOf(",")).split(";").some(($)=>$.toLowerCase()==="base64");try{let $=w?Buffer.from(Q[1]??"","base64"):Buffer.from(decodeURIComponent(Q[1]??""),"utf8");return{buffer:$,byteLength:$.byteLength}}catch{return null}}function jt2(A){return A.replace(/["\\\r\n]/g,"_")}var _t2=H.object({type:H.literal("text"),text:H.string()}),vt2=H.object({type:H.literal("file"),mediaType:H.string().optional(),filename:H.string().optional(),url:H.string()}),yt2=H.object({state:H.literal("approval-responded"),approval:H.object({id:H.string(),approved:H.boolean()})}).passthrough(),Tt2=H.object({role:H.string(),parts:H.array(H.unknown()).optional(),content:H.string().optional()}),h11=H.object({id:H.string().optional(),messages:H.array(Tt2).min(1),trigger:H.string().optional()}),xt2=H.object({kind:H.literal(Bl),id:H.string().regex(M11)}),St2=H.object({type:H.literal("data-upload"),data:H.object({ref:xt2})});async function m11(A,Q){let B=gt2(A);if(!B)return{message:"",attachments:[]};let w=[],$=[];for(let I of B.parts??[]){let D=_t2.safeParse(I);if(D.success){if(D.data.text.length>0)w.push(D.data.text);continue}let U=vt2.safeParse(I);if(U.success){let J=y11(U.data);if(J instanceof Response)return J;$.push(J);continue}let Y=St2.safeParse(I);if(Y.success){let J=await T11(Y.data.data.ref.id,Q.uploadStore);if(J instanceof Response)return J;$.push(J);continue}if(ht2(I)==="data-upload")return new Response("Invalid upload ref",{status:400})}return{message:w.length>0?w.join(`
|
|
2483
|
+
`)}})}},At2={"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive","x-vercel-ai-ui-message-stream":"v1","x-accel-buffering":"no"};function F11({status:A,statusText:Q,headers:B,stream:w,consumeSseStream:$}){let f=w.pipeThrough(new ea2);if($){let[I,D]=f.tee();f=I,$({stream:D})}return new Response(f.pipeThrough(new TextEncoderStream),{status:A,statusText:Q,headers:ta2(B,At2)})}var Al=K.record(K.string(),WM.optional()),v3w=zBA(()=>ec(K.union([K.strictObject({type:K.literal("text-start"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("text-delta"),id:K.string(),delta:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("text-end"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("error"),errorText:K.string()}),K.strictObject({type:K.literal("tool-input-start"),toolCallId:K.string(),toolName:K.string(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:Al.optional(),dynamic:K.boolean().optional(),title:K.string().optional()}),K.strictObject({type:K.literal("tool-input-delta"),toolCallId:K.string(),inputTextDelta:K.string()}),K.strictObject({type:K.literal("tool-input-available"),toolCallId:K.string(),toolName:K.string(),input:K.unknown(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:Al.optional(),dynamic:K.boolean().optional(),title:K.string().optional()}),K.strictObject({type:K.literal("tool-input-error"),toolCallId:K.string(),toolName:K.string(),input:K.unknown(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:Al.optional(),dynamic:K.boolean().optional(),errorText:K.string(),title:K.string().optional()}),K.strictObject({type:K.literal("tool-approval-request"),approvalId:K.string(),toolCallId:K.string()}),K.strictObject({type:K.literal("tool-output-available"),toolCallId:K.string(),output:K.unknown(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:Al.optional(),dynamic:K.boolean().optional(),preliminary:K.boolean().optional()}),K.strictObject({type:K.literal("tool-output-error"),toolCallId:K.string(),errorText:K.string(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:Al.optional(),dynamic:K.boolean().optional()}),K.strictObject({type:K.literal("tool-output-denied"),toolCallId:K.string()}),K.strictObject({type:K.literal("reasoning-start"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("reasoning-delta"),id:K.string(),delta:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("reasoning-end"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("source-url"),sourceId:K.string(),url:K.string(),title:K.string().optional(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("source-document"),sourceId:K.string(),mediaType:K.string(),title:K.string(),filename:K.string().optional(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("file"),url:K.string(),mediaType:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.custom((A)=>typeof A==="string"&&A.startsWith("data-"),{message:'Type must start with "data-"'}),id:K.string().optional(),data:K.unknown(),transient:K.boolean().optional()}),K.strictObject({type:K.literal("start-step")}),K.strictObject({type:K.literal("finish-step")}),K.strictObject({type:K.literal("start"),messageId:K.string().optional(),messageMetadata:K.unknown().optional()}),K.strictObject({type:K.literal("finish"),finishReason:K.enum(["stop","length","content-filter","tool-calls","error","other"]).optional(),messageMetadata:K.unknown().optional()}),K.strictObject({type:K.literal("abort"),reason:K.string().optional()}),K.strictObject({type:K.literal("message-metadata"),messageMetadata:K.unknown()})])));function Qt2(A){return A.type.startsWith("data-")}function jkA(A){return A.type.startsWith("tool-")}function Bt2(A){return A.type==="dynamic-tool"}function w11(A){return jkA(A)||Bt2(A)}function $11(A){return A.type.split("-").slice(1).join("-")}function wt2({lastMessage:A,messageId:Q}){return{message:(A==null?void 0:A.role)==="assistant"?A:{id:Q,metadata:void 0,role:"assistant",parts:[]},activeTextParts:{},activeReasoningParts:{},partialToolCalls:{}}}function $t2({stream:A,messageMetadataSchema:Q,dataPartSchemas:B,runUpdateMessageJob:w,onError:$,onToolCall:f,onData:I}){return A.pipeThrough(new TransformStream({async transform(D,U){await w(async({state:Y,write:J})=>{var X,G,Z,N;function V(E){let T=Y.message.parts.filter(w11).find((y)=>y.toolCallId===E);if(T==null)throw new $_({chunkType:"tool-invocation",chunkId:E,message:`No tool invocation found for tool call ID "${E}".`});return T}function L(E){var S;let T=Y.message.parts.find((x)=>jkA(x)&&x.toolCallId===E.toolCallId),y=E,_=T;if(T!=null){if(T.state=E.state,_.input=y.input,_.output=y.output,_.errorText=y.errorText,_.rawInput=y.rawInput,_.preliminary=y.preliminary,E.title!==void 0)_.title=E.title;if(E.toolMetadata!==void 0)_.toolMetadata=E.toolMetadata;_.providerExecuted=(S=y.providerExecuted)!=null?S:T.providerExecuted;let x=y.providerMetadata;if(x!=null)if(E.state==="output-available"||E.state==="output-error"){let g=T;g.resultProviderMetadata=x}else T.callProviderMetadata=x}else Y.message.parts.push({type:`tool-${E.toolName}`,toolCallId:E.toolCallId,state:E.state,title:E.title,...E.toolMetadata!==void 0?{toolMetadata:E.toolMetadata}:{},input:y.input,output:y.output,rawInput:y.rawInput,errorText:y.errorText,providerExecuted:y.providerExecuted,preliminary:y.preliminary,...y.providerMetadata!=null&&(E.state==="output-available"||E.state==="output-error")?{resultProviderMetadata:y.providerMetadata}:{},...y.providerMetadata!=null&&!(E.state==="output-available"||E.state==="output-error")?{callProviderMetadata:y.providerMetadata}:{}})}function M(E){var S,T;let y=Y.message.parts.find((g)=>g.type==="dynamic-tool"&&g.toolCallId===E.toolCallId),_=E,x=y;if(y!=null){if(y.state=E.state,x.toolName=E.toolName,x.input=_.input,x.output=_.output,x.errorText=_.errorText,x.rawInput=(S=_.rawInput)!=null?S:x.rawInput,x.preliminary=_.preliminary,E.title!==void 0)x.title=E.title;if(E.toolMetadata!==void 0)x.toolMetadata=E.toolMetadata;x.providerExecuted=(T=_.providerExecuted)!=null?T:y.providerExecuted;let g=_.providerMetadata;if(g!=null)if(E.state==="output-available"||E.state==="output-error"){let n=y;n.resultProviderMetadata=g}else y.callProviderMetadata=g}else Y.message.parts.push({type:"dynamic-tool",toolName:E.toolName,toolCallId:E.toolCallId,state:E.state,input:_.input,output:_.output,errorText:_.errorText,preliminary:_.preliminary,providerExecuted:_.providerExecuted,title:E.title,...E.toolMetadata!==void 0?{toolMetadata:E.toolMetadata}:{},..._.providerMetadata!=null&&(E.state==="output-available"||E.state==="output-error")?{resultProviderMetadata:_.providerMetadata}:{},..._.providerMetadata!=null&&!(E.state==="output-available"||E.state==="output-error")?{callProviderMetadata:_.providerMetadata}:{}})}async function O(E){if(E!=null){let S=Y.message.metadata!=null?K11(Y.message.metadata,E):E;if(Q!=null)await VBA({value:S,schema:Q,context:{field:"message.metadata",entityId:Y.message.id}});Y.message.metadata=S}}switch(D.type){case"text-start":{let E={type:"text",text:"",providerMetadata:D.providerMetadata,state:"streaming"};Y.activeTextParts[D.id]=E,Y.message.parts.push(E),J();break}case"text-delta":{let E=Y.activeTextParts[D.id];if(E==null)throw new $_({chunkType:"text-delta",chunkId:D.id,message:`Received text-delta for missing text part with ID "${D.id}". Ensure a "text-start" chunk is sent before any "text-delta" chunks.`});E.text+=D.delta,E.providerMetadata=(X=D.providerMetadata)!=null?X:E.providerMetadata,J();break}case"text-end":{let E=Y.activeTextParts[D.id];if(E==null)throw new $_({chunkType:"text-end",chunkId:D.id,message:`Received text-end for missing text part with ID "${D.id}". Ensure a "text-start" chunk is sent before any "text-end" chunks.`});E.state="done",E.providerMetadata=(G=D.providerMetadata)!=null?G:E.providerMetadata,delete Y.activeTextParts[D.id],J();break}case"reasoning-start":{let E={type:"reasoning",text:"",providerMetadata:D.providerMetadata,state:"streaming"};Y.activeReasoningParts[D.id]=E,Y.message.parts.push(E),J();break}case"reasoning-delta":{let E=Y.activeReasoningParts[D.id];if(E==null)throw new $_({chunkType:"reasoning-delta",chunkId:D.id,message:`Received reasoning-delta for missing reasoning part with ID "${D.id}". Ensure a "reasoning-start" chunk is sent before any "reasoning-delta" chunks.`});E.text+=D.delta,E.providerMetadata=(Z=D.providerMetadata)!=null?Z:E.providerMetadata,J();break}case"reasoning-end":{let E=Y.activeReasoningParts[D.id];if(E==null)throw new $_({chunkType:"reasoning-end",chunkId:D.id,message:`Received reasoning-end for missing reasoning part with ID "${D.id}". Ensure a "reasoning-start" chunk is sent before any "reasoning-end" chunks.`});E.providerMetadata=(N=D.providerMetadata)!=null?N:E.providerMetadata,E.state="done",delete Y.activeReasoningParts[D.id],J();break}case"file":{Y.message.parts.push({type:"file",mediaType:D.mediaType,url:D.url,...D.providerMetadata!=null?{providerMetadata:D.providerMetadata}:{}}),J();break}case"source-url":{Y.message.parts.push({type:"source-url",sourceId:D.sourceId,url:D.url,title:D.title,providerMetadata:D.providerMetadata}),J();break}case"source-document":{Y.message.parts.push({type:"source-document",sourceId:D.sourceId,mediaType:D.mediaType,title:D.title,filename:D.filename,providerMetadata:D.providerMetadata}),J();break}case"tool-input-start":{let E=Y.message.parts.filter(jkA);if(Y.partialToolCalls[D.toolCallId]={text:"",toolName:D.toolName,index:E.length,dynamic:D.dynamic,title:D.title,toolMetadata:D.toolMetadata},D.dynamic)M({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-streaming",input:void 0,providerExecuted:D.providerExecuted,title:D.title,toolMetadata:D.toolMetadata,providerMetadata:D.providerMetadata});else L({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-streaming",input:void 0,providerExecuted:D.providerExecuted,title:D.title,toolMetadata:D.toolMetadata,providerMetadata:D.providerMetadata});J();break}case"tool-input-delta":{let E=Y.partialToolCalls[D.toolCallId];if(E==null)throw new $_({chunkType:"tool-input-delta",chunkId:D.toolCallId,message:`Received tool-input-delta for missing tool call with ID "${D.toolCallId}". Ensure a "tool-input-start" chunk is sent before any "tool-input-delta" chunks.`});E.text+=D.inputTextDelta;let{value:S}=await Ql(E.text);if(E.dynamic)M({toolCallId:D.toolCallId,toolName:E.toolName,state:"input-streaming",input:S,title:E.title,toolMetadata:E.toolMetadata});else L({toolCallId:D.toolCallId,toolName:E.toolName,state:"input-streaming",input:S,title:E.title,toolMetadata:E.toolMetadata});J();break}case"tool-input-available":{if(D.dynamic)M({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-available",input:D.input,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:D.title,toolMetadata:D.toolMetadata});else L({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-available",input:D.input,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:D.title,toolMetadata:D.toolMetadata});if(J(),f&&!D.providerExecuted)await f({toolCall:D});break}case"tool-input-error":{let E=Y.message.parts.filter(w11).find((T)=>T.toolCallId===D.toolCallId);if(E!=null?E.type==="dynamic-tool":!!D.dynamic)M({toolCallId:D.toolCallId,toolName:D.toolName,state:"output-error",input:D.input,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,toolMetadata:D.toolMetadata});else L({toolCallId:D.toolCallId,toolName:D.toolName,state:"output-error",input:void 0,rawInput:D.input,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,toolMetadata:D.toolMetadata});J();break}case"tool-approval-request":{let E=V(D.toolCallId);E.state="approval-requested",E.approval={id:D.approvalId},J();break}case"tool-output-denied":{let E=V(D.toolCallId);E.state="output-denied",J();break}case"tool-output-available":{let E=V(D.toolCallId);if(E.type==="dynamic-tool")M({toolCallId:D.toolCallId,toolName:E.toolName,state:"output-available",input:E.input,output:D.output,preliminary:D.preliminary,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});else L({toolCallId:D.toolCallId,toolName:$11(E),state:"output-available",input:E.input,output:D.output,providerExecuted:D.providerExecuted,preliminary:D.preliminary,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});J();break}case"tool-output-error":{let E=V(D.toolCallId);if(E.type==="dynamic-tool")M({toolCallId:D.toolCallId,toolName:E.toolName,state:"output-error",input:E.input,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});else L({toolCallId:D.toolCallId,toolName:$11(E),state:"output-error",input:E.input,rawInput:E.rawInput,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});J();break}case"start-step":{Y.message.parts.push({type:"step-start"});break}case"finish-step":{Y.activeTextParts={},Y.activeReasoningParts={};break}case"start":{if(D.messageId!=null)Y.message.id=D.messageId;if(await O(D.messageMetadata),D.messageId!=null||D.messageMetadata!=null)J();break}case"finish":{if(D.finishReason!=null)Y.finishReason=D.finishReason;if(await O(D.messageMetadata),D.messageMetadata!=null)J();break}case"message-metadata":{if(await O(D.messageMetadata),D.messageMetadata!=null)J();break}case"error":{$==null||$(Error(D.errorText));break}default:if(Qt2(D)){if((B==null?void 0:B[D.type])!=null){let T=Y.message.parts.findIndex((_)=>("id"in _)&&("data"in _)&&_.id===D.id&&_.type===D.type),y=T>=0?T:Y.message.parts.length;await VBA({value:D.data,schema:B[D.type],context:{field:`message.parts[${y}].data`,entityName:D.type,entityId:D.id}})}let E=D;if(E.transient){I==null||I(E);break}let S=E.id!=null?Y.message.parts.find((T)=>E.type===T.type&&E.id===T.id):void 0;if(S!=null)S.data=E.data;else Y.message.parts.push(E);I==null||I(E),J()}}U.enqueue(D)})}}))}function ft2({messageId:A,originalMessages:Q=[],onStepFinish:B,onFinish:w,onError:$,stream:f}){let I=Q==null?void 0:Q[Q.length-1];if((I==null?void 0:I.role)!=="assistant")I=void 0;else A=I.id;let D=!1,U=f.pipeThrough(new TransformStream({transform(N,V){if(N.type==="start"){let L=N;if(L.messageId==null&&A!=null)L.messageId=A}if(N.type==="abort")D=!0;V.enqueue(N)}}));if(w==null&&B==null)return U;let Y=wt2({lastMessage:I?structuredClone(I):void 0,messageId:A!=null?A:""}),J=async(N)=>{await N({state:Y,write:()=>{}})},X=!1,G=async()=>{if(X||!w)return;X=!0;let N=Y.message.id===(I==null?void 0:I.id);await w({isAborted:D,isContinuation:N,responseMessage:Y.message,messages:[...N?Q.slice(0,-1):Q,Y.message],finishReason:Y.finishReason})},Z=async()=>{if(!B)return;let N=Y.message.id===(I==null?void 0:I.id);try{await B({isContinuation:N,responseMessage:structuredClone(Y.message),messages:[...N?Q.slice(0,-1):Q,structuredClone(Y.message)]})}catch(V){$(V)}};return $t2({stream:U,runUpdateMessageJob:J,onError:$}).pipeThrough(new TransformStream({async transform(N,V){if(N.type==="finish-step")await Z();V.enqueue(N)},async cancel(){await G()},async flush(){await G()}}))}var y3w=JF({prefix:"aitxt",size:24});function Z11({execute:A,onError:Q=bkA,originalMessages:B,onStepFinish:w,onFinish:$,generateId:f=a01}){let I,D=[],U=new ReadableStream({start(X){I=X}});function Y(X){try{I.enqueue(X)}catch(G){}}try{let X=A({writer:{write(G){Y(G)},merge(G){D.push((async()=>{let Z=G.getReader();while(!0){let{done:N,value:V}=await Z.read();if(N)break;Y(V)}})().catch((Z)=>{Y({type:"error",errorText:Q(Z)})}))},onError:Q}});if(X)D.push(X.catch((G)=>{Y({type:"error",errorText:Q(G)})}))}catch(X){Y({type:"error",errorText:Q(X)})}return new Promise(async(X)=>{while(D.length>0)await D.shift();X()}).finally(()=>{try{I.close()}catch(X){}}),ft2({stream:U,messageId:f(),originalMessages:B,onStepFinish:w,onFinish:$,onError:Q})}var yf=K.record(K.string(),WM.optional()),g3w=zBA(()=>ec(K.array(K.object({id:K.string(),role:K.enum(["system","user","assistant"]),metadata:K.unknown().optional(),parts:K.array(K.union([K.object({type:K.literal("text"),text:K.string(),state:K.enum(["streaming","done"]).optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("reasoning"),text:K.string(),state:K.enum(["streaming","done"]).optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("source-url"),sourceId:K.string(),url:K.string(),title:K.string().optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("source-document"),sourceId:K.string(),mediaType:K.string(),title:K.string(),filename:K.string().optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("file"),mediaType:K.string(),filename:K.string().optional(),url:K.string(),providerMetadata:N2.optional()}),K.object({type:K.literal("step-start")}),K.object({type:K.string().startsWith("data-"),id:K.string().optional(),data:K.unknown()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("input-streaming"),input:K.unknown().optional(),providerExecuted:K.boolean().optional(),callProviderMetadata:N2.optional(),output:K.never().optional(),errorText:K.never().optional(),approval:K.never().optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("input-available"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.never().optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("approval-requested"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.never().optional(),reason:K.never().optional()})}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("approval-responded"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.boolean(),reason:K.string().optional()})}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("output-available"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.unknown(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),preliminary:K.boolean().optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("output-error"),input:K.unknown().optional(),rawInput:K.unknown().optional(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.string(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("output-denied"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!1),reason:K.string().optional()})}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("input-streaming"),providerExecuted:K.boolean().optional(),callProviderMetadata:N2.optional(),input:K.unknown().optional(),output:K.never().optional(),errorText:K.never().optional(),approval:K.never().optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("input-available"),providerExecuted:K.boolean().optional(),input:K.unknown(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.never().optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("approval-requested"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.never().optional(),reason:K.never().optional()})}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("approval-responded"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.boolean(),reason:K.string().optional()})}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("output-available"),providerExecuted:K.boolean().optional(),input:K.unknown(),output:K.unknown(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),preliminary:K.boolean().optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("output-error"),providerExecuted:K.boolean().optional(),input:K.unknown().optional(),rawInput:K.unknown().optional(),output:K.never().optional(),errorText:K.string(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:yf.optional(),state:K.literal("output-denied"),providerExecuted:K.boolean().optional(),input:K.unknown(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!1),reason:K.string().optional()})})])).nonempty("Message must contain at least one part")})).nonempty("Messages array must not be empty")));var m3w=JF({prefix:"aiobj",size:24});function N11(A){return({url:Q,abortSignal:B})=>ya2({url:Q,maxBytes:A==null?void 0:A.maxBytes,abortSignal:B})}var c3w=JF({prefix:"aiobj",size:24});var l3w=N11();var It2="AI_NoSuchProviderError",Dt2=`vercel.ai.error.${It2}`,Ut2=Symbol.for(Dt2),Yt2;Yt2=Ut2;var p3w=N11();var z11={name:"@brains/web-chat",private:!0,version:"0.2.0-alpha.127",description:"Web chat interface for Brains",type:"module",exports:{".":"./src/index.ts"},files:["src","dist","package.json"],scripts:{build:"bun scripts/build-ui.ts","build:ui":"bun scripts/build-ui.ts",typecheck:"tsc --noEmit && tsc --noEmit -p ui-react/tsconfig.json",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix",test:"bun test"},dependencies:{"@ai-sdk/react":"^3.0.116","@brains/auth-service":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@streamdown/cjk":"^1.0.3","@streamdown/code":"^1.1.1","@streamdown/math":"^1.0.2","@streamdown/mermaid":"^1.0.2",ai:"^6.0.86","class-variance-authority":"^0.7.0",cmdk:"^1.1.1","lucide-react":"^1.16.0",nanoid:"^5.0.4","radix-ui":"^1.4.3",react:"^19.2.6","react-dom":"^19.2.6",shiki:"^4.1.0",streamdown:"^2.5.0","use-stick-to-bottom":"^1.1.4"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/react":"^19.0.3","@types/react-dom":"^19.0.3",typescript:"^5.3.3",vite:"^7.2.4"}};async function q11(A,Q){if(!await Q.resolveOperatorSession(A))return Q.createOperatorLoginRequiredResponse(A);let B=new URL(A.url),w=B.searchParams.get("id")?.trim();if(!w)return new Response("Missing document id",{status:400});let $=await Q.entityService.getEntity({entityType:"document",id:w});if(!$)return new Response("Document not found",{status:404});let f=Xt2($.content);if(!f)return new Response("Document content is not a PDF",{status:415});let I=Ht2($.metadata,w);return V11({requestUrl:B,data:f.data,mediaType:f.mimeType,filename:I})}async function L11(A,Q){if(!await Q.resolveOperatorSession(A))return Q.createOperatorLoginRequiredResponse(A);let B=new URL(A.url),w=B.searchParams.get("id")?.trim();if(!w)return new Response("Missing image id",{status:400});let $=await Q.entityService.getEntity({entityType:"image",id:w});if(!$)return new Response("Image not found",{status:404});let f=Wt2($.content);if(!f)return new Response("Image content is not an image",{status:415});let I=Gt2($.metadata,w,f.mimeType);return V11({requestUrl:B,data:f.data,mediaType:f.mimeType,filename:I})}function V11(A){let Q=new Headers({"Content-Type":A.mediaType,"Content-Length":String(A.data.byteLength),"Content-Disposition":`${A.requestUrl.searchParams.has("download")?"attachment":"inline"}; filename="${Kt2(A.filename)}"`});return new Response(A.data,{headers:Q})}function E11(A,Q){let B=A.match(/^data:([^;]+);base64,(.+)$/i);if(!B)return null;let[,w,$]=B;if(!w||!$||!Q.test(w))return null;let f=Buffer.from($,"base64"),I=f.buffer.slice(f.byteOffset,f.byteOffset+f.byteLength);return{mimeType:w,data:I}}function Xt2(A){let Q=E11(A,/^application\/pdf$/i);if(Q?.mimeType.toLowerCase()!=="application/pdf")return null;return{mimeType:"application/pdf",data:Q.data}}function Wt2(A){return E11(A,/^image\/[a-z0-9.+-]+$/i)}function Ht2(A,Q){let B=A?.filename;return typeof B==="string"&&B.length>0?B:`${Q}.pdf`}function Gt2(A,Q,B){let w=A?.filename;if(typeof w==="string"&&w.length>0)return w;let $=A?.format;if(typeof $==="string"&&$.length>0)return`${Q}.${$==="jpeg"?"jpg":$}`;let f=B.split("/")[1];return`${Q}.${f&&f.length>0?f:"png"}`}function Kt2(A){return A.replace(/["\\\r\n]/g,"_")}WA();aA();var Bl="upload",M11=lR;var Ft2={namespace:"upload",refKind:Bl,routePath:"/api/chat/uploads"};function EBA(){return Ft2}aA();var O11="upload.txt";var R11=5000000,Zt2=[".md",".txt",".markdown"],Nt2=["text/plain","text/markdown","text/x-markdown"],_kA=new Map([[".png","image/png"],[".jpg","image/jpeg"],[".jpeg","image/jpeg"],[".webp","image/webp"],[".gif","image/gif"],[".pdf","application/pdf"]]),zt2=new Set(_kA.values());function CBA(A){let Q=A.split(/[\\/]/).at(-1)?.trim()??"",B=Array.from(Q).filter((w)=>{let $=w.charCodeAt(0);return $>31&&$!==127}).join("").slice(0,160);return B.length>0?B:"upload.txt"}function b11(A,Q){let B=Q?.trim()??"";if(B.length>0)return B;let w=A.toLowerCase();if(w.endsWith(".md")||w.endsWith(".markdown"))return"text/markdown";if(w.endsWith(".txt"))return"text/plain";return"application/octet-stream"}function P11(A,Q){let B=Q?.trim()??"",w=B.split(";",1)[0]?.toLowerCase()??B;if(w.length>0&&w!=="application/octet-stream")return w;let $=b11(A,void 0);if($!=="application/octet-stream")return $;let f=A.toLowerCase();for(let[I,D]of _kA)if(f.endsWith(I))return D;return"application/octet-stream"}function k11(A,Q){if(Q&&Nt2.some((B)=>Q.toLowerCase().startsWith(B)))return!0;return Zt2.some((B)=>A.toLowerCase().endsWith(B))}function qt2(A){return A<=1e5}function Lt2(A){return A<=5000000}function Vt2(A,Q){let B=P11(A,Q);if(zt2.has(B))return!0;return _kA.has(Ct2(A))}function Et2(A){if(A.includes(0))return!1;try{return new TextDecoder("utf-8",{fatal:!0}).decode(A),!0}catch{return!1}}function Mt2(A){let Q=CBA(A.filename),B=b11(Q,A.mediaType);if(!k11(Q,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};if(!qt2(A.content.byteLength))return{ok:!1,code:"file_too_large",message:`File upload too large: ${Q}`};if(!Et2(A.content))return{ok:!1,code:"binary_content",message:`Unsupported file upload type: ${Q}`};return{ok:!0,filename:Q,mediaType:B,sizeBytes:A.content.byteLength,text:new TextDecoder("utf-8").decode(A.content).replace(/^\uFEFF/,"")}}function OBA(A){let Q=CBA(A.filename),B=P11(Q,A.mediaType);if(k11(Q,B)){let w=Mt2({filename:Q,mediaType:B,content:A.content});return w.ok?{...w,kind:"text"}:w}if(!Vt2(Q,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};if(!Lt2(A.content.byteLength))return{ok:!1,code:"file_too_large",message:`File upload too large: ${Q}`};if(!Ot2(A.content,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};return{ok:!0,kind:"file",filename:Q,mediaType:B,sizeBytes:A.content.byteLength}}function Ct2(A){let Q=A.lastIndexOf(".");return Q>=0?A.slice(Q).toLowerCase():""}function Ot2(A,Q){switch(Q){case"image/png":return C11(A,[137,80,78,71]);case"image/jpeg":return C11(A,[255,216,255]);case"image/gif":return MBA(A,"GIF87a")||MBA(A,"GIF89a");case"image/webp":return MBA(A,"RIFF")&&j11(A,"WEBP",8);case"application/pdf":return MBA(A,"%PDF-");default:return!1}}function C11(A,Q){return Q.every((B,w)=>A[w]===B)}function MBA(A,Q){return j11(A,Q,0)}function j11(A,Q,B){return Array.from(Q).every((w,$)=>A[B+$]===w.charCodeAt(0))}var Rt2="file",bt2=16384;async function _11(A,Q){if(!await Q.resolveOperatorSession(A))return new Response("Forbidden",{status:403});let B=Number(A.headers.get("content-length"));if(Number.isFinite(B)&&B>R11+bt2)return new Response("File upload too large",{status:400});let w;try{w=await A.formData()}catch{return new Response("Invalid multipart upload",{status:400})}let $=w.get(Rt2);if(!($ instanceof File))return new Response("Missing upload file",{status:400});let f=Buffer.from(await $.arrayBuffer()),I=OBA({filename:$.name,mediaType:$.type,content:f});if(!I.ok)return new Response(I.message,{status:400});let D=Q.getUploadStore(),U=await D.save({filename:I.filename,mediaType:I.mediaType,content:f});return Response.json(D.toResponseBody(U),{status:201})}async function v11(A,Q){if(!await Q.resolveOperatorSession(A))return new Response("Forbidden",{status:403});let B=new URL(A.url).searchParams.get("id")?.trim();if(!B)return new Response("Missing upload id",{status:400});let w=await x11(B,Q.getUploadStore());if(w instanceof Response)return w;let{record:$,content:f}=w,I=S11($,f);if(I instanceof Response)return I;let D=new URL(A.url).searchParams.has("download")?"attachment":"inline",U=new Uint8Array(f).buffer;return new Response(U,{headers:{"Content-Type":$.mediaType,"Content-Length":String(f.byteLength),"Content-Disposition":`${D}; filename="${jt2($.filename)}"`}})}function y11(A){let Q=CBA(A.filename??O11),B=kt2(A.url);if(!B)return new Response(`Unsupported file upload URL: ${Q}`,{status:400});let w=OBA({filename:Q,mediaType:A.mediaType,content:B.buffer});if(!w.ok)return new Response(w.message,{status:400});return g11(w,B.buffer)}async function T11(A,Q){let B=await x11(A,Q);if(B instanceof Response)return B;let{record:w,content:$}=B,f=S11(w,$);if(f instanceof Response)return f;return g11(f,$,{kind:Bl,id:A})}async function x11(A,Q){try{return await Q.read(A)}catch(B){if(B instanceof DW)return Pt2(B);throw B}}function S11(A,Q){let B=OBA({filename:A.filename,mediaType:A.mediaType,content:Q});if(!B.ok)return new Response(B.message,{status:400});return B}function g11(A,Q,B){if(A.kind==="text")return{kind:"text",filename:A.filename,mediaType:A.mediaType,content:A.text,sizeBytes:A.sizeBytes,...B!==void 0?{source:B}:{}};return{kind:"file",filename:A.filename,mediaType:A.mediaType,data:new Uint8Array(Q),sizeBytes:A.sizeBytes,...B!==void 0?{source:B}:{}}}function Pt2(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 kt2(A){let Q=/^data:[^,]*,(.*)$/s.exec(A);if(!Q)return null;let w=A.slice(5,A.indexOf(",")).split(";").some(($)=>$.toLowerCase()==="base64");try{let $=w?Buffer.from(Q[1]??"","base64"):Buffer.from(decodeURIComponent(Q[1]??""),"utf8");return{buffer:$,byteLength:$.byteLength}}catch{return null}}function jt2(A){return A.replace(/["\\\r\n]/g,"_")}var _t2=H.object({type:H.literal("text"),text:H.string()}),vt2=H.object({type:H.literal("file"),mediaType:H.string().optional(),filename:H.string().optional(),url:H.string()}),yt2=H.object({state:H.literal("approval-responded"),approval:H.object({id:H.string(),approved:H.boolean()})}).passthrough(),Tt2=H.object({role:H.string(),parts:H.array(H.unknown()).optional(),content:H.string().optional()}),h11=H.object({id:H.string().optional(),messages:H.array(Tt2).min(1),trigger:H.string().optional()}),xt2=H.object({kind:H.literal(Bl),id:H.string().regex(M11)}),St2=H.object({type:H.literal("data-upload"),data:H.object({ref:xt2})});async function m11(A,Q){let B=gt2(A);if(!B)return{message:"",attachments:[]};let w=[],$=[];for(let I of B.parts??[]){let D=_t2.safeParse(I);if(D.success){if(D.data.text.length>0)w.push(D.data.text);continue}let U=vt2.safeParse(I);if(U.success){let J=y11(U.data);if(J instanceof Response)return J;$.push(J);continue}let Y=St2.safeParse(I);if(Y.success){let J=await T11(Y.data.data.ref.id,Q.uploadStore);if(J instanceof Response)return J;$.push(J);continue}if(ht2(I)==="data-upload")return new Response("Invalid upload ref",{status:400})}return{message:w.length>0?w.join(`
|
|
2484
2484
|
|
|
2485
2485
|
`):B.content??"",attachments:$}}function u11(A){let Q=A.messages.at(-1);if(!Q||Q.role==="user")return[];return(Q.parts??[]).map((B)=>yt2.safeParse(B)).filter((B)=>B.success).map((B)=>B.data.approval)}function gt2(A){for(let Q=A.messages.length-1;Q>=0;Q-=1){let B=A.messages[Q];if(B?.role==="user")return B}return}function ht2(A){if(typeof A!=="object"||A===null||!("type"in A))return;let Q=A.type;return typeof Q==="string"?Q:void 0}function c11(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}function mt2(A){return c11(A)&&A.kind==="upload"&&typeof A.id==="string"}function wl(A){if(mt2(A))return"uploaded file";if(Array.isArray(A))return A.map((Q)=>wl(Q));if(!c11(A))return A;return l11(A)}function l11(A){return Object.fromEntries(Object.entries(A).map(([Q,B])=>[Q,wl(B)]))}function ut2(A){if(A.kind!=="tool-approval")return A;return{...A,...A.input!==void 0?{input:l11(A.input)}:{},...A.output!==void 0?{output:wl(A.output)}:{}}}function p11(A,Q,B){A.write({type:"text-start",id:Q}),A.write({type:"text-delta",id:Q,delta:B}),A.write({type:"text-end",id:Q})}function vkA(A,Q){for(let B of Q){let w=ut2(B);if(w.kind==="attachment"){A.write({type:"data-attachment",id:w.id,data:w});continue}if(w.kind==="sources"){A.write({type:"data-sources",id:w.id,data:w});continue}if(w.kind==="actions"){A.write({type:"data-actions",id:w.id,data:w});continue}let $=w.toolCallId??w.id,f=w.input??{};switch(A.write({type:"tool-input-available",toolCallId:$,toolName:w.toolName,input:f,dynamic:!0,title:w.preview?`${w.summary}
|
|
2486
2486
|
|
|
@@ -4634,7 +4634,7 @@ details.web-chat-data-part[open] > summary > .web-chat-data-part-chevron {
|
|
|
4634
4634
|
|
|
4635
4635
|
`);$=I.pop()??"";for(let D of I){let U=D.split(`
|
|
4636
4636
|
`).find((L)=>L.startsWith("data: "));if(!U)continue;let Y;try{Y=JSON.parse(U.slice(6))}catch{return B.cancel().catch(()=>{}),{success:!1,error:"Malformed SSE event from remote agent"}}let J=Y.result;if(!J)continue;if(J.final!==!0)continue;B.cancel().catch(()=>{});let G=J.status,Z=G?.state??"unknown",V=(G?.message?.parts??[]).filter((L)=>L.kind==="text"&&typeof L.text==="string").map((L)=>L.text).join(`
|
|
4637
|
-
`)||"No response text";return{success:!0,data:{state:Z,response:V}}}f=await F21(B,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class $l extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A;this.name="A2ARequestTimeoutError"}}class fl extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A;this.name="A2AStreamIdleTimeoutError"}}async function qe2(A,Q,B,w){let $=new AbortController,f;try{return await Promise.race([A(Q,{...B,signal:$.signal}),new Promise((I,D)=>{f=setTimeout(()=>{$.abort(),D(new $l(w))},w)})])}catch(I){if(I instanceof $l)throw I;if($.signal.aborted)throw new $l(w);throw I}finally{if(f)clearTimeout(f)}}async function F21(A,Q){let B;try{return await Promise.race([A.read(),new Promise((w,$)=>{B=setTimeout(()=>$(new fl(Q)),Q)})])}catch(w){if(w instanceof fl)A.cancel().catch(()=>{});throw w}finally{if(B)clearTimeout(B)}}function Le2(A){if(A instanceof $l||A instanceof fl)return!0;return A instanceof Error}function Ve2(A,Q){let B=Q>1?` after ${Q} attempts`:"";if(A instanceof fl)return`${A.message}${B}`;let w=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${B}: ${w}`}function N21(A={}){let Q=A.fetch??globalThis.fetch,B={requestTimeoutMs:A.requestTimeoutMs??He2,streamIdleTimeoutMs:A.streamIdleTimeoutMs??Ge2,maxNetworkAttempts:A.maxNetworkAttempts??Ke2};return{name:"a2a_call",description:"Call a saved remote A2A agent by its local directory id. Use this when the user asks what a saved agent has to say or asks a saved agent for its skills/capabilities. Use only a saved agent id such as yeehaa.io or docs.rizom.ai. For follow-ups to a prior exact-id call, call again with the same id so the tool revalidates current directory state. Never pass a display name like Brain, never pass a full URL, and do not use this tool to probe whether an agent exists. If the user gives a URL, an unsaved agent, or an ambiguous name, ask them to add/save or clarify the agent first.",inputSchema:K21,visibility:"anchor",handler:async(w)=>{let $=H.object(K21).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{agent:f,message:I}=$.data,D=Fe2(f);if(!D)return{success:!1,error:"Invalid agent id. Use a saved agent id from your directory, not a URL."};if(!A.entityService)return{success:!1,error:"Agent directory is unavailable. Add the agent first, then try again."};let U=await A.entityService.getEntity({entityType:"agent",id:D,visibilityScope:a$("a2a_call tool is anchor-only and resolves saved remote agents at any visibility")});if(!U)return{success:!1,error:`Agent ${D} is not in your directory. Add it first.`};if(U.metadata.status!=="approved")return{success:!1,error:`Agent ${D} is discovered but not approved yet. Approve it first.`};let Y=`https://${D}`,J=await Ze2(Y,Q);if(!J)return{success:!1,error:`Could not fetch Agent Card from ${Y}`};let X=J.url,G;if(A.outboundTokens)try{let Z=new URL(X).hostname;G=A.outboundTokens[Z]}catch{}return Ne2(X,I,Q,G,B)}}}var ukA={name:"@brains/a2a",private:!0,version:"0.2.0-alpha.125",type:"module",main:"./src/index.ts",module:"./src/index.ts",types:"./src/index.ts",files:["src"],scripts:{typecheck:"tsc --noEmit",lint:"eslint --max-warnings 0 .","lint:fix":"eslint --fix .",test:"bun test"},dependencies:{"@a2a-js/sdk":"^0.3.12","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",hono:"^4.7.10"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",typescript:"^5.3.3"}};var Me2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","X-Content-Type-Options":"nosniff"};class I_ extends IW{agentCard;taskManager=new hkA;agentService;permissionContext;app;hasWebserver=!1;constructor(A={}){super("a2a",ukA,A,D21)}async onRegister(A){if(await super.onRegister(A),this.hasWebserver=A.plugins.has("webserver"),this.agentService=A.agent,this.permissionContext=A.permissions,this.hasWebserver)A.endpoints.register({label:"A2A",url:"/a2a",priority:25}),A.interactions.register({id:"a2a",label:"A2A",description:"Let other agents discover and talk to this brain.",href:"/a2a",kind:"agent",priority:25}),this.logger.info("A2A interface registered",{domain:A.domain});else this.logger.info("A2A interface registered in tool-only mode",{domain:A.domain})}async onReady(A){await this.rebuildAgentCard(A)}async rebuildAgentCard(A){let Q=A.identity.get(),B=A.identity.getProfile(),w=A.tools.listForPermissionLevel("public"),$=this.config.trustedTokens&&Object.keys(this.config.trustedTokens).length>0,f;if(A.entityService.hasEntityType("skill"))try{let I=await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}});if(I.length>0)f=I.map((D)=>jI.safeParse(D.metadata)).filter((D)=>D.success).map((D)=>D.data)}catch{}this.agentCard=U21({character:Q,profile:B,version:ukA.version,domain:A.domain,organization:this.config.organization,tools:w,skills:f,authEnabled:$}),this.logger.debug("Agent Card rebuilt",{skills:this.agentCard.skills.length})}getAgentCard(){return this.agentCard}resolveCallerPermission(A){if(!A?.startsWith("Bearer ")||!this.config.trustedTokens)return"public";let Q=A.slice(7),B=this.config.trustedTokens[Q];if(!B||!this.permissionContext)return"public";return this.permissionContext.getUserLevel("a2a",B)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(Me2))Q.set(B,w);return new Response(A.body,{status:A.status,statusText:A.statusText,headers:Q})}getOrCreateApp(){if(this.app)return this.app;let A=new A_;return A.get("/.well-known/agent-card.json",(Q)=>{if(!this.agentCard)return this.withCors(Q.json({error:"Agent Card not ready"},503));return this.withCors(Q.json(this.agentCard))}),A.get("/a2a",(Q)=>{return this.withCors(Q.json({error:"Use POST with JSON-RPC 2.0 requests.",agentCard:"/.well-known/agent-card.json"},405))}),A.options("/a2a",()=>this.withCors(new Response(null,{status:204}))),A.post("/a2a",async(Q)=>{if(!this.agentService)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32603,message:"Agent service not ready"},id:null},503));let B;try{B=await Q.req.json()}catch{return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32700,message:"Parse error"},id:null}))}let w=X21.safeParse(B);if(!w.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32600,message:"Invalid request"},id:null}));let $=this.resolveCallerPermission(Q.req.header("Authorization"));if(w.data.method==="message/stream"){let I=H21.safeParse(w.data.params??{});if(!I.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32602,message:`Invalid params: ${I.error.message}`},id:w.data.id}));let{stream:D}=G21(w.data.id,I.data.message,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(new Response(D,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}))}let f=await W21(w.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(Q.json(f))}),this.app=A,A}getWebRoutes(){if(!this.hasWebserver)return[];let A=(Q)=>Promise.resolve(this.getOrCreateApp().fetch(Q));return[{path:"/.well-known/agent-card.json",method:"GET",public:!0,handler:A},{path:"/a2a",method:"GET",public:!0,handler:A},{path:"/a2a",method:"POST",public:!0,handler:A},{path:"/a2a",method:"OPTIONS",public:!0,handler:A}]}async getTools(){return[N21({outboundTokens:this.config.outboundTokens,requestTimeoutMs:this.config.requestTimeoutMs,streamIdleTimeoutMs:this.config.streamIdleTimeoutMs,maxNetworkAttempts:this.config.maxNetworkAttempts,entityService:this.getContext().entityService})]}async getInstructions(){return"## Agent-to-agent calls\n- Use `a2a_call` only for agents already saved in the local `agent` directory.\n- Pass only the saved local agent id to `a2a_call` (for example `yeehaa.io` or `docs.rizom.ai`). Never pass a full URL or a display name like `Brain`.\n- If the user names an exact saved local agent id such as `yeehaa.io` or `docs.rizom.ai`, call `a2a_call` directly with that id. Do not preflight with `system_list` or `system_get`; the tool validates saved/approved status and reports errors.\n- If the user asks you to ask, message, contact, hear what a saved agent has to say, or ask a saved agent for its own skills/capabilities, treat that as an agent-directory request first and call `a2a_call` in the same turn. Do not stop after listing the agent, drafting the question, searching general content locally, or reading the saved agent entity metadata.\n- After `a2a_call` returns within a turn, answer that turn from its response. Do **not** supplement with `system_get` (or any other read tool) on the agent entity, unless the user explicitly asks for directory/profile details about the agent itself.\n- Do not create, capture, or generate a note containing the user's question in the same turn as a saved-agent contact request. The user asked to ask the saved agent, not to persist the question.\n- If `a2a_call` fails because auth, re-authentication, network, or the remote agent is unavailable, report that failure directly. Do not answer from memory, local docs, onboarding docs, or general knowledge; the saved agent was the requested source.\n- Each new turn that asks the same saved agent something \u2014 including short follow-ups like \"what skills does it have\", \"and what about X\", \"tell me more\" \u2014 is a **new** contact request and needs its **own** fresh `a2a_call`. Do not assume the previous turn's a2a response already covers a new question, and do not substitute `system_list`/`system_get` or a no-tool answer for the fresh call. If the previous turn targeted an exact saved local id such as `yeehaa.io`, use that same id again for the follow-up even if the previous response was a refusal or error; let `a2a_call` validate the current directory state again.\n- If the user gives a full URL for an agent, do not pass that URL to `a2a_call`. Use a saved local agent id only. If that URL is not already saved in the local directory, tell the user to add it first.\n- If the user refers to an agent by name, first make sure that name resolves to exactly one saved agent id. If multiple saved agents could match, ask a concise clarification question naming the matching saved agent ids and do not call any agent yet. Never choose the first match.\n- After asking that clarification question, end the turn. Do not call `a2a_call` later in the same turn.\n- If the target agent is not in the directory, do not create a wish, reminder, todo, note, fallback task, or any new entity. Tell the user to add it first.\n- In these invalid agent-target cases, do not call any tool unless the user explicitly asks you to add/save the agent.\n- Only use creation tools for an agent if the user explicitly asks you to add or save that agent.\n- If the target agent is discovered but not approved yet, do not call it and do not create a wish. Tell the user it must be approved first."}createDaemon(){return{start:async()=>{if(this.hasWebserver)this.logger.info("A2A mounted on shared webserver host");else this.logger.info("A2A running without webserver routes")},stop:async()=>{this.logger.info("A2A server stopped")}}}}aA();class ckA{logger;handleImport;handleDelete;deleteOnFileRemoval;fileOperations;constructor(A,Q,B,w,$=!0){if(this.logger=A,this.fileOperations=w,this.deleteOnFileRemoval=$,B)this.handleImport=async(f)=>{let I=await B({type:"directory-import",data:{paths:[f]}});this.logger.debug("Queued import job for file change",{jobId:I,path:f})},this.handleDelete=async(f)=>{if(!this.deleteOnFileRemoval){this.logger.warn("File deleted but deleteOnFileRemoval is disabled",{path:f});return}try{let{entityType:I,id:D}=this.fileOperations.parseEntityFromPath(f),U=await B({type:"directory-delete",data:{entityId:D,entityType:I,filePath:f}});this.logger.info("Queued delete job for removed file",{jobId:U,path:f,entityId:D,entityType:I})}catch(I){this.logger.warn("Could not extract entity info from deleted file",{path:f,error:I})}};else this.handleImport=async(f)=>{await Q([f])},this.handleDelete=async(f)=>{this.logger.warn("File deleted but no job queue available",{path:f})}}async handleFileChange(A,Q){this.logger.debug("Processing file change",{event:A,path:Q});try{switch(A){case"add":case"change":await this.handleImport(Q);break;case"delete":case"unlink":await this.handleDelete(Q);break;default:this.logger.debug("Unhandled file event",{event:A,path:Q})}}catch(B){this.logger.error("Failed to handle file change",{event:A,path:Q,error:B})}}}var xB1=U1(vB1(),1);import{extname as VQQ}from"path";var dBA=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function FM(A){let Q=VQQ(A).toLowerCase();return dBA.includes(Q)}function yB1(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 ujA(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as EQQ,relative as MQQ,sep as TB1,join as CQQ}from"path";function iU(A,Q){return EQQ(Q)?Q:CQQ(A,Q)}function H_(A,Q){let B=iU(A,Q),w=MQQ(A,B);return TB1==="/"?w:w.split(TB1).join("/")}function OQQ(A,Q){if(!H_(Q,A).startsWith("image/"))return!1;return FM(A)}function RQQ(A,Q){if(H_(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return OQQ(A,Q)}class cjA{watcher;watchCallback;pendingChanges=new Map;batchTimeout;syncPath;watchInterval;logger;onFileChange;constructor(A){this.syncPath=A.syncPath,this.watchInterval=A.watchInterval,this.logger=A.logger,this.onFileChange=A.onFileChange}async start(){if(this.watcher){this.logger.debug("Already watching directory");return}if(this.logger.debug("Starting directory watch",{path:this.syncPath,interval:this.watchInterval}),this.watcher=xB1.default.watch(this.syncPath,{ignored:/(^|[/\\])\../,persistent:!0,interval:this.watchInterval,awaitWriteFinish:{stabilityThreshold:2000,pollInterval:100}}),this.watcher.on("add",(A)=>void this.handleFileChange("add",A)).on("change",(A)=>void this.handleFileChange("change",A)).on("unlink",(A)=>void this.handleFileChange("delete",A)).on("error",(A)=>this.logger.error("Watcher error",A)),this.watchCallback)this.watcher.on("all",this.watchCallback)}stop(){if(this.watcher)this.watcher.close(),this.watcher=void 0,this.logger.info("Stopped directory watch");if(this.batchTimeout)clearTimeout(this.batchTimeout),this.batchTimeout=void 0}setCallback(A){if(this.watchCallback=A,this.watcher)this.watcher.on("all",A)}async handleFileChange(A,Q){if(!RQQ(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let B=H_(this.syncPath,Q);if(this.pendingChanges.set(B,A),this.batchTimeout)clearTimeout(this.batchTimeout);this.batchTimeout=setTimeout(()=>{this.processPendingChanges()},500)}async processPendingChanges(){if(this.pendingChanges.size===0)return;let A=new Map(this.pendingChanges);this.pendingChanges.clear(),this.batchTimeout=void 0,this.logger.debug("Processing batched file changes",{changeCount:A.size});for(let[Q,B]of A){let w=iU(this.syncPath,Q);try{if(this.onFileChange)await this.onFileChange(B,w)}catch($){this.logger.error("Error processing file change",{path:Q,event:B,error:$})}}}isWatching(){return!!this.watcher}getPendingChangesCount(){return this.pendingChanges.size}}async function SB1(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return bQQ(Q)}function gB1(A){if(A)A.stop();return}function hB1(A,Q){if(A)A.setCallback(Q)}async function bQQ(A){let{logger:Q,syncPath:B,watchInterval:w,importEntities:$,jobQueueCallback:f,fileOperations:I,deleteOnFileRemoval:D}=A,U=new ckA(Q,$,f,I,D),Y=new cjA({syncPath:B,watchInterval:w,logger:Q,onFileChange:async(J,X)=>{await U.handleFileChange(J,X)}});return await Y.start(),Y}async function mB1(A){let Q=Date.now();A.logger.debug("Starting sync (import only)");let B=await A.importEntities(),w=await A.removeOrphanedEntities(),$=Date.now()-Q;return A.markSynced(new Date),A.logger.debug("Sync completed",{duration:$,imported:B.imported,orphansDeleted:w.deleted}),{export:{exported:0,failed:0,errors:[]},import:B,duration:$}}aA();class ljA{logger;syncPath;deleteOnFileRemoval;constructor(A){this.logger=A.logger,this.syncPath=A.syncPath,this.deleteOnFileRemoval=A.deleteOnFileRemoval}prepareBatchOperations(A){let Q=[],B=this.createImportOperations(A);Q.push(...B);let w=B.length;if(this.deleteOnFileRemoval)Q.push({type:"directory-cleanup",data:{}});let $=A.length;return this.logger.debug("Prepared batch operations",{exportOperationsCount:0,importOperationsCount:w,totalFiles:$}),{operations:Q,exportOperationsCount:0,importOperationsCount:w,totalFiles:$}}async queueSyncBatch(A,Q,B,w){let $=this.prepareBatchOperations(B);if($.operations.length===0)return this.logger.debug("No sync operations needed",{source:Q}),null;return{batchId:await A.jobs.enqueueBatch($.operations,{source:Q,rootJobId:w?.rootJobId??X$(),metadata:{progressToken:w?.progressToken,operationType:"file_operations",operationTarget:this.syncPath,pluginId:w?.pluginId??"directory-sync",interfaceType:w?.interfaceType,channelId:w?.channelId}}),operationCount:$.operations.length,exportOperationsCount:$.exportOperationsCount,importOperationsCount:$.importOperationsCount,totalFiles:$.totalFiles}}createImportOperations(A){if(A.length===0)return[];let Q=50,B=[];for(let w=0;w<A.length;w+=Q){let $=A.slice(w,w+Q);B.push({type:"directory-import",data:{batchIndex:Math.floor(w/Q),paths:$,batchSize:$.length}})}return B}}class pjA{syncInProgress=!1;logger;fileOperations;batchOperationsManager;constructor(A){this.logger=A.logger,this.fileOperations=A.fileOperations,this.batchOperationsManager=new ljA({logger:A.logger,syncPath:A.syncPath,deleteOnFileRemoval:A.deleteOnFileRemoval})}async queueSyncBatch(A,Q,B){if(this.syncInProgress)return this.logger.debug("Sync already in progress, skipping",{source:Q}),null;this.syncInProgress=!0;try{let w=await this.fileOperations.getAllSyncFiles();return await this.batchOperationsManager.queueSyncBatch(A,Q,w,B)}finally{this.syncInProgress=!1}}}class ijA{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 yQQ,dirname as TQQ,extname as xQQ}from"path";import{extname as PQQ}from"path";var nBA=[".pdf"],uB1=".meta.json";function ZM(A){let Q=PQQ(A).toLowerCase();return nBA.includes(Q)}function cB1(A){return A.toLowerCase().endsWith(uB1)}function rjA(A){return`${A}${uB1}`}function lB1(A){switch(A.toLowerCase().replace(".","")){case"pdf":default:return"application/pdf"}}import{extname as kQQ,join as oBA}from"path";function sBA(A,Q){let w=H_(A,Q).split("/"),$,f;if(w.length===1)$="note",f=w;else if(w.length>1&&w[0])$=w[0],f=w.slice(1);else $="note",f=w;let I;if(f.length>1){let D=f[f.length-1];if(D)f[f.length-1]=pB1(D);I=f.join(":")}else I=pB1(f[0]??"");return{entityType:$,id:I}}function iB1(A,Q,B,w=".md"){let $=Q.split(":").filter((Y)=>Y.length>0),f=B==="note";if($.length===1)return f?oBA(A,`${$[0]}${w}`):oBA(A,B,`${$[0]}${w}`);let I=$;if($[0]===B)I=$.slice(1);let D=I[I.length-1],U=I.slice(0,-1);if(f)return oBA(A,...U,`${D}${w}`);return oBA(A,B,...U,`${D}${w}`)}function rB1(A){if(A.entityType==="document")return".pdf";if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return ujA(Q);let B=A.content.match(/^data:image\/([a-z+]+);base64,/i);return B?.[1]?ujA(B[1]):".md"}function pB1(A){let Q=kQQ(A).toLowerCase();return Q===".md"||dBA.includes(Q)||nBA.includes(Q)?A.slice(0,-Q.length):A}JU();import{mkdir as SQQ,readFile as G_,writeFile as njA,stat as gQQ,utimes as hQQ}from"fs/promises";import{join as aBA}from"path";import{mkdir as dB1,readdir as _QQ,stat as vQQ}from"fs/promises";import{access as jQQ}from"fs/promises";async function W5(A){try{return await jQQ(A),!0}catch{return!1}}async function djA(A,Q){return aB1(A,Q,{includeDocuments:!1,includeImages:!1})}async function nB1(A,Q){return aB1(A,Q,{includeDocuments:!0,includeImages:!0})}async function oB1(A,Q){if(!await W5(A))await dB1(A,{recursive:!0});for(let B of Q)if(B!=="note")await dB1(aBA(A,B),{recursive:!0})}async function sB1(A,Q){let B=[],w={totalFiles:0,byEntityType:{}};if(!await W5(A))return{files:B,stats:w};let $=await djA(A,Q);for(let f of $)try{let I=aBA(A,f),D=await vQQ(I),{entityType:U}=sBA(A,f);B.push({path:f,entityType:U,modified:D.mtime}),w.totalFiles++,w.byEntityType[U]=(w.byEntityType[U]??0)+1}catch{continue}return{files:B,stats:w}}async function aB1(A,Q,B){let w=[];if(!await W5(A))return w;let $=async(f,I="",D=!1,U=!1)=>{let Y=await _QQ(f,{withFileTypes:!0});for(let J of Y){let X=I?aBA(I,J.name):J.name;if(J.isFile()&&!J.name.endsWith(".invalid")&&!cB1(J.name)){if(J.name.endsWith(".md"))w.push(X);else if(B.includeImages&&D&&FM(J.name))w.push(X);else if(B.includeDocuments&&U&&ZM(J.name))w.push(X)}else if(J.isDirectory()&&!J.name.startsWith(".")){if(I===""&&!Q.hasEntityType(J.name))continue;let G=aBA(f,J.name),Z=J.name==="image"&&I==="",N=J.name==="document"&&I==="";await $(G,X,D||Z,U||N)}}};return await $(A),w}function mQQ(A){return typeof A==="object"&&A!==null}class ojA{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return sBA(this.syncPath,A)}async readEntity(A){let Q=iU(this.syncPath,A),B=await gQQ(Q),{entityType:w,id:$}=this.parseEntityFromPath(A),f=B.birthtime.getTime()>0?B.birthtime:B.mtime,I=B.mtime,D,U;if(FM(A)||ZM(A)){let X=(await G_(Q)).toString("base64"),G=xQQ(A);if(D=`data:${ZM(A)?lB1(G):yB1(G)};base64,${X}`,ZM(A))U=await this.readDocumentSidecar(Q,A)}else D=await G_(Q,"utf-8");let Y={entityType:w,id:$,content:D,created:f,updated:I};if(U)Y.metadata=U;return Y}async readDocumentSidecar(A,Q){let B={mimeType:"application/pdf",filename:yQQ(Q)},w=rjA(A);if(!await W5(w))return B;try{let $=await G_(w,"utf-8"),f=JSON.parse($),I=mQQ(f)?f:{};return{...B,...I}}catch{return B}}async writeEntity(A){let Q=this.getEntityFilePath(A),B=A.entityType==="image",w=A.entityType==="document";if(B||w){let f=B?/^data:image\/[a-z+]+;base64,(.+)$/i:/^data:application\/pdf;base64,(.+)$/i,I=A.content.match(f),D=I?.[1]?Buffer.from(I[1],"base64"):Buffer.from(A.content,"base64"),U=!1;if(await W5(Q)){let Y=await G_(Q),J=gB(Y.toString("base64")),X=gB(D.toString("base64"));if(J===X)U=!0}if(!U)await this.ensureEntityDirectory(A,Q),await njA(Q,D);if(w)await this.writeDocumentSidecar(A,Q);if(U)return}else{let f=this.entityService.serializeEntity(A);if(await W5(Q)){let I=await G_(Q,"utf-8"),D=gB(I),U=gB(f);if(D===U)return}await this.ensureEntityDirectory(A,Q),await njA(Q,f,"utf-8")}let $=new Date(A.updated);await hQQ(Q,$,$)}async ensureEntityDirectory(A,Q){if(A.entityType!=="note")await SQQ(TQQ(Q),{recursive:!0})}async writeDocumentSidecar(A,Q){let B=A.metadata,w={};for(let[I,D]of Object.entries(B)){if(I==="mimeType")continue;if(D===void 0)continue;w[I]=D}let $=rjA(Q),f=`${JSON.stringify(w,null,2)}
|
|
4637
|
+
`)||"No response text";return{success:!0,data:{state:Z,response:V}}}f=await F21(B,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class $l extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A;this.name="A2ARequestTimeoutError"}}class fl extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A;this.name="A2AStreamIdleTimeoutError"}}async function qe2(A,Q,B,w){let $=new AbortController,f;try{return await Promise.race([A(Q,{...B,signal:$.signal}),new Promise((I,D)=>{f=setTimeout(()=>{$.abort(),D(new $l(w))},w)})])}catch(I){if(I instanceof $l)throw I;if($.signal.aborted)throw new $l(w);throw I}finally{if(f)clearTimeout(f)}}async function F21(A,Q){let B;try{return await Promise.race([A.read(),new Promise((w,$)=>{B=setTimeout(()=>$(new fl(Q)),Q)})])}catch(w){if(w instanceof fl)A.cancel().catch(()=>{});throw w}finally{if(B)clearTimeout(B)}}function Le2(A){if(A instanceof $l||A instanceof fl)return!0;return A instanceof Error}function Ve2(A,Q){let B=Q>1?` after ${Q} attempts`:"";if(A instanceof fl)return`${A.message}${B}`;let w=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${B}: ${w}`}function N21(A={}){let Q=A.fetch??globalThis.fetch,B={requestTimeoutMs:A.requestTimeoutMs??He2,streamIdleTimeoutMs:A.streamIdleTimeoutMs??Ge2,maxNetworkAttempts:A.maxNetworkAttempts??Ke2};return{name:"a2a_call",description:"Call a saved remote A2A agent by its local directory id. Use this when the user asks what a saved agent has to say or asks a saved agent for its skills/capabilities. Use only a saved agent id such as yeehaa.io or docs.rizom.ai. For follow-ups to a prior exact-id call, call again with the same id so the tool revalidates current directory state. Never pass a display name like Brain, never pass a full URL, and do not use this tool to probe whether an agent exists. If the user gives a URL, an unsaved agent, or an ambiguous name, ask them to add/save or clarify the agent first.",inputSchema:K21,visibility:"anchor",handler:async(w)=>{let $=H.object(K21).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{agent:f,message:I}=$.data,D=Fe2(f);if(!D)return{success:!1,error:"Invalid agent id. Use a saved agent id from your directory, not a URL."};if(!A.entityService)return{success:!1,error:"Agent directory is unavailable. Add the agent first, then try again."};let U=await A.entityService.getEntity({entityType:"agent",id:D,visibilityScope:a$("a2a_call tool is anchor-only and resolves saved remote agents at any visibility")});if(!U)return{success:!1,error:`Agent ${D} is not in your directory. Add it first.`};if(U.metadata.status!=="approved")return{success:!1,error:`Agent ${D} is discovered but not approved yet. Approve it first.`};let Y=`https://${D}`,J=await Ze2(Y,Q);if(!J)return{success:!1,error:`Could not fetch Agent Card from ${Y}`};let X=J.url,G;if(A.outboundTokens)try{let Z=new URL(X).hostname;G=A.outboundTokens[Z]}catch{}return Ne2(X,I,Q,G,B)}}}var ukA={name:"@brains/a2a",private:!0,version:"0.2.0-alpha.127",type:"module",main:"./src/index.ts",module:"./src/index.ts",types:"./src/index.ts",files:["src"],scripts:{typecheck:"tsc --noEmit",lint:"eslint --max-warnings 0 .","lint:fix":"eslint --fix .",test:"bun test"},dependencies:{"@a2a-js/sdk":"^0.3.12","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",hono:"^4.7.10"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",typescript:"^5.3.3"}};var Me2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","X-Content-Type-Options":"nosniff"};class I_ extends IW{agentCard;taskManager=new hkA;agentService;permissionContext;app;hasWebserver=!1;constructor(A={}){super("a2a",ukA,A,D21)}async onRegister(A){if(await super.onRegister(A),this.hasWebserver=A.plugins.has("webserver"),this.agentService=A.agent,this.permissionContext=A.permissions,this.hasWebserver)A.endpoints.register({label:"A2A",url:"/a2a",priority:25}),A.interactions.register({id:"a2a",label:"A2A",description:"Let other agents discover and talk to this brain.",href:"/a2a",kind:"agent",priority:25}),this.logger.info("A2A interface registered",{domain:A.domain});else this.logger.info("A2A interface registered in tool-only mode",{domain:A.domain})}async onReady(A){await this.rebuildAgentCard(A)}async rebuildAgentCard(A){let Q=A.identity.get(),B=A.identity.getProfile(),w=A.tools.listForPermissionLevel("public"),$=this.config.trustedTokens&&Object.keys(this.config.trustedTokens).length>0,f;if(A.entityService.hasEntityType("skill"))try{let I=await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}});if(I.length>0)f=I.map((D)=>jI.safeParse(D.metadata)).filter((D)=>D.success).map((D)=>D.data)}catch{}this.agentCard=U21({character:Q,profile:B,version:ukA.version,domain:A.domain,organization:this.config.organization,tools:w,skills:f,authEnabled:$}),this.logger.debug("Agent Card rebuilt",{skills:this.agentCard.skills.length})}getAgentCard(){return this.agentCard}resolveCallerPermission(A){if(!A?.startsWith("Bearer ")||!this.config.trustedTokens)return"public";let Q=A.slice(7),B=this.config.trustedTokens[Q];if(!B||!this.permissionContext)return"public";return this.permissionContext.getUserLevel("a2a",B)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(Me2))Q.set(B,w);return new Response(A.body,{status:A.status,statusText:A.statusText,headers:Q})}getOrCreateApp(){if(this.app)return this.app;let A=new A_;return A.get("/.well-known/agent-card.json",(Q)=>{if(!this.agentCard)return this.withCors(Q.json({error:"Agent Card not ready"},503));return this.withCors(Q.json(this.agentCard))}),A.get("/a2a",(Q)=>{return this.withCors(Q.json({error:"Use POST with JSON-RPC 2.0 requests.",agentCard:"/.well-known/agent-card.json"},405))}),A.options("/a2a",()=>this.withCors(new Response(null,{status:204}))),A.post("/a2a",async(Q)=>{if(!this.agentService)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32603,message:"Agent service not ready"},id:null},503));let B;try{B=await Q.req.json()}catch{return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32700,message:"Parse error"},id:null}))}let w=X21.safeParse(B);if(!w.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32600,message:"Invalid request"},id:null}));let $=this.resolveCallerPermission(Q.req.header("Authorization"));if(w.data.method==="message/stream"){let I=H21.safeParse(w.data.params??{});if(!I.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32602,message:`Invalid params: ${I.error.message}`},id:w.data.id}));let{stream:D}=G21(w.data.id,I.data.message,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(new Response(D,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}))}let f=await W21(w.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(Q.json(f))}),this.app=A,A}getWebRoutes(){if(!this.hasWebserver)return[];let A=(Q)=>Promise.resolve(this.getOrCreateApp().fetch(Q));return[{path:"/.well-known/agent-card.json",method:"GET",public:!0,handler:A},{path:"/a2a",method:"GET",public:!0,handler:A},{path:"/a2a",method:"POST",public:!0,handler:A},{path:"/a2a",method:"OPTIONS",public:!0,handler:A}]}async getTools(){return[N21({outboundTokens:this.config.outboundTokens,requestTimeoutMs:this.config.requestTimeoutMs,streamIdleTimeoutMs:this.config.streamIdleTimeoutMs,maxNetworkAttempts:this.config.maxNetworkAttempts,entityService:this.getContext().entityService})]}async getInstructions(){return"## Agent-to-agent calls\n- Use `a2a_call` only for agents already saved in the local `agent` directory.\n- Pass only the saved local agent id to `a2a_call` (for example `yeehaa.io` or `docs.rizom.ai`). Never pass a full URL or a display name like `Brain`.\n- If the user names an exact saved local agent id such as `yeehaa.io` or `docs.rizom.ai`, call `a2a_call` directly with that id. Do not preflight with `system_list` or `system_get`; the tool validates saved/approved status and reports errors.\n- If the user asks you to ask, message, contact, hear what a saved agent has to say, or ask a saved agent for its own skills/capabilities, treat that as an agent-directory request first and call `a2a_call` in the same turn. Do not stop after listing the agent, drafting the question, searching general content locally, or reading the saved agent entity metadata.\n- After `a2a_call` returns within a turn, answer that turn from its response. Do **not** supplement with `system_get` (or any other read tool) on the agent entity, unless the user explicitly asks for directory/profile details about the agent itself.\n- Do not create, capture, or generate a note containing the user's question in the same turn as a saved-agent contact request. The user asked to ask the saved agent, not to persist the question.\n- If `a2a_call` fails because auth, re-authentication, network, or the remote agent is unavailable, report that failure directly. Do not answer from memory, local docs, onboarding docs, or general knowledge; the saved agent was the requested source.\n- Each new turn that asks the same saved agent something \u2014 including short follow-ups like \"what skills does it have\", \"and what about X\", \"tell me more\" \u2014 is a **new** contact request and needs its **own** fresh `a2a_call`. Do not assume the previous turn's a2a response already covers a new question, and do not substitute `system_list`/`system_get` or a no-tool answer for the fresh call. If the previous turn targeted an exact saved local id such as `yeehaa.io`, use that same id again for the follow-up even if the previous response was a refusal or error; let `a2a_call` validate the current directory state again.\n- If the user gives a full URL for an agent, do not pass that URL to `a2a_call`. Use a saved local agent id only. If that URL is not already saved in the local directory, tell the user to add it first.\n- If the user refers to an agent by name, first make sure that name resolves to exactly one saved agent id. If multiple saved agents could match, ask a concise clarification question naming the matching saved agent ids and do not call any agent yet. Never choose the first match.\n- After asking that clarification question, end the turn. Do not call `a2a_call` later in the same turn.\n- If the target agent is not in the directory, do not create a wish, reminder, todo, note, fallback task, or any new entity. Tell the user to add it first.\n- In these invalid agent-target cases, do not call any tool unless the user explicitly asks you to add/save the agent.\n- Only use creation tools for an agent if the user explicitly asks you to add or save that agent.\n- If the target agent is discovered but not approved yet, do not call it and do not create a wish. Tell the user it must be approved first."}createDaemon(){return{start:async()=>{if(this.hasWebserver)this.logger.info("A2A mounted on shared webserver host");else this.logger.info("A2A running without webserver routes")},stop:async()=>{this.logger.info("A2A server stopped")}}}}aA();class ckA{logger;handleImport;handleDelete;deleteOnFileRemoval;fileOperations;constructor(A,Q,B,w,$=!0){if(this.logger=A,this.fileOperations=w,this.deleteOnFileRemoval=$,B)this.handleImport=async(f)=>{let I=await B({type:"directory-import",data:{paths:[f]}});this.logger.debug("Queued import job for file change",{jobId:I,path:f})},this.handleDelete=async(f)=>{if(!this.deleteOnFileRemoval){this.logger.warn("File deleted but deleteOnFileRemoval is disabled",{path:f});return}try{let{entityType:I,id:D}=this.fileOperations.parseEntityFromPath(f),U=await B({type:"directory-delete",data:{entityId:D,entityType:I,filePath:f}});this.logger.info("Queued delete job for removed file",{jobId:U,path:f,entityId:D,entityType:I})}catch(I){this.logger.warn("Could not extract entity info from deleted file",{path:f,error:I})}};else this.handleImport=async(f)=>{await Q([f])},this.handleDelete=async(f)=>{this.logger.warn("File deleted but no job queue available",{path:f})}}async handleFileChange(A,Q){this.logger.debug("Processing file change",{event:A,path:Q});try{switch(A){case"add":case"change":await this.handleImport(Q);break;case"delete":case"unlink":await this.handleDelete(Q);break;default:this.logger.debug("Unhandled file event",{event:A,path:Q})}}catch(B){this.logger.error("Failed to handle file change",{event:A,path:Q,error:B})}}}var xB1=U1(vB1(),1);import{extname as VQQ}from"path";var dBA=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function FM(A){let Q=VQQ(A).toLowerCase();return dBA.includes(Q)}function yB1(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 ujA(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as EQQ,relative as MQQ,sep as TB1,join as CQQ}from"path";function iU(A,Q){return EQQ(Q)?Q:CQQ(A,Q)}function H_(A,Q){let B=iU(A,Q),w=MQQ(A,B);return TB1==="/"?w:w.split(TB1).join("/")}function OQQ(A,Q){if(!H_(Q,A).startsWith("image/"))return!1;return FM(A)}function RQQ(A,Q){if(H_(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return OQQ(A,Q)}class cjA{watcher;watchCallback;pendingChanges=new Map;batchTimeout;syncPath;watchInterval;logger;onFileChange;constructor(A){this.syncPath=A.syncPath,this.watchInterval=A.watchInterval,this.logger=A.logger,this.onFileChange=A.onFileChange}async start(){if(this.watcher){this.logger.debug("Already watching directory");return}if(this.logger.debug("Starting directory watch",{path:this.syncPath,interval:this.watchInterval}),this.watcher=xB1.default.watch(this.syncPath,{ignored:/(^|[/\\])\../,persistent:!0,interval:this.watchInterval,awaitWriteFinish:{stabilityThreshold:2000,pollInterval:100}}),this.watcher.on("add",(A)=>void this.handleFileChange("add",A)).on("change",(A)=>void this.handleFileChange("change",A)).on("unlink",(A)=>void this.handleFileChange("delete",A)).on("error",(A)=>this.logger.error("Watcher error",A)),this.watchCallback)this.watcher.on("all",this.watchCallback)}stop(){if(this.watcher)this.watcher.close(),this.watcher=void 0,this.logger.info("Stopped directory watch");if(this.batchTimeout)clearTimeout(this.batchTimeout),this.batchTimeout=void 0}setCallback(A){if(this.watchCallback=A,this.watcher)this.watcher.on("all",A)}async handleFileChange(A,Q){if(!RQQ(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let B=H_(this.syncPath,Q);if(this.pendingChanges.set(B,A),this.batchTimeout)clearTimeout(this.batchTimeout);this.batchTimeout=setTimeout(()=>{this.processPendingChanges()},500)}async processPendingChanges(){if(this.pendingChanges.size===0)return;let A=new Map(this.pendingChanges);this.pendingChanges.clear(),this.batchTimeout=void 0,this.logger.debug("Processing batched file changes",{changeCount:A.size});for(let[Q,B]of A){let w=iU(this.syncPath,Q);try{if(this.onFileChange)await this.onFileChange(B,w)}catch($){this.logger.error("Error processing file change",{path:Q,event:B,error:$})}}}isWatching(){return!!this.watcher}getPendingChangesCount(){return this.pendingChanges.size}}async function SB1(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return bQQ(Q)}function gB1(A){if(A)A.stop();return}function hB1(A,Q){if(A)A.setCallback(Q)}async function bQQ(A){let{logger:Q,syncPath:B,watchInterval:w,importEntities:$,jobQueueCallback:f,fileOperations:I,deleteOnFileRemoval:D}=A,U=new ckA(Q,$,f,I,D),Y=new cjA({syncPath:B,watchInterval:w,logger:Q,onFileChange:async(J,X)=>{await U.handleFileChange(J,X)}});return await Y.start(),Y}async function mB1(A){let Q=Date.now();A.logger.debug("Starting sync (import only)");let B=await A.importEntities(),w=await A.removeOrphanedEntities(),$=Date.now()-Q;return A.markSynced(new Date),A.logger.debug("Sync completed",{duration:$,imported:B.imported,orphansDeleted:w.deleted}),{export:{exported:0,failed:0,errors:[]},import:B,duration:$}}aA();class ljA{logger;syncPath;deleteOnFileRemoval;constructor(A){this.logger=A.logger,this.syncPath=A.syncPath,this.deleteOnFileRemoval=A.deleteOnFileRemoval}prepareBatchOperations(A){let Q=[],B=this.createImportOperations(A);Q.push(...B);let w=B.length;if(this.deleteOnFileRemoval)Q.push({type:"directory-cleanup",data:{}});let $=A.length;return this.logger.debug("Prepared batch operations",{exportOperationsCount:0,importOperationsCount:w,totalFiles:$}),{operations:Q,exportOperationsCount:0,importOperationsCount:w,totalFiles:$}}async queueSyncBatch(A,Q,B,w){let $=this.prepareBatchOperations(B);if($.operations.length===0)return this.logger.debug("No sync operations needed",{source:Q}),null;return{batchId:await A.jobs.enqueueBatch($.operations,{source:Q,rootJobId:w?.rootJobId??X$(),metadata:{progressToken:w?.progressToken,operationType:"file_operations",operationTarget:this.syncPath,pluginId:w?.pluginId??"directory-sync",interfaceType:w?.interfaceType,channelId:w?.channelId}}),operationCount:$.operations.length,exportOperationsCount:$.exportOperationsCount,importOperationsCount:$.importOperationsCount,totalFiles:$.totalFiles}}createImportOperations(A){if(A.length===0)return[];let Q=50,B=[];for(let w=0;w<A.length;w+=Q){let $=A.slice(w,w+Q);B.push({type:"directory-import",data:{batchIndex:Math.floor(w/Q),paths:$,batchSize:$.length}})}return B}}class pjA{syncInProgress=!1;logger;fileOperations;batchOperationsManager;constructor(A){this.logger=A.logger,this.fileOperations=A.fileOperations,this.batchOperationsManager=new ljA({logger:A.logger,syncPath:A.syncPath,deleteOnFileRemoval:A.deleteOnFileRemoval})}async queueSyncBatch(A,Q,B){if(this.syncInProgress)return this.logger.debug("Sync already in progress, skipping",{source:Q}),null;this.syncInProgress=!0;try{let w=await this.fileOperations.getAllSyncFiles();return await this.batchOperationsManager.queueSyncBatch(A,Q,w,B)}finally{this.syncInProgress=!1}}}class ijA{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 yQQ,dirname as TQQ,extname as xQQ}from"path";import{extname as PQQ}from"path";var nBA=[".pdf"],uB1=".meta.json";function ZM(A){let Q=PQQ(A).toLowerCase();return nBA.includes(Q)}function cB1(A){return A.toLowerCase().endsWith(uB1)}function rjA(A){return`${A}${uB1}`}function lB1(A){switch(A.toLowerCase().replace(".","")){case"pdf":default:return"application/pdf"}}import{extname as kQQ,join as oBA}from"path";function sBA(A,Q){let w=H_(A,Q).split("/"),$,f;if(w.length===1)$="note",f=w;else if(w.length>1&&w[0])$=w[0],f=w.slice(1);else $="note",f=w;let I;if(f.length>1){let D=f[f.length-1];if(D)f[f.length-1]=pB1(D);I=f.join(":")}else I=pB1(f[0]??"");return{entityType:$,id:I}}function iB1(A,Q,B,w=".md"){let $=Q.split(":").filter((Y)=>Y.length>0),f=B==="note";if($.length===1)return f?oBA(A,`${$[0]}${w}`):oBA(A,B,`${$[0]}${w}`);let I=$;if($[0]===B)I=$.slice(1);let D=I[I.length-1],U=I.slice(0,-1);if(f)return oBA(A,...U,`${D}${w}`);return oBA(A,B,...U,`${D}${w}`)}function rB1(A){if(A.entityType==="document")return".pdf";if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return ujA(Q);let B=A.content.match(/^data:image\/([a-z+]+);base64,/i);return B?.[1]?ujA(B[1]):".md"}function pB1(A){let Q=kQQ(A).toLowerCase();return Q===".md"||dBA.includes(Q)||nBA.includes(Q)?A.slice(0,-Q.length):A}JU();import{mkdir as SQQ,readFile as G_,writeFile as njA,stat as gQQ,utimes as hQQ}from"fs/promises";import{join as aBA}from"path";import{mkdir as dB1,readdir as _QQ,stat as vQQ}from"fs/promises";import{access as jQQ}from"fs/promises";async function W5(A){try{return await jQQ(A),!0}catch{return!1}}async function djA(A,Q){return aB1(A,Q,{includeDocuments:!1,includeImages:!1})}async function nB1(A,Q){return aB1(A,Q,{includeDocuments:!0,includeImages:!0})}async function oB1(A,Q){if(!await W5(A))await dB1(A,{recursive:!0});for(let B of Q)if(B!=="note")await dB1(aBA(A,B),{recursive:!0})}async function sB1(A,Q){let B=[],w={totalFiles:0,byEntityType:{}};if(!await W5(A))return{files:B,stats:w};let $=await djA(A,Q);for(let f of $)try{let I=aBA(A,f),D=await vQQ(I),{entityType:U}=sBA(A,f);B.push({path:f,entityType:U,modified:D.mtime}),w.totalFiles++,w.byEntityType[U]=(w.byEntityType[U]??0)+1}catch{continue}return{files:B,stats:w}}async function aB1(A,Q,B){let w=[];if(!await W5(A))return w;let $=async(f,I="",D=!1,U=!1)=>{let Y=await _QQ(f,{withFileTypes:!0});for(let J of Y){let X=I?aBA(I,J.name):J.name;if(J.isFile()&&!J.name.endsWith(".invalid")&&!cB1(J.name)){if(J.name.endsWith(".md"))w.push(X);else if(B.includeImages&&D&&FM(J.name))w.push(X);else if(B.includeDocuments&&U&&ZM(J.name))w.push(X)}else if(J.isDirectory()&&!J.name.startsWith(".")){if(I===""&&!Q.hasEntityType(J.name))continue;let G=aBA(f,J.name),Z=J.name==="image"&&I==="",N=J.name==="document"&&I==="";await $(G,X,D||Z,U||N)}}};return await $(A),w}function mQQ(A){return typeof A==="object"&&A!==null}class ojA{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return sBA(this.syncPath,A)}async readEntity(A){let Q=iU(this.syncPath,A),B=await gQQ(Q),{entityType:w,id:$}=this.parseEntityFromPath(A),f=B.birthtime.getTime()>0?B.birthtime:B.mtime,I=B.mtime,D,U;if(FM(A)||ZM(A)){let X=(await G_(Q)).toString("base64"),G=xQQ(A);if(D=`data:${ZM(A)?lB1(G):yB1(G)};base64,${X}`,ZM(A))U=await this.readDocumentSidecar(Q,A)}else D=await G_(Q,"utf-8");let Y={entityType:w,id:$,content:D,created:f,updated:I};if(U)Y.metadata=U;return Y}async readDocumentSidecar(A,Q){let B={mimeType:"application/pdf",filename:yQQ(Q)},w=rjA(A);if(!await W5(w))return B;try{let $=await G_(w,"utf-8"),f=JSON.parse($),I=mQQ(f)?f:{};return{...B,...I}}catch{return B}}async writeEntity(A){let Q=this.getEntityFilePath(A),B=A.entityType==="image",w=A.entityType==="document";if(B||w){let f=B?/^data:image\/[a-z+]+;base64,(.+)$/i:/^data:application\/pdf;base64,(.+)$/i,I=A.content.match(f),D=I?.[1]?Buffer.from(I[1],"base64"):Buffer.from(A.content,"base64"),U=!1;if(await W5(Q)){let Y=await G_(Q),J=gB(Y.toString("base64")),X=gB(D.toString("base64"));if(J===X)U=!0}if(!U)await this.ensureEntityDirectory(A,Q),await njA(Q,D);if(w)await this.writeDocumentSidecar(A,Q);if(U)return}else{let f=this.entityService.serializeEntity(A);if(await W5(Q)){let I=await G_(Q,"utf-8"),D=gB(I),U=gB(f);if(D===U)return}await this.ensureEntityDirectory(A,Q),await njA(Q,f,"utf-8")}let $=new Date(A.updated);await hQQ(Q,$,$)}async ensureEntityDirectory(A,Q){if(A.entityType!=="note")await SQQ(TQQ(Q),{recursive:!0})}async writeDocumentSidecar(A,Q){let B=A.metadata,w={};for(let[I,D]of Object.entries(B)){if(I==="mimeType")continue;if(D===void 0)continue;w[I]=D}let $=rjA(Q),f=`${JSON.stringify(w,null,2)}
|
|
4638
4638
|
`;if(await W5($)){if(await G_($,"utf-8")===f)return}await this.ensureEntityDirectory(A,$),await njA($,f,"utf-8")}getFilePath(A,Q,B=".md"){return iB1(this.syncPath,A,Q,B)}getEntityFilePath(A){return this.getFilePath(A.id,A.entityType,rB1(A))}async getAllMarkdownFiles(){return djA(this.syncPath,this.entityService)}async getAllSyncFiles(){return nB1(this.syncPath,this.entityService)}async ensureDirectoryStructure(A){await oB1(this.syncPath,A)}shouldUpdateEntity(A,Q){let B=gB(Q.content);return A.contentHash!==B}async gatherFileStatus(){return sB1(this.syncPath,this.entityService)}async syncDirectoryExists(){return W5(this.syncPath)}async fileExists(A){return W5(A)}}C7();WA();C7();async function tBA(A,Q,B,w){let{sourceUrl:$}=A,f=await Q.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}});if(f[0])return w.debug("Reusing existing image entity",{sourceUrl:$,imageId:f[0].id}),f[0].id;let I=await B($),{base64:D}=TN(I),U=ZV(D),Y=xN(D);if(!U||!Y)throw Error("Could not detect image format or dimensions");let J=await Q.createEntity({entity:{id:A.id,entityType:"image",content:I,metadata:{title:A.title,alt:A.alt,format:U,width:Y.width,height:Y.height,sourceUrl:$}}});return w.debug("Created image entity from URL",{sourceUrl:$,imageId:J.entityId}),J.entityId}var tB1=H.object({title:H.string(),slug:H.string().optional(),coverImageUrl:H.string().url(),coverImageId:H.string().optional(),coverImageAlt:H.string().optional()});class sjA{entityService;fetcher;logger;constructor(A,Q,B=qU){this.entityService=A;this.fetcher=B;this.logger=Q.child("FrontmatterImageConverter")}detectCoverImageUrl(A){let Q;try{Q=jB(A)}catch{return null}let{frontmatter:B}=Q,w=tB1.safeParse(B);if(!w.success)return null;if(w.data.coverImageId)return null;let{title:$,slug:f,coverImageUrl:I,coverImageAlt:D}=w.data;if(!gG(I))return null;return{sourceUrl:I,postTitle:$,postSlug:f??X1($),customAlt:D}}async convert(A){let Q;try{Q=jB(A)}catch(Y){return this.logger.debug("Parse failed",{error:Y}),{content:A,converted:!1}}let{frontmatter:B}=Q,w=tB1.safeParse(B);if(!w.success)return{content:A,converted:!1};if(w.data.coverImageId)return{content:A,converted:!1};let{title:$,slug:f,coverImageUrl:I,coverImageAlt:D}=w.data;if(!gG(I))return{content:A,converted:!1};let U={postTitle:$,postSlug:f??X1($),sourceUrl:I,customAlt:D};try{let Y=await this.createImageEntity(U),J={...B};return delete J.coverImageUrl,delete J.coverImageAlt,J.coverImageId=Y,{content:TG(J,Q.content),converted:!0,imageId:Y}}catch(Y){return this.logger.warn("Failed to convert coverImageUrl",{url:I,error:y0(Y)}),{content:A,converted:!1}}}async createImageEntity(A){let{postTitle:Q,postSlug:B,sourceUrl:w,customAlt:$}=A,f=`Cover image for ${Q}`;return tBA({id:`${B}-cover`,title:f,alt:$??f,sourceUrl:w},this.entityService,this.fetcher,this.logger)}}C7();WA();class zl{entityService;fetcher;logger;constructor(A,Q,B=qU){this.entityService=A;this.fetcher=B;this.logger=Q.child("MarkdownImageConverter")}detectInlineImages(A,Q){let B=[],w=ZNA(A);for(let $ of w){if(!gG($.url))continue;if($.url.startsWith("entity://"))continue;let f=this.reconstructMarkdown($);B.push({sourceUrl:$.url,alt:$.alt,originalMarkdown:f,postSlug:Q})}return B}reconstructMarkdown(A){if(A.title)return``;return``}async convert(A,Q){let B=this.detectInlineImages(A,Q);if(B.length===0)return{content:A,converted:!1,convertedCount:0};let w=A,$=0,f=0;for(let I of B)try{let D=await this.createImageEntity(I,f++),U=``;w=w.replace(I.originalMarkdown,U),$++,this.logger.debug("Converted inline image",{sourceUrl:I.sourceUrl,imageId:D})}catch(D){this.logger.warn("Failed to convert inline image",{sourceUrl:I.sourceUrl,error:y0(D)})}return{content:w,converted:$>0,convertedCount:$}}async createImageEntity(A,Q){let{sourceUrl:B,alt:w,postSlug:$}=A;return tBA({id:`${$}-inline-${Q}`,title:w||`Inline image ${Q+1} for ${$}`,alt:w||"",sourceUrl:B},this.entityService,this.fetcher,this.logger)}}class ajA{logger;entityService;fileOperations;constructor(A,Q,B){this.logger=A,this.entityService=Q,this.fileOperations=B}async importEntitiesWithProgress(A,Q,B,w){this.logger.debug("Importing entities with progress reporting");let $={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},f=A??await this.fileOperations.getAllSyncFiles(),I=f.length;await Q.report({progress:0,message:`Starting import of ${I} files`});for(let D=0;D<I;D+=B){let U=f.slice(D,D+B),Y=await w(U);$.imported+=Y.imported,$.skipped+=Y.skipped,$.failed+=Y.failed,$.quarantined+=Y.quarantined,$.errors.push(...Y.errors),$.quarantinedFiles.push(...Y.quarantinedFiles),$.jobIds.push(...Y.jobIds);let J=Math.min(D+B,I),X=Math.round(J/I*40);await Q.report({progress:X,message:`Imported ${J}/${I} files`})}return $}async exportEntitiesWithProgress(A,Q,B,w){this.logger.debug("Exporting entities with progress reporting");let $=A??this.entityService.getEntityTypes();await Q.report({progress:50,message:`Starting export of ${$.length} entity types`});let f=await w(A);return await Q.report({progress:100,message:`Exported ${f.exported} entities`}),this.logger.debug("Export completed",f),f}}WA();import{rename as uQQ,appendFile as cQQ,readFile as lQQ,writeFile as pQQ,access as iQQ}from"fs/promises";import{join as eB1}from"path";class tjA{logger;syncPath;constructor(A,Q){this.logger=A;this.syncPath=Q}isValidationError(A){if(A instanceof H.ZodError)return!0;let Q=y0(A);return Q.includes("invalid_type")||Q.includes("invalid_enum_value")||Q.includes("Required")||Q.includes("Invalid frontmatter")||Q.includes("Unknown entity type")}async quarantineInvalidFile(A,Q,B,w){let $=w(A),f=`${$}.invalid`;try{await uQQ($,f),B.quarantined++,B.quarantinedFiles.push(A);let I=eB1(this.syncPath,".import-errors.log"),D=new Date().toISOString(),U=y0(Q),Y=`${D} - ${A}: ${U}
|
|
4639
4639
|
\u2192 ${A}.invalid
|
|
4640
4640
|
|
|
@@ -4662,7 +4662,7 @@ details.web-chat-data-part[open] > summary > .web-chat-data-part-chevron {
|
|
|
4662
4662
|
*...and ${A.files.length-10} more files*`)}if(A.exists&&A.stats.totalFiles===0)Q.push(`
|
|
4663
4663
|
## Getting Started
|
|
4664
4664
|
`),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(`
|
|
4665
|
-
`)}}aA();class CwA extends ZB{directorySync;constructor(A,Q,B){super(A,{schema:t_A,jobTypeName:"directory-export"});this.directorySync=B}async process(A,Q,B){this.logger.debug("Processing directory export job",{jobId:Q,data:A});let w=Date.now();try{let $=await this.directorySync.exportEntitiesWithProgress(A.entityTypes,B,A.batchSize??100);return this.logger.debug("Directory export job completed",{jobId:Q,exported:$.exported,failed:$.failed,duration:Date.now()-w}),$}catch($){throw this.logger.error("Directory export job failed",{jobId:Q,error:$}),$}}summarizeDataForLog(A){return{entityTypes:A.entityTypes??"all",batchSize:A.batchSize}}}aA();class OwA extends ZB{directorySync;constructor(A,Q,B){super(A,{schema:a_A,jobTypeName:"directory-import"});this.directorySync=B}async process(A,Q,B){this.logger.debug("Processing directory import job",{jobId:Q,data:A});let w=Date.now();try{let $=await this.directorySync.importEntitiesWithProgress(A.paths,B,A.batchSize??100);return this.logger.debug("Directory import job completed",{jobId:Q,imported:$.imported,skipped:$.skipped,failed:$.failed,quarantined:$.quarantined,duration:Date.now()-w}),$}catch($){throw this.logger.error("Directory import job failed",{jobId:Q,error:$}),$}}summarizeDataForLog(A){return{pathCount:A.paths?.length??"all",batchSize:A.batchSize}}}aA();class RwA extends ZB{directorySync;context;constructor(A,Q,B){super(A,{schema:o_A,jobTypeName:"directory-sync"});this.context=Q,this.directorySync=B}async process(A,Q,B){let w=Date.now(),$=A.syncDirection??"both";this.logger.info("Starting directory sync job",{jobId:Q,operation:A.operation,syncDirection:$});let f={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},I={exported:0,failed:0,errors:[]};if($!=="export")if(await B.report({progress:10,message:"Scanning directory for changes"}),f=await this.importWithProgress(A.paths,B),$==="import")await this.waitForImportJobs(f.jobIds,B),await B.report({progress:100,message:`Import complete: ${f.imported} imported`});else await B.report({progress:50,message:`Imported ${f.imported} entities`}),await this.waitForImportJobs(f.jobIds,B),await B.report({progress:56,message:"Processing complete, starting export"});if($!=="import"){let U=$==="export"?10:60;await B.report({progress:U,message:"Exporting entities to directory"}),I=await this.exportWithProgress(A.entityTypes,B),await B.report({progress:100,message:$==="export"?`Export complete: ${I.exported} exported`:`Sync complete: ${f.imported} imported, ${I.exported} exported`})}let D=Date.now()-w;return this.logger.info("Directory sync job completed",{jobId:Q,duration:D,imported:f.imported,exported:I.exported}),{import:f,export:I,duration:D}}async importWithProgress(A,Q){try{return await this.directorySync.importEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Import phase failed",{error:B}),B}}async exportWithProgress(A,Q){try{return await this.directorySync.exportEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Export phase failed",{error:B}),B}}async waitForImportJobs(A,Q){if(A.length===0)return;this.logger.debug(`Waiting for ${A.length} import jobs to complete`);let{entityService:B}=this.context,w=300000,$=500,f=Date.now(),I=async()=>{let U=(await Promise.all(A.map((J)=>B.getAsyncJobStatus(J)))).filter((J)=>J&&(J.status==="completed"||J.status==="failed")).length;if(U===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-f>w){this.logger.warn(`Timeout waiting for import jobs (${U}/${A.length} completed)`);return}let Y=Math.round(U/A.length*100);return await Q.report({progress:50+Math.round(Y*0.05),message:`Processing ${U}/${A.length} entities`}),await new Promise((J)=>setTimeout(J,$)),I()};return I()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}aA();class bwA extends ZB{context;directorySync;gitSync;constructor(A,Q,B,w){super(A,{schema:s_A,jobTypeName:"sync-request"});this.context=Q;this.directorySync=B;this.gitSync=w}async process(A,Q,B){await B.report({progress:5,message:"Pulling latest content from git"});let w=await this.gitSync.withLock(async()=>{return await this.gitSync.pull(),await B.report({progress:35,message:"Scanning pulled content for sync changes"}),this.directorySync.queueSyncBatch(this.context,A.source,{rootJobId:Q,interfaceType:A.interfaceType,channelId:A.channelId})});if(!w)return await B.report({progress:100,message:"Sync complete: no files to import"}),{gitPulled:!0,batchQueued:!1};return await B.report({progress:100,message:`Sync queued: ${w.importOperationsCount} import jobs for ${w.totalFiles} files`}),m6Q(w)}summarizeDataForLog(A){return{source:A.source,interfaceType:A.interfaceType,channelId:A.channelId}}}function m6Q(A){return{gitPulled:!0,batchQueued:!0,batchId:A.batchId,importOperations:A.importOperationsCount,totalFiles:A.totalFiles}}aA();class PwA extends ZB{context;constructor(A,Q,B){super(A,{schema:EwA,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,B){let w=EwA.parse(A);this.logger.info("Processing entity deletion for removed file",{entityId:w.entityId,entityType:w.entityType,filePath:w.filePath}),await B.report({progress:0,total:1,message:`Deleting ${w.entityType}:${w.entityId}`});try{let $=await this.context.entityService.deleteEntity({entityType:w.entityType,id:w.entityId});if($)this.logger.info("Successfully deleted entity for removed file",{entityId:w.entityId,entityType:w.entityType});else this.logger.warn("Entity not found in database",{entityId:w.entityId,entityType:w.entityType});return await B.report({progress:1,total:1,message:`Deleted ${w.entityType}:${w.entityId}`}),{deleted:$,entityId:w.entityId,entityType:w.entityType,filePath:w.filePath}}catch($){throw this.logger.error("Failed to delete entity",{entityId:w.entityId,entityType:w.entityType,error:$}),$}}summarizeDataForLog(A){return{entityId:A.entityId,entityType:A.entityType,filePath:A.filePath}}}aA();WA();var u6Q=H.object({});class kwA extends ZB{directorySync;constructor(A,Q){super(A,{schema:u6Q,jobTypeName:"directory-cleanup"});this.directorySync=Q}async process(A,Q,B){await B.report({progress:0,message:"Removing orphaned entities"});let w=await this.directorySync.removeOrphanedEntities();return await B.report({progress:100,message:`Cleanup complete: ${w.deleted} orphans removed`}),w}}aA();C7();WA();o8();C7();import{readFile as c6Q,writeFile as l6Q}from"fs/promises";var p6Q=e_A;class jwA extends ZB{context;fetcher;constructor(A,Q,B=qU){super(Q,{schema:p6Q,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=B}async process(A,Q,B){let{filePath:w,sourceUrl:$,postTitle:f,postSlug:I,customAlt:D}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:w,sourceUrl:$,postSlug:I});try{await this.reportProgress(B,{progress:qQ.INIT,message:`Reading file: ${w}`});let U;try{U=await c6Q(w,"utf-8")}catch(V){return this.logger.error("Failed to read file",{filePath:w,error:y0(V)}),K6.failure(V)}let Y;try{Y=jB(U)}catch(V){return this.logger.warn("Failed to parse markdown",{filePath:w,error:y0(V)}),K6.failure(V)}let J=Y.frontmatter;if(J.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:w}),await this.reportProgress(B,{progress:qQ.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(B,{progress:qQ.FETCH,message:"Checking for existing image"});let X=await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}}),G;if(X[0])G=X[0].id,this.logger.debug("Reusing existing image entity",{sourceUrl:$,imageId:G}),await this.reportProgress(B,{progress:qQ.EXTRACT,message:`Reusing existing image: ${G}`});else{await this.reportProgress(B,{progress:qQ.PROCESS,message:`Fetching image from ${$}`});let V;try{V=await this.fetcher($)}catch(T){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:y0(T)}),K6.failure(T)}await this.reportProgress(B,{progress:qQ.GENERATE,message:"Creating image entity"});let{base64:L}=TN(V),M=ZV(L),O=xN(L);if(!M||!O)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),K6.failure(Error("Could not detect image format or dimensions"));G=`${I}-cover`;let E=`Cover image for ${f}`,S=D??E;await this.context.entityService.createEntity({entity:{id:G,entityType:"image",content:V,metadata:{title:E,alt:S,format:M,width:O.width,height:O.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:G,sourceUrl:$}),await this.reportProgress(B,{progress:qQ.EXTRACT,message:`Created image: ${G}`})}await this.reportProgress(B,{progress:qQ.SAVE,message:"Updating file"});let Z={...J};delete Z.coverImageUrl,delete Z.coverImageAlt,Z.coverImageId=G;let N=TG(Z,Y.content);try{await l6Q(w,N,"utf-8")}catch(V){return this.logger.error("Failed to write file",{filePath:w,error:y0(V)}),K6.failure(V)}return await this.reportProgress(B,{progress:qQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:w,imageId:G,sourceUrl:$}),{success:!0,imageId:G}}catch(U){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:w,error:y0(U)}),K6.failure(U)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}aA();C7();WA();o8();import{readFile as i6Q,writeFile as r6Q}from"fs/promises";class _wA extends ZB{converter;constructor(A,Q,B=qU){super(Q,{schema:AvA,jobTypeName:"inline-image-convert"});this.converter=new zl(A.entityService,Q,B)}async process(A,Q,B){let{filePath:w,postSlug:$}=A;this.logger.debug("Starting inline image conversion job",{jobId:Q,filePath:w,postSlug:$});try{await this.reportProgress(B,{progress:qQ.INIT,message:`Reading file: ${w}`});let f;try{f=await i6Q(w,"utf-8")}catch(U){let Y=y0(U);return this.logger.error("Failed to read file",{filePath:w,error:Y}),{success:!1,error:Y}}await this.reportProgress(B,{progress:qQ.FETCH,message:"Detecting inline images"});let I=this.converter.detectInlineImages(f,$);if(I.length===0)return this.logger.debug("No inline images to convert",{filePath:w}),await this.reportProgress(B,{progress:qQ.COMPLETE,message:"No images to convert"}),{success:!0,skipped:!0,convertedCount:0};this.logger.debug("Found inline images to convert",{filePath:w,count:I.length}),await this.reportProgress(B,{progress:qQ.PROCESS,message:`Converting ${I.length} images`});let D=await this.converter.convert(f,$);if(!D.converted)return this.logger.debug("No images were converted",{filePath:w}),await this.reportProgress(B,{progress:qQ.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(B,{progress:qQ.SAVE,message:"Writing updated file"});try{await r6Q(w,D.content,"utf-8")}catch(U){let Y=y0(U);return this.logger.error("Failed to write file",{filePath:w,error:Y}),{success:!1,error:Y}}return await this.reportProgress(B,{progress:qQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:w,convertedCount:D.convertedCount}),{success:!0,convertedCount:D.convertedCount}}catch(f){let I=y0(f);return this.logger.error("Inline image conversion job failed",{jobId:Q,filePath:w,error:I}),{success:!1,error:I}}}summarizeDataForLog(A){return{filePath:A.filePath,postSlug:A.postSlug}}}function j51(A,Q,B){let w=($)=>B.child($);A.jobs.registerHandler("directory-sync",new RwA(w("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new CwA(w("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new OwA(w("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new PwA(w("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new kwA(w("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new jwA(A,w("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new _wA(A,w("InlineImageConversionJobHandler"))),B.debug("Registered async job handlers")}aA();import{unlink as d6Q,access as n6Q}from"fs/promises";function _51(A,Q,B,w){let{subscribe:$}=A.messaging,{entityService:f}=A;$("entity:created",async(I)=>{let{entity:D}=I.payload;try{await Q.fileOps.writeEntity(D),B.debug("Auto-exported created entity",{id:D.id,entityType:D.entityType})}catch(U){B.error("Auto-export FAILED for created entity",{id:D.id,entityType:D.entityType,error:U instanceof Error?U.message:String(U),stack:U instanceof Error?U.stack:void 0})}return{success:!0}}),$("entity:updated",async(I)=>{let{entityType:D,entityId:U}=I.payload;try{let Y=await f.getEntity({entityType:D,id:U});if(!Y)return B.debug("Entity not found in DB, skipping export",{entityType:D,entityId:U}),{success:!1};await Q.fileOps.writeEntity(Y),B.debug("Auto-exported updated entity",{id:Y.id,entityType:Y.entityType})}catch(Y){B.error("Auto-export FAILED for updated entity",{entityType:D,entityId:U,error:Y instanceof Error?Y.message:String(Y),stack:Y instanceof Error?Y.stack:void 0})}return{success:!0}}),$("entity:deleted",async(I)=>{let{entityId:D,entityType:U}=I.payload,Y=Q.fileOps.getFilePath(D,U);if(await n6Q(Y).then(()=>!0,()=>!1))await d6Q(Y),B.debug("Auto-deleted entity file",{id:D,entityType:U,path:Y});return{success:!0}}),B.debug("Setup auto-sync for entity events",{entityTypes:w})}function v51(A,Q,B){Q.setJobQueueCallback(async(w)=>{let $=[{type:w.type,data:w.data}];return A.jobs.enqueueBatch($,{priority:5,source:"directory-sync-watcher",rootJobId:X$(),metadata:{operationType:"file_operations",operationTarget:B,pluginId:"directory-sync"}})})}WA();aA();import{readdir as x51,mkdir as s6Q,copyFile as a6Q}from"fs/promises";import{join as T51,resolve as QvA}from"path";import{join as o6Q}from"path";async function y51(A){if(!await W5(o6Q(A,".git")))return!1;try{return await nJ(A).revparse(["--verify","HEAD"]),!0}catch{return!1}}async function t6Q(A,Q){if(!await W5(A))return!0;if((await x51(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await y51(A))return Q.debug("Git repository with history detected - skipping seed content",{path:A}),!1;return!0}async function S51(A,Q){let B=await x51(A,{withFileTypes:!0});for(let w of B){let $=T51(A,w.name),f=T51(Q,w.name);if(w.isDirectory()){if(!await W5(f))await s6Q(f,{recursive:!0});await S51($,f)}else await a6Q($,f)}}async function g51(A,Q,B){let w=QvA(process.cwd(),A);B=B?QvA(B):QvA(process.cwd(),"seed-content");let $=await t6Q(w,Q);if($&&await W5(B))Q.debug("Copying seed content to brain-data directory"),await S51(B,w),Q.debug("Seed content copied successfully");else if($)Q.debug("No seed content directory found, starting with empty brain-data");else Q.debug("brain-data directory not empty, skipping seed content")}function h51(A,Q,B,w,$){let f=!1,I=async()=>{if(f)return;f=!0;let D=Q();if(B.seedContent){let U=B.syncPath??A.dataDir;await g51(U,w,B.seedContentPath)}try{if($){w.debug("Git enabled \u2014 pulling before import");let Y=await $.pull();if(Y.files.length>0)w.info("Pulled changes from remote",{filesChanged:Y.files.length})}w.debug("Starting initial sync");let U=await D.sync();w.debug("Initial sync completed",{imported:U.import.imported,failed:U.import.failed,duration:U.duration}),await A.messaging.send({type:mL.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(U){w.error("Initial sync failed",U),await A.messaging.send({type:mL.initialSyncCompleted,payload:{success:!1,error:y0(U)},...{broadcast:!0}})}};A.messaging.subscribe(mL.pluginsRegistered,async()=>{return w.debug("Plugins registered, starting initial sync"),await I(),{success:!0}})}WA();function m51(A,Q,B,w){let $=new VL(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(D){w.error("Git auto-commit failed",{error:D})}})},B),f=["entity:created","entity:updated","entity:deleted"],I=[];for(let D of f){let U=A.subscribe(D,async()=>{return $.trigger(),{success:!0}});I.push(U)}return()=>{$.dispose();for(let D of I)D()}}function u51(A,Q,B,w,$){if(w<=0)return()=>{};let f=w*60*1000,I=!1,D=async()=>{if(I)return;I=!0;try{let{files:Y,result:J}=await A.withLock(async()=>{let X=await A.pull();if(X.files.length===0)return{files:[],result:null};let G=await Q.queueSyncBatch(B,"periodic-sync");return{files:X.files,result:G}});if(Y.length>0)$.info("Periodic sync: pulled changes",{filesChanged:Y.length});if(J)$.debug("Periodic sync: queued imports",{importOperations:J.importOperationsCount,totalFiles:J.totalFiles})}catch(Y){$.error("Periodic git sync failed",{error:Y})}finally{I=!1}},U=setInterval(()=>{D()},f);return $.info("Started periodic git sync",{intervalMinutes:w}),()=>{clearInterval(U)}}import{spawnSync as l51}from"child_process";import{cpSync as e6Q,existsSync as c51,mkdirSync as A5Q,mkdtempSync as Q5Q,rmSync as B5Q}from"fs";import{tmpdir as w5Q}from"os";import{fileURLToPath as $5Q}from"url";import{join as f5Q,resolve as I5Q}from"path";function Fz(A,Q){let B=l51("git",Q,{cwd:A,stdio:"pipe"});if(B.status!==0){let w=B.stderr.toString().trim(),$=B.stdout.toString().trim();throw Error(w||$||`git ${Q.join(" ")} failed`)}}function D5Q(A){return A.startsWith("file://")}function U5Q(A){return $5Q(A)}function Y5Q(A,Q){return l51("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function p51(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!D5Q(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",B=U5Q(A.gitUrl),w=I5Q(A.seedContentPath);if(!c51(w))throw Error(`Seed content path not found: ${w}`);if(!c51(B))A.logger.debug("Creating local bare content remote",{remotePath:B,branch:Q}),A5Q(B,{recursive:!0}),Fz(process.cwd(),["init","--bare",`--initial-branch=${Q}`,B]);if(Y5Q(B,Q)){A.logger.debug("Content remote already initialized",{remotePath:B,branch:Q});return}A.logger.debug("Seeding local content remote",{remotePath:B,seedPath:w,branch:Q});let $=Q5Q(f5Q(w5Q(),"directory-sync-seed-"));try{Fz($,["init",`--initial-branch=${Q}`]),Fz($,["config","user.name",A.authorName??"Brain"]),Fz($,["config","user.email",A.authorEmail??"brain@localhost"]),e6Q(w,$,{recursive:!0}),Fz($,["add","."]),Fz($,["commit","-m","seed content remote"]),Fz($,["remote","add","origin",A.gitUrl]),Fz($,["push","-u","origin",Q])}finally{B5Q($,{recursive:!0,force:!0})}}function i51(A,Q,B,w,$){let{subscribe:f}=A.messaging;f("entity:export:request",async(I)=>{try{return{success:!0,data:await Q().exportEntities(I.payload.entityTypes)}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Export failed"}}}),f("entity:import:request",async(I)=>{try{let D=Q(),U=I.payload.paths,Y=await D.importEntities(U);if(U&&U.length>0)await D.removeOrphanedEntities();return{success:!0,data:Y}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Import failed"}}}),f("sync:status:request",async()=>{try{let D=await Q().getStatus();return{success:!0,data:{syncPath:D.syncPath,isInitialized:D.exists,watchEnabled:D.watching}}}catch(I){return{success:!1,error:I instanceof Error?I.message:"Status check failed"}}}),f("sync:configure:request",async(I)=>{try{return await B({syncPath:I.payload.syncPath}),{success:!0,data:{syncPath:I.payload.syncPath,configured:!0}}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Configuration failed"}}}),f("git-sync:get-repo-info",async()=>{if(!$?.repo)return{success:!1,error:"Git not configured"};return{success:!0,data:{repo:$.repo,branch:$.branch??"main"}}}),w.debug("Registered message handlers")}aA();WA();aA();WA();function r51(A,Q){return oQ(A,"history","Get version history for an entity from git. Without sha: returns commit list. With sha: returns entity content at that version.",H.object({entityType:H.string().describe("Entity type (e.g. post, note, link)"),id:H.string().describe("Entity ID"),sha:H.string().optional().describe("Commit SHA to retrieve content at. Omit to list commit history."),limit:H.number().int().positive().optional().default(10).describe("Max commits to return (list mode only)")}),async(B)=>{let w=`${B.entityType}/${B.id}.md`;try{if(B.sha){let f=await Q.show(B.sha,w);return Y8({sha:B.sha,entityType:B.entityType,id:B.id,content:f},`Content at ${B.sha.slice(0,7)}`)}let $=await Q.log(w,B.limit);if($.length===0)return Y8({commits:[]},`No history found for ${B.entityType}/${B.id}`);return Y8({commits:$,entityType:B.entityType,id:B.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return H$($ instanceof Error?$.message:"History lookup failed")}})}function d51(A,Q,B,w){let $=[oQ(B,"sync","Sync brain entities with the filesystem. Use this for refresh, pull, sync, or backup-to-git requests. Pulls from git if configured, then imports files. Git commit and push happen automatically after imports complete.",H.object({}),async(f,I)=>{try{let D=I.channelId?`${I.interfaceType}:${I.channelId}`:`plugin:${B}`,U={interfaceType:I.interfaceType,channelId:I.channelId};if(w){let J=await Q.jobs.enqueue({type:"sync-request",data:{source:D,interfaceType:U.interfaceType,channelId:U.channelId},toolContext:I});return Y8({jobId:J,status:"queued",gitPulled:!0},"Sync queued: pulling from git and scanning files")}let Y=await A.queueSyncBatch(Q,D,U);if(!Y)return Y8({gitPulled:!1},"No files to sync");return Y8({batchId:Y.batchId,importOperations:Y.importOperationsCount,totalFiles:Y.totalFiles,gitPulled:!1},`Sync started: ${Y.importOperationsCount} import jobs queued for ${Y.totalFiles} files`)}catch(D){return H$(D instanceof Error?D.message:"Sync failed")}},{cli:{name:"sync"}}),oQ(B,"status","Get sync and git repository status \u2014 last sync time, watching state, pending git changes. Use this for status questions, not for actually syncing or backing up.",H.object({}),async()=>{try{let f=await A.getStatus(),I={syncPath:f.syncPath,lastSync:f.lastSync?.toISOString(),watching:f.watching};if(w){let D=await w.getStatus();I.git={isRepo:D.isRepo,branch:D.branch,hasChanges:D.hasChanges,ahead:D.ahead,behind:D.behind,remote:D.remote}}return Y8(I)}catch(f){return H$(f instanceof Error?f.message:"Status check failed")}},{visibility:"public"})];if(w)$.push(r51(B,w));return $}var n51={name:"@brains/directory-sync",private:!0,version:"0.2.0-alpha.125",description:"Directory-based entity synchronization plugin for Brains",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":{types:"./src/index.ts",import:"./src/index.ts"}},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",clean:"rm -rf .turbo"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",chokidar:"^3.5.3","simple-git":"^3.21.0"},devDependencies:{"@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},peerDependencies:{}};class BvA extends YB{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",n51,A,_l)}requireDirectorySync(){if(!this.directorySync)throw Error("DirectorySync service not initialized");return this.directorySync}hasGitSync(){return this.gitSync!==void 0}async onRegister(A){let{logger:Q,entityService:B}=A;A.templates.register({status:{name:"status",description:"Directory synchronization status",schema:vl,basePrompt:"",formatter:new MwA,requiredPermission:"anchor"}});let w=this.config.syncPath??A.dataDir;this.directorySync=new ql({syncPath:w,autoSync:this.config.autoSync,watchInterval:this.config.watchInterval,includeMetadata:this.config.includeMetadata,entityTypes:this.config.entityTypes,deleteOnFileRemoval:this.config.deleteOnFileRemoval,entityService:B,logger:Q});try{await this.directorySync.initializeDirectory(),this.logger.debug("Directory structure initialized",{path:w})}catch(I){throw this.logger.error("Failed to initialize directory",I),I}await this.registerJobHandlers(A);let $=this.requireDirectorySync();if(_51(A,$,this.logger,this.config.entityTypes),this.config.autoSync)v51(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 p51({gitUrl:this.config.git.gitUrl,branch:this.config.git.branch,seedContentPath:this.config.seedContentPath,bootstrapFromSeed:this.config.git.bootstrapFromSeed,authorName:this.config.git.authorName,authorEmail:this.config.git.authorEmail,logger:this.logger.child("ContentRemoteBootstrap")});let I=this.config.syncPath??A.dataDir;if(this.gitSync=new n_A({logger:this.logger.child("GitSync"),dataDir:I,repo:this.config.git.repo,gitUrl:this.config.git.gitUrl,branch:this.config.git.branch,authToken:this.config.git.authToken,authorName:this.config.git.authorName,authorEmail:this.config.git.authorEmail}),await this.gitSync.initialize(),this.logger.info("Git integration enabled",{repo:this.config.git.repo}),A.jobs.registerHandler("sync-request",new bwA(this.logger.child("DirectorySyncRequestJobHandler"),A,this.requireDirectorySync(),this.gitSync)),this.gitCleanups.push(m51(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(u51(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)h51(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);i51(A,()=>this.requireDirectorySync(),(I)=>this.configure(I),this.logger,this.config.git)}async getTools(){let A=this.requireDirectorySync();return d51(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 ql({...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){j51(A,this.requireDirectorySync(),this.logger)}}function LM(A={}){return new BvA(A)}aA();WA();var o51={name:"@brains/email-resend",private:!0,version:"0.2.0-alpha.125",description:"Generic email delivery adapter for Resend",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/email-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var W5Q=H.object({apiKey:H.string().min(1).optional(),from:H.string().min(1).optional()});class s51 extends YB{fetchImpl;constructor(A={},Q={}){super("email-resend",o51,A,W5Q);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(e0A,async(B)=>{let w=fE0.parse(B.payload);try{return{success:!0,data:await this.sendWithResend(w)}}catch($){if(w.sensitivity==="secret")Q.warn("Email delivery failed for a secret message");else Q.warn("Email delivery failed",{to:w.to,subject:w.subject,error:$ instanceof Error?$.message:String($)});return{success:!1,error:"Email delivery failed"}}})}async sendWithResend(A){let Q=this.config.apiKey,B=this.config.from;if(!Q||!B)return{status:"failed"};let w=await this.fetchImpl("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${Q}`,"Content-Type":"application/json"},body:JSON.stringify({from:B,to:A.to,subject:A.subject,text:A.text,...A.html?{html:A.html}:{}})});if(!w.ok)throw Error("Resend email request failed");let $=await w.json();return $.id?{status:"sent",id:$.id}:{status:"sent"}}}function vwA(A={}){return new s51(A)}aA();import{render as YK1}from"preact-render-to-string";import{h as $C}from"preact";function a51(A){var Q,B,w="";if(typeof A=="string"||typeof A=="number")w+=A;else if(typeof A=="object")if(Array.isArray(A)){var $=A.length;for(Q=0;Q<$;Q++)A[Q]&&(B=a51(A[Q]))&&(w&&(w+=" "),w+=B)}else for(B in A)A[B]&&(w&&(w+=" "),w+=B);return w}function L_(){for(var A,Q,B=0,w="",$=arguments.length;B<$;B++)(A=arguments[B])&&(Q=a51(A))&&(w&&(w+=" "),w+=Q);return w}var H5Q=(A)=>{let Q=K5Q(A),{conflictingClassGroups:B,conflictingClassGroupModifiers:w}=A;return{getClassGroupId:(I)=>{let D=I.split("-");if(D[0]===""&&D.length!==1)D.shift();return B$1(D,Q)||G5Q(I)},getConflictingClassGroupIds:(I,D)=>{let U=B[I]||[];if(D&&w[I])return[...U,...w[I]];return U}}},B$1=(A,Q)=>{if(A.length===0)return Q.classGroupId;let B=A[0],w=Q.nextPart.get(B),$=w?B$1(A.slice(1),w):void 0;if($)return $;if(Q.validators.length===0)return;let f=A.join("-");return Q.validators.find(({validator:I})=>I(f))?.classGroupId},t51=/^\[(.+)\]$/,G5Q=(A)=>{if(t51.test(A)){let Q=t51.exec(A)[1],B=Q?.substring(0,Q.indexOf(":"));if(B)return"arbitrary.."+B}},K5Q=(A)=>{let{theme:Q,prefix:B}=A,w={nextPart:new Map,validators:[]};return Z5Q(Object.entries(A.classGroups),B).forEach(([f,I])=>{$vA(I,w,f,Q)}),w},$vA=(A,Q,B,w)=>{A.forEach(($)=>{if(typeof $==="string"){let f=$===""?Q:e51(Q,$);f.classGroupId=B;return}if(typeof $==="function"){if(F5Q($)){$vA($(w),Q,B,w);return}Q.validators.push({validator:$,classGroupId:B});return}Object.entries($).forEach(([f,I])=>{$vA(I,e51(Q,f),B,w)})})},e51=(A,Q)=>{let B=A;return Q.split("-").forEach((w)=>{if(!B.nextPart.has(w))B.nextPart.set(w,{nextPart:new Map,validators:[]});B=B.nextPart.get(w)}),B},F5Q=(A)=>A.isThemeGetter,Z5Q=(A,Q)=>{if(!Q)return A;return A.map(([B,w])=>{let $=w.map((f)=>{if(typeof f==="string")return Q+f;if(typeof f==="object")return Object.fromEntries(Object.entries(f).map(([I,D])=>[Q+I,D]));return f});return[B,$]})},N5Q=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,B=new Map,w=new Map,$=(f,I)=>{if(B.set(f,I),Q++,Q>A)Q=0,w=B,B=new Map};return{get(f){let I=B.get(f);if(I!==void 0)return I;if((I=w.get(f))!==void 0)return $(f,I),I},set(f,I){if(B.has(f))B.set(f,I);else $(f,I)}}};var z5Q=(A)=>{let{separator:Q,experimentalParseClassName:B}=A,w=Q.length===1,$=Q[0],f=Q.length,I=(D)=>{let U=[],Y=0,J=0,X;for(let L=0;L<D.length;L++){let M=D[L];if(Y===0){if(M===$&&(w||D.slice(L,L+f)===Q)){U.push(D.slice(J,L)),J=L+f;continue}if(M==="/"){X=L;continue}}if(M==="[")Y++;else if(M==="]")Y--}let G=U.length===0?D:D.substring(J),Z=G.startsWith("!"),N=Z?G.substring(1):G,V=X&&X>J?X-J:void 0;return{modifiers:U,hasImportantModifier:Z,baseClassName:N,maybePostfixModifierPosition:V}};if(B)return(D)=>B({className:D,parseClassName:I});return I},q5Q=(A)=>{if(A.length<=1)return A;let Q=[],B=[];return A.forEach((w)=>{if(w[0]==="[")Q.push(...B.sort(),w),B=[];else B.push(w)}),Q.push(...B.sort()),Q},L5Q=(A)=>({cache:N5Q(A.cacheSize),parseClassName:z5Q(A),...H5Q(A)}),V5Q=/\s+/,E5Q=(A,Q)=>{let{parseClassName:B,getClassGroupId:w,getConflictingClassGroupIds:$}=Q,f=[],I=A.trim().split(V5Q),D="";for(let U=I.length-1;U>=0;U-=1){let Y=I[U],{modifiers:J,hasImportantModifier:X,baseClassName:G,maybePostfixModifierPosition:Z}=B(Y),N=Boolean(Z),V=w(N?G.substring(0,Z):G);if(!V){if(!N){D=Y+(D.length>0?" "+D:D);continue}if(V=w(G),!V){D=Y+(D.length>0?" "+D:D);continue}N=!1}let L=q5Q(J).join(":"),M=X?L+"!":L,O=M+V;if(f.includes(O))continue;f.push(O);let E=$(V,N);for(let S=0;S<E.length;++S){let T=E[S];f.push(M+T)}D=Y+(D.length>0?" "+D:D)}return D};function M5Q(){let A=0,Q,B,w="";while(A<arguments.length)if(Q=arguments[A++]){if(B=w$1(Q))w&&(w+=" "),w+=B}return w}var w$1=(A)=>{if(typeof A==="string")return A;let Q,B="";for(let w=0;w<A.length;w++)if(A[w]){if(Q=w$1(A[w]))B&&(B+=" "),B+=Q}return B};function A$1(A,...Q){let B,w,$,f=I;function I(U){let Y=Q.reduce((J,X)=>X(J),A());return B=L5Q(Y),w=B.cache.get,$=B.cache.set,f=D,D(U)}function D(U){let Y=w(U);if(Y)return Y;let J=E5Q(U,B);return $(U,J),J}return function(){return f(M5Q.apply(null,arguments))}}var T8=(A)=>{let Q=(B)=>B[A]||[];return Q.isThemeGetter=!0,Q},$$1=/^\[(?:([a-z-]+):)?(.+)\]$/i,C5Q=/^\d+\/\d+$/,O5Q=new Set(["px","full","screen"]),R5Q=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,b5Q=/\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$/,P5Q=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,k5Q=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,j5Q=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,KF=(A)=>V_(A)||O5Q.has(A)||C5Q.test(A),Zz=(A)=>E_(A,"length",h5Q),V_=(A)=>Boolean(A)&&!Number.isNaN(Number(A)),wvA=(A)=>E_(A,"number",V_),yl=(A)=>Boolean(A)&&Number.isInteger(Number(A)),_5Q=(A)=>A.endsWith("%")&&V_(A.slice(0,-1)),rQ=(A)=>$$1.test(A),Nz=(A)=>R5Q.test(A),v5Q=new Set(["length","size","percentage"]),y5Q=(A)=>E_(A,v5Q,f$1),T5Q=(A)=>E_(A,"position",f$1),x5Q=new Set(["image","url"]),S5Q=(A)=>E_(A,x5Q,u5Q),g5Q=(A)=>E_(A,"",m5Q),Tl=()=>!0,E_=(A,Q,B)=>{let w=$$1.exec(A);if(w){if(w[1])return typeof Q==="string"?w[1]===Q:Q.has(w[1]);return B(w[2])}return!1},h5Q=(A)=>b5Q.test(A)&&!P5Q.test(A),f$1=()=>!1,m5Q=(A)=>k5Q.test(A),u5Q=(A)=>j5Q.test(A);var Q$1=()=>{let A=T8("colors"),Q=T8("spacing"),B=T8("blur"),w=T8("brightness"),$=T8("borderColor"),f=T8("borderRadius"),I=T8("borderSpacing"),D=T8("borderWidth"),U=T8("contrast"),Y=T8("grayscale"),J=T8("hueRotate"),X=T8("invert"),G=T8("gap"),Z=T8("gradientColorStops"),N=T8("gradientColorStopPositions"),V=T8("inset"),L=T8("margin"),M=T8("opacity"),O=T8("padding"),E=T8("saturate"),S=T8("scale"),T=T8("sepia"),y=T8("skew"),_=T8("space"),x=T8("translate"),g=()=>["auto","contain","none"],n=()=>["auto","hidden","clip","visible","scroll"],m=()=>["auto",rQ,Q],BA=()=>[rQ,Q],a=()=>["",KF,Zz],j=()=>["auto",V_,rQ],R=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],P=()=>["solid","dashed","dotted","double","none"],c=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],l=()=>["start","end","center","between","around","evenly","stretch"],e=()=>["","0",rQ],s=()=>["auto","avoid","all","avoid-page","page","left","right","column"],XA=()=>[V_,rQ];return{cacheSize:500,separator:":",theme:{colors:[Tl],spacing:[KF,Zz],blur:["none","",Nz,rQ],brightness:XA(),borderColor:[A],borderRadius:["none","","full",Nz,rQ],borderSpacing:BA(),borderWidth:a(),contrast:XA(),grayscale:e(),hueRotate:XA(),invert:e(),gap:BA(),gradientColorStops:[A],gradientColorStopPositions:[_5Q,Zz],inset:m(),margin:m(),opacity:XA(),padding:BA(),saturate:XA(),scale:XA(),sepia:e(),skew:XA(),space:BA(),translate:BA()},classGroups:{aspect:[{aspect:["auto","square","video",rQ]}],container:["container"],columns:[{columns:[Nz]}],"break-after":[{"break-after":s()}],"break-before":[{"break-before":s()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:[...R(),rQ]}],overflow:[{overflow:n()}],"overflow-x":[{"overflow-x":n()}],"overflow-y":[{"overflow-y":n()}],overscroll:[{overscroll:g()}],"overscroll-x":[{"overscroll-x":g()}],"overscroll-y":[{"overscroll-y":g()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:[V]}],"inset-x":[{"inset-x":[V]}],"inset-y":[{"inset-y":[V]}],start:[{start:[V]}],end:[{end:[V]}],top:[{top:[V]}],right:[{right:[V]}],bottom:[{bottom:[V]}],left:[{left:[V]}],visibility:["visible","invisible","collapse"],z:[{z:["auto",yl,rQ]}],basis:[{basis:m()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",rQ]}],grow:[{grow:e()}],shrink:[{shrink:e()}],order:[{order:["first","last","none",yl,rQ]}],"grid-cols":[{"grid-cols":[Tl]}],"col-start-end":[{col:["auto",{span:["full",yl,rQ]},rQ]}],"col-start":[{"col-start":j()}],"col-end":[{"col-end":j()}],"grid-rows":[{"grid-rows":[Tl]}],"row-start-end":[{row:["auto",{span:[yl,rQ]},rQ]}],"row-start":[{"row-start":j()}],"row-end":[{"row-end":j()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",rQ]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",rQ]}],gap:[{gap:[G]}],"gap-x":[{"gap-x":[G]}],"gap-y":[{"gap-y":[G]}],"justify-content":[{justify:["normal",...l()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...l(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...l(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[O]}],px:[{px:[O]}],py:[{py:[O]}],ps:[{ps:[O]}],pe:[{pe:[O]}],pt:[{pt:[O]}],pr:[{pr:[O]}],pb:[{pb:[O]}],pl:[{pl:[O]}],m:[{m:[L]}],mx:[{mx:[L]}],my:[{my:[L]}],ms:[{ms:[L]}],me:[{me:[L]}],mt:[{mt:[L]}],mr:[{mr:[L]}],mb:[{mb:[L]}],ml:[{ml:[L]}],"space-x":[{"space-x":[_]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[_]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",rQ,Q]}],"min-w":[{"min-w":[rQ,Q,"min","max","fit"]}],"max-w":[{"max-w":[rQ,Q,"none","full","min","max","fit","prose",{screen:[Nz]},Nz]}],h:[{h:[rQ,Q,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[rQ,Q,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[rQ,Q,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[rQ,Q,"auto","min","max","fit"]}],"font-size":[{text:["base",Nz,Zz]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",wvA]}],"font-family":[{font:[Tl]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:["tighter","tight","normal","wide","wider","widest",rQ]}],"line-clamp":[{"line-clamp":["none",V_,wvA]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",KF,rQ]}],"list-image":[{"list-image":["none",rQ]}],"list-style-type":[{list:["none","disc","decimal",rQ]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[A]}],"placeholder-opacity":[{"placeholder-opacity":[M]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[A]}],"text-opacity":[{"text-opacity":[M]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...P(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",KF,Zz]}],"underline-offset":[{"underline-offset":["auto",KF,rQ]}],"text-decoration-color":[{decoration:[A]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:BA()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",rQ]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",rQ]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[M]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...R(),T5Q]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",y5Q]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},S5Q]}],"bg-color":[{bg:[A]}],"gradient-from-pos":[{from:[N]}],"gradient-via-pos":[{via:[N]}],"gradient-to-pos":[{to:[N]}],"gradient-from":[{from:[Z]}],"gradient-via":[{via:[Z]}],"gradient-to":[{to:[Z]}],rounded:[{rounded:[f]}],"rounded-s":[{"rounded-s":[f]}],"rounded-e":[{"rounded-e":[f]}],"rounded-t":[{"rounded-t":[f]}],"rounded-r":[{"rounded-r":[f]}],"rounded-b":[{"rounded-b":[f]}],"rounded-l":[{"rounded-l":[f]}],"rounded-ss":[{"rounded-ss":[f]}],"rounded-se":[{"rounded-se":[f]}],"rounded-ee":[{"rounded-ee":[f]}],"rounded-es":[{"rounded-es":[f]}],"rounded-tl":[{"rounded-tl":[f]}],"rounded-tr":[{"rounded-tr":[f]}],"rounded-br":[{"rounded-br":[f]}],"rounded-bl":[{"rounded-bl":[f]}],"border-w":[{border:[D]}],"border-w-x":[{"border-x":[D]}],"border-w-y":[{"border-y":[D]}],"border-w-s":[{"border-s":[D]}],"border-w-e":[{"border-e":[D]}],"border-w-t":[{"border-t":[D]}],"border-w-r":[{"border-r":[D]}],"border-w-b":[{"border-b":[D]}],"border-w-l":[{"border-l":[D]}],"border-opacity":[{"border-opacity":[M]}],"border-style":[{border:[...P(),"hidden"]}],"divide-x":[{"divide-x":[D]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[D]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[M]}],"divide-style":[{divide:P()}],"border-color":[{border:[$]}],"border-color-x":[{"border-x":[$]}],"border-color-y":[{"border-y":[$]}],"border-color-s":[{"border-s":[$]}],"border-color-e":[{"border-e":[$]}],"border-color-t":[{"border-t":[$]}],"border-color-r":[{"border-r":[$]}],"border-color-b":[{"border-b":[$]}],"border-color-l":[{"border-l":[$]}],"divide-color":[{divide:[$]}],"outline-style":[{outline:["",...P()]}],"outline-offset":[{"outline-offset":[KF,rQ]}],"outline-w":[{outline:[KF,Zz]}],"outline-color":[{outline:[A]}],"ring-w":[{ring:a()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[A]}],"ring-opacity":[{"ring-opacity":[M]}],"ring-offset-w":[{"ring-offset":[KF,Zz]}],"ring-offset-color":[{"ring-offset":[A]}],shadow:[{shadow:["","inner","none",Nz,g5Q]}],"shadow-color":[{shadow:[Tl]}],opacity:[{opacity:[M]}],"mix-blend":[{"mix-blend":[...c(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":c()}],filter:[{filter:["","none"]}],blur:[{blur:[B]}],brightness:[{brightness:[w]}],contrast:[{contrast:[U]}],"drop-shadow":[{"drop-shadow":["","none",Nz,rQ]}],grayscale:[{grayscale:[Y]}],"hue-rotate":[{"hue-rotate":[J]}],invert:[{invert:[X]}],saturate:[{saturate:[E]}],sepia:[{sepia:[T]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[B]}],"backdrop-brightness":[{"backdrop-brightness":[w]}],"backdrop-contrast":[{"backdrop-contrast":[U]}],"backdrop-grayscale":[{"backdrop-grayscale":[Y]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[J]}],"backdrop-invert":[{"backdrop-invert":[X]}],"backdrop-opacity":[{"backdrop-opacity":[M]}],"backdrop-saturate":[{"backdrop-saturate":[E]}],"backdrop-sepia":[{"backdrop-sepia":[T]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":[I]}],"border-spacing-x":[{"border-spacing-x":[I]}],"border-spacing-y":[{"border-spacing-y":[I]}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["none","all","","colors","opacity","shadow","transform",rQ]}],duration:[{duration:XA()}],ease:[{ease:["linear","in","out","in-out",rQ]}],delay:[{delay:XA()}],animate:[{animate:["none","spin","ping","pulse","bounce",rQ]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[S]}],"scale-x":[{"scale-x":[S]}],"scale-y":[{"scale-y":[S]}],rotate:[{rotate:[yl,rQ]}],"translate-x":[{"translate-x":[x]}],"translate-y":[{"translate-y":[x]}],"skew-x":[{"skew-x":[y]}],"skew-y":[{"skew-y":[y]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",rQ]}],accent:[{accent:["auto",A]}],appearance:[{appearance:["none","auto"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",rQ]}],"caret-color":[{caret:[A]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":BA()}],"scroll-mx":[{"scroll-mx":BA()}],"scroll-my":[{"scroll-my":BA()}],"scroll-ms":[{"scroll-ms":BA()}],"scroll-me":[{"scroll-me":BA()}],"scroll-mt":[{"scroll-mt":BA()}],"scroll-mr":[{"scroll-mr":BA()}],"scroll-mb":[{"scroll-mb":BA()}],"scroll-ml":[{"scroll-ml":BA()}],"scroll-p":[{"scroll-p":BA()}],"scroll-px":[{"scroll-px":BA()}],"scroll-py":[{"scroll-py":BA()}],"scroll-ps":[{"scroll-ps":BA()}],"scroll-pe":[{"scroll-pe":BA()}],"scroll-pt":[{"scroll-pt":BA()}],"scroll-pr":[{"scroll-pr":BA()}],"scroll-pb":[{"scroll-pb":BA()}],"scroll-pl":[{"scroll-pl":BA()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",rQ]}],fill:[{fill:[A,"none"]}],"stroke-w":[{stroke:[KF,Zz,wvA]}],stroke:[{stroke:[A,"none"]}],sr:["sr-only","not-sr-only"],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-s","border-w-e","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-s","border-color-e","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]}}},c5Q=(A,{cacheSize:Q,prefix:B,separator:w,experimentalParseClassName:$,extend:f={},override:I={}})=>{xl(A,"cacheSize",Q),xl(A,"prefix",B),xl(A,"separator",w),xl(A,"experimentalParseClassName",$);for(let D in I)l5Q(A[D],I[D]);for(let D in f)p5Q(A[D],f[D]);return A},xl=(A,Q,B)=>{if(B!==void 0)A[Q]=B},l5Q=(A,Q)=>{if(Q)for(let B in Q)xl(A,B,Q[B])},p5Q=(A,Q)=>{if(Q)for(let B in Q){let w=Q[B];if(w!==void 0)A[B]=(A[B]||[]).concat(w)}},ywA=(A,...Q)=>typeof A==="function"?A$1(Q$1,A,...Q):A$1(()=>c5Q(Q$1(),A),...Q);var i5Q=ywA({extend:{classGroups:{"font-size":[{text:["display-2xl","display-xl","display-lg","display-md","display-sm","heading-lg","heading-md","heading-sm","body-xl","body-lg","body-md","body-sm","body-xs","label-md","label-sm","label-xs"]}]}}});function B2(...A){return i5Q(L_(A))}var I$1=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,D$1=L_,dw=(A,Q)=>(B)=>{var w;if((Q===null||Q===void 0?void 0:Q.variants)==null)return D$1(A,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className);let{variants:$,defaultVariants:f}=Q,I=Object.keys($).map((Y)=>{let J=B===null||B===void 0?void 0:B[Y],X=f===null||f===void 0?void 0:f[Y];if(J===null)return null;let G=I$1(J)||I$1(X);return $[Y][G]}),D=B&&Object.entries(B).reduce((Y,J)=>{let[X,G]=J;if(G===void 0)return Y;return Y[X]=G,Y},{}),U=Q===null||Q===void 0?void 0:(w=Q.compoundVariants)===null||w===void 0?void 0:w.reduce((Y,J)=>{let{class:X,className:G,...Z}=J;return Object.entries(Z).every((N)=>{let[V,L]=N;return Array.isArray(L)?L.includes({...f,...D}[V]):{...f,...D}[V]===L})?[...Y,X,G]:Y},[]);return D$1(A,I,U,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className)};import{jsxDEV as fvA}from"preact/jsx-dev-runtime";var U$1=dw("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 IvA({variant:A,title:Q,children:B,className:w}){return fvA("div",{className:B2(U$1({variant:A}),w),role:"alert",children:[Q&&fvA("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),fvA("div",{className:B2(Q&&"mt-1","text-sm text-current opacity-75"),children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{jsxDEV as r5Q}from"preact/jsx-dev-runtime";var Y$1=dw("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 VM({variant:A,size:Q,className:B,children:w,ssrOnClick:$,type:f="button",...I}){return r5Q("button",{type:f,className:B2(Y$1({variant:A,size:Q}),B),...I,...$&&{onclick:$},children:w},void 0,!1,void 0,this)}import{jsxDEV as d5Q}from"preact/jsx-dev-runtime";var J$1=dw("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 E$({href:A,children:Q,variant:B,size:w,external:$=!1,className:f,"aria-label":I}){let D=$?{target:"_blank",rel:"noopener noreferrer"}:{};return d5Q("a",{href:A,className:B2(J$1({variant:B,size:w}),f),"aria-label":I,...D,children:Q},void 0,!1,void 0,this)}import{jsxDEV as TwA}from"preact/jsx-dev-runtime";var X$1=dw("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"}}),n5Q={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function M_({variant:A,size:Q,className:B}){let w=n5Q[Q??"md"];return TwA("button",{onclick:"toggleTheme()",type:"button",className:B2(X$1({variant:A,size:Q}),B),"aria-label":"Toggle dark mode",children:TwA("svg",{className:B2(w,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[TwA("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),TwA("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 DvA}from"preact/jsx-dev-runtime";var W$1=dw("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function xwA({items:A,className:Q,linkClassName:B="hover:text-accent transition-colors",orientation:w,children:$}){if(A.length===0&&!$)return null;let f=[...A].sort((I,D)=>I.priority-D.priority);return DvA("ul",{className:B2(W$1({orientation:w}),Q),children:[f.map((I)=>DvA("li",{children:DvA("a",{href:I.href,className:B,children:I.label},void 0,!1,void 0,this)},I.href,!1,void 0,this)),$]},void 0,!0,void 0,this)}import{jsxDEV as ERw}from"preact/jsx-dev-runtime";import{jsxDEV as ORw}from"preact/jsx-dev-runtime";import{createContext as o5Q,h as s5Q}from"preact";import{useContext as a5Q}from"preact/hooks";var UvA=o5Q(null);function C_({headCollector:A,children:Q}){return s5Q(UvA.Provider,{value:A},Q)}function H$1(){return a5Q(UvA)}function ZQ(A){let Q=H$1();if(Q)Q.setHeadProps(A);return null}import{createContext as ODQ,h as RDQ}from"preact";import{useContext as bDQ}from"preact/hooks";FzA();var Ef1=U1(Vf1(),1),MDQ=new Hh({gfm:!0,breaks:!0}),CDQ={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 jyA(A,Q){let{imageRenderer:B}=Q??{},$=(B?new Hh({gfm:!0,breaks:!0}).use({renderer:{image(f,I,D){return B(f,I,D)??!1}}}):MDQ).parse(A);return $=$.replace(/<\/blockquote>\s*<p>(\u2014|--|\u2013)([\s\S]*?)<\/p>/g,`</blockquote>
|
|
4665
|
+
`)}}aA();class CwA extends ZB{directorySync;constructor(A,Q,B){super(A,{schema:t_A,jobTypeName:"directory-export"});this.directorySync=B}async process(A,Q,B){this.logger.debug("Processing directory export job",{jobId:Q,data:A});let w=Date.now();try{let $=await this.directorySync.exportEntitiesWithProgress(A.entityTypes,B,A.batchSize??100);return this.logger.debug("Directory export job completed",{jobId:Q,exported:$.exported,failed:$.failed,duration:Date.now()-w}),$}catch($){throw this.logger.error("Directory export job failed",{jobId:Q,error:$}),$}}summarizeDataForLog(A){return{entityTypes:A.entityTypes??"all",batchSize:A.batchSize}}}aA();class OwA extends ZB{directorySync;constructor(A,Q,B){super(A,{schema:a_A,jobTypeName:"directory-import"});this.directorySync=B}async process(A,Q,B){this.logger.debug("Processing directory import job",{jobId:Q,data:A});let w=Date.now();try{let $=await this.directorySync.importEntitiesWithProgress(A.paths,B,A.batchSize??100);return this.logger.debug("Directory import job completed",{jobId:Q,imported:$.imported,skipped:$.skipped,failed:$.failed,quarantined:$.quarantined,duration:Date.now()-w}),$}catch($){throw this.logger.error("Directory import job failed",{jobId:Q,error:$}),$}}summarizeDataForLog(A){return{pathCount:A.paths?.length??"all",batchSize:A.batchSize}}}aA();class RwA extends ZB{directorySync;context;constructor(A,Q,B){super(A,{schema:o_A,jobTypeName:"directory-sync"});this.context=Q,this.directorySync=B}async process(A,Q,B){let w=Date.now(),$=A.syncDirection??"both";this.logger.info("Starting directory sync job",{jobId:Q,operation:A.operation,syncDirection:$});let f={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},I={exported:0,failed:0,errors:[]};if($!=="export")if(await B.report({progress:10,message:"Scanning directory for changes"}),f=await this.importWithProgress(A.paths,B),$==="import")await this.waitForImportJobs(f.jobIds,B),await B.report({progress:100,message:`Import complete: ${f.imported} imported`});else await B.report({progress:50,message:`Imported ${f.imported} entities`}),await this.waitForImportJobs(f.jobIds,B),await B.report({progress:56,message:"Processing complete, starting export"});if($!=="import"){let U=$==="export"?10:60;await B.report({progress:U,message:"Exporting entities to directory"}),I=await this.exportWithProgress(A.entityTypes,B),await B.report({progress:100,message:$==="export"?`Export complete: ${I.exported} exported`:`Sync complete: ${f.imported} imported, ${I.exported} exported`})}let D=Date.now()-w;return this.logger.info("Directory sync job completed",{jobId:Q,duration:D,imported:f.imported,exported:I.exported}),{import:f,export:I,duration:D}}async importWithProgress(A,Q){try{return await this.directorySync.importEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Import phase failed",{error:B}),B}}async exportWithProgress(A,Q){try{return await this.directorySync.exportEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Export phase failed",{error:B}),B}}async waitForImportJobs(A,Q){if(A.length===0)return;this.logger.debug(`Waiting for ${A.length} import jobs to complete`);let{entityService:B}=this.context,w=300000,$=500,f=Date.now(),I=async()=>{let U=(await Promise.all(A.map((J)=>B.getAsyncJobStatus(J)))).filter((J)=>J&&(J.status==="completed"||J.status==="failed")).length;if(U===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-f>w){this.logger.warn(`Timeout waiting for import jobs (${U}/${A.length} completed)`);return}let Y=Math.round(U/A.length*100);return await Q.report({progress:50+Math.round(Y*0.05),message:`Processing ${U}/${A.length} entities`}),await new Promise((J)=>setTimeout(J,$)),I()};return I()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}aA();class bwA extends ZB{context;directorySync;gitSync;constructor(A,Q,B,w){super(A,{schema:s_A,jobTypeName:"sync-request"});this.context=Q;this.directorySync=B;this.gitSync=w}async process(A,Q,B){await B.report({progress:5,message:"Pulling latest content from git"});let w=await this.gitSync.withLock(async()=>{return await this.gitSync.pull(),await B.report({progress:35,message:"Scanning pulled content for sync changes"}),this.directorySync.queueSyncBatch(this.context,A.source,{rootJobId:Q,interfaceType:A.interfaceType,channelId:A.channelId})});if(!w)return await B.report({progress:100,message:"Sync complete: no files to import"}),{gitPulled:!0,batchQueued:!1};return await B.report({progress:100,message:`Sync queued: ${w.importOperationsCount} import jobs for ${w.totalFiles} files`}),m6Q(w)}summarizeDataForLog(A){return{source:A.source,interfaceType:A.interfaceType,channelId:A.channelId}}}function m6Q(A){return{gitPulled:!0,batchQueued:!0,batchId:A.batchId,importOperations:A.importOperationsCount,totalFiles:A.totalFiles}}aA();class PwA extends ZB{context;constructor(A,Q,B){super(A,{schema:EwA,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,B){let w=EwA.parse(A);this.logger.info("Processing entity deletion for removed file",{entityId:w.entityId,entityType:w.entityType,filePath:w.filePath}),await B.report({progress:0,total:1,message:`Deleting ${w.entityType}:${w.entityId}`});try{let $=await this.context.entityService.deleteEntity({entityType:w.entityType,id:w.entityId});if($)this.logger.info("Successfully deleted entity for removed file",{entityId:w.entityId,entityType:w.entityType});else this.logger.warn("Entity not found in database",{entityId:w.entityId,entityType:w.entityType});return await B.report({progress:1,total:1,message:`Deleted ${w.entityType}:${w.entityId}`}),{deleted:$,entityId:w.entityId,entityType:w.entityType,filePath:w.filePath}}catch($){throw this.logger.error("Failed to delete entity",{entityId:w.entityId,entityType:w.entityType,error:$}),$}}summarizeDataForLog(A){return{entityId:A.entityId,entityType:A.entityType,filePath:A.filePath}}}aA();WA();var u6Q=H.object({});class kwA extends ZB{directorySync;constructor(A,Q){super(A,{schema:u6Q,jobTypeName:"directory-cleanup"});this.directorySync=Q}async process(A,Q,B){await B.report({progress:0,message:"Removing orphaned entities"});let w=await this.directorySync.removeOrphanedEntities();return await B.report({progress:100,message:`Cleanup complete: ${w.deleted} orphans removed`}),w}}aA();C7();WA();o8();C7();import{readFile as c6Q,writeFile as l6Q}from"fs/promises";var p6Q=e_A;class jwA extends ZB{context;fetcher;constructor(A,Q,B=qU){super(Q,{schema:p6Q,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=B}async process(A,Q,B){let{filePath:w,sourceUrl:$,postTitle:f,postSlug:I,customAlt:D}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:w,sourceUrl:$,postSlug:I});try{await this.reportProgress(B,{progress:qQ.INIT,message:`Reading file: ${w}`});let U;try{U=await c6Q(w,"utf-8")}catch(V){return this.logger.error("Failed to read file",{filePath:w,error:y0(V)}),K6.failure(V)}let Y;try{Y=jB(U)}catch(V){return this.logger.warn("Failed to parse markdown",{filePath:w,error:y0(V)}),K6.failure(V)}let J=Y.frontmatter;if(J.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:w}),await this.reportProgress(B,{progress:qQ.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(B,{progress:qQ.FETCH,message:"Checking for existing image"});let X=await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}}),G;if(X[0])G=X[0].id,this.logger.debug("Reusing existing image entity",{sourceUrl:$,imageId:G}),await this.reportProgress(B,{progress:qQ.EXTRACT,message:`Reusing existing image: ${G}`});else{await this.reportProgress(B,{progress:qQ.PROCESS,message:`Fetching image from ${$}`});let V;try{V=await this.fetcher($)}catch(T){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:y0(T)}),K6.failure(T)}await this.reportProgress(B,{progress:qQ.GENERATE,message:"Creating image entity"});let{base64:L}=TN(V),M=ZV(L),O=xN(L);if(!M||!O)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),K6.failure(Error("Could not detect image format or dimensions"));G=`${I}-cover`;let E=`Cover image for ${f}`,S=D??E;await this.context.entityService.createEntity({entity:{id:G,entityType:"image",content:V,metadata:{title:E,alt:S,format:M,width:O.width,height:O.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:G,sourceUrl:$}),await this.reportProgress(B,{progress:qQ.EXTRACT,message:`Created image: ${G}`})}await this.reportProgress(B,{progress:qQ.SAVE,message:"Updating file"});let Z={...J};delete Z.coverImageUrl,delete Z.coverImageAlt,Z.coverImageId=G;let N=TG(Z,Y.content);try{await l6Q(w,N,"utf-8")}catch(V){return this.logger.error("Failed to write file",{filePath:w,error:y0(V)}),K6.failure(V)}return await this.reportProgress(B,{progress:qQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:w,imageId:G,sourceUrl:$}),{success:!0,imageId:G}}catch(U){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:w,error:y0(U)}),K6.failure(U)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}aA();C7();WA();o8();import{readFile as i6Q,writeFile as r6Q}from"fs/promises";class _wA extends ZB{converter;constructor(A,Q,B=qU){super(Q,{schema:AvA,jobTypeName:"inline-image-convert"});this.converter=new zl(A.entityService,Q,B)}async process(A,Q,B){let{filePath:w,postSlug:$}=A;this.logger.debug("Starting inline image conversion job",{jobId:Q,filePath:w,postSlug:$});try{await this.reportProgress(B,{progress:qQ.INIT,message:`Reading file: ${w}`});let f;try{f=await i6Q(w,"utf-8")}catch(U){let Y=y0(U);return this.logger.error("Failed to read file",{filePath:w,error:Y}),{success:!1,error:Y}}await this.reportProgress(B,{progress:qQ.FETCH,message:"Detecting inline images"});let I=this.converter.detectInlineImages(f,$);if(I.length===0)return this.logger.debug("No inline images to convert",{filePath:w}),await this.reportProgress(B,{progress:qQ.COMPLETE,message:"No images to convert"}),{success:!0,skipped:!0,convertedCount:0};this.logger.debug("Found inline images to convert",{filePath:w,count:I.length}),await this.reportProgress(B,{progress:qQ.PROCESS,message:`Converting ${I.length} images`});let D=await this.converter.convert(f,$);if(!D.converted)return this.logger.debug("No images were converted",{filePath:w}),await this.reportProgress(B,{progress:qQ.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(B,{progress:qQ.SAVE,message:"Writing updated file"});try{await r6Q(w,D.content,"utf-8")}catch(U){let Y=y0(U);return this.logger.error("Failed to write file",{filePath:w,error:Y}),{success:!1,error:Y}}return await this.reportProgress(B,{progress:qQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:w,convertedCount:D.convertedCount}),{success:!0,convertedCount:D.convertedCount}}catch(f){let I=y0(f);return this.logger.error("Inline image conversion job failed",{jobId:Q,filePath:w,error:I}),{success:!1,error:I}}}summarizeDataForLog(A){return{filePath:A.filePath,postSlug:A.postSlug}}}function j51(A,Q,B){let w=($)=>B.child($);A.jobs.registerHandler("directory-sync",new RwA(w("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new CwA(w("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new OwA(w("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new PwA(w("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new kwA(w("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new jwA(A,w("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new _wA(A,w("InlineImageConversionJobHandler"))),B.debug("Registered async job handlers")}aA();import{unlink as d6Q,access as n6Q}from"fs/promises";function _51(A,Q,B,w){let{subscribe:$}=A.messaging,{entityService:f}=A;$("entity:created",async(I)=>{let{entity:D}=I.payload;try{await Q.fileOps.writeEntity(D),B.debug("Auto-exported created entity",{id:D.id,entityType:D.entityType})}catch(U){B.error("Auto-export FAILED for created entity",{id:D.id,entityType:D.entityType,error:U instanceof Error?U.message:String(U),stack:U instanceof Error?U.stack:void 0})}return{success:!0}}),$("entity:updated",async(I)=>{let{entityType:D,entityId:U}=I.payload;try{let Y=await f.getEntity({entityType:D,id:U});if(!Y)return B.debug("Entity not found in DB, skipping export",{entityType:D,entityId:U}),{success:!1};await Q.fileOps.writeEntity(Y),B.debug("Auto-exported updated entity",{id:Y.id,entityType:Y.entityType})}catch(Y){B.error("Auto-export FAILED for updated entity",{entityType:D,entityId:U,error:Y instanceof Error?Y.message:String(Y),stack:Y instanceof Error?Y.stack:void 0})}return{success:!0}}),$("entity:deleted",async(I)=>{let{entityId:D,entityType:U}=I.payload,Y=Q.fileOps.getFilePath(D,U);if(await n6Q(Y).then(()=>!0,()=>!1))await d6Q(Y),B.debug("Auto-deleted entity file",{id:D,entityType:U,path:Y});return{success:!0}}),B.debug("Setup auto-sync for entity events",{entityTypes:w})}function v51(A,Q,B){Q.setJobQueueCallback(async(w)=>{let $=[{type:w.type,data:w.data}];return A.jobs.enqueueBatch($,{priority:5,source:"directory-sync-watcher",rootJobId:X$(),metadata:{operationType:"file_operations",operationTarget:B,pluginId:"directory-sync"}})})}WA();aA();import{readdir as x51,mkdir as s6Q,copyFile as a6Q}from"fs/promises";import{join as T51,resolve as QvA}from"path";import{join as o6Q}from"path";async function y51(A){if(!await W5(o6Q(A,".git")))return!1;try{return await nJ(A).revparse(["--verify","HEAD"]),!0}catch{return!1}}async function t6Q(A,Q){if(!await W5(A))return!0;if((await x51(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await y51(A))return Q.debug("Git repository with history detected - skipping seed content",{path:A}),!1;return!0}async function S51(A,Q){let B=await x51(A,{withFileTypes:!0});for(let w of B){let $=T51(A,w.name),f=T51(Q,w.name);if(w.isDirectory()){if(!await W5(f))await s6Q(f,{recursive:!0});await S51($,f)}else await a6Q($,f)}}async function g51(A,Q,B){let w=QvA(process.cwd(),A);B=B?QvA(B):QvA(process.cwd(),"seed-content");let $=await t6Q(w,Q);if($&&await W5(B))Q.debug("Copying seed content to brain-data directory"),await S51(B,w),Q.debug("Seed content copied successfully");else if($)Q.debug("No seed content directory found, starting with empty brain-data");else Q.debug("brain-data directory not empty, skipping seed content")}function h51(A,Q,B,w,$){let f=!1,I=async()=>{if(f)return;f=!0;let D=Q();if(B.seedContent){let U=B.syncPath??A.dataDir;await g51(U,w,B.seedContentPath)}try{if($){w.debug("Git enabled \u2014 pulling before import");let Y=await $.pull();if(Y.files.length>0)w.info("Pulled changes from remote",{filesChanged:Y.files.length})}w.debug("Starting initial sync");let U=await D.sync();w.debug("Initial sync completed",{imported:U.import.imported,failed:U.import.failed,duration:U.duration}),await A.messaging.send({type:mL.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(U){w.error("Initial sync failed",U),await A.messaging.send({type:mL.initialSyncCompleted,payload:{success:!1,error:y0(U)},...{broadcast:!0}})}};A.messaging.subscribe(mL.pluginsRegistered,async()=>{return w.debug("Plugins registered, starting initial sync"),await I(),{success:!0}})}WA();function m51(A,Q,B,w){let $=new VL(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(D){w.error("Git auto-commit failed",{error:D})}})},B),f=["entity:created","entity:updated","entity:deleted"],I=[];for(let D of f){let U=A.subscribe(D,async()=>{return $.trigger(),{success:!0}});I.push(U)}return()=>{$.dispose();for(let D of I)D()}}function u51(A,Q,B,w,$){if(w<=0)return()=>{};let f=w*60*1000,I=!1,D=async()=>{if(I)return;I=!0;try{let{files:Y,result:J}=await A.withLock(async()=>{let X=await A.pull();if(X.files.length===0)return{files:[],result:null};let G=await Q.queueSyncBatch(B,"periodic-sync");return{files:X.files,result:G}});if(Y.length>0)$.info("Periodic sync: pulled changes",{filesChanged:Y.length});if(J)$.debug("Periodic sync: queued imports",{importOperations:J.importOperationsCount,totalFiles:J.totalFiles})}catch(Y){$.error("Periodic git sync failed",{error:Y})}finally{I=!1}},U=setInterval(()=>{D()},f);return $.info("Started periodic git sync",{intervalMinutes:w}),()=>{clearInterval(U)}}import{spawnSync as l51}from"child_process";import{cpSync as e6Q,existsSync as c51,mkdirSync as A5Q,mkdtempSync as Q5Q,rmSync as B5Q}from"fs";import{tmpdir as w5Q}from"os";import{fileURLToPath as $5Q}from"url";import{join as f5Q,resolve as I5Q}from"path";function Fz(A,Q){let B=l51("git",Q,{cwd:A,stdio:"pipe"});if(B.status!==0){let w=B.stderr.toString().trim(),$=B.stdout.toString().trim();throw Error(w||$||`git ${Q.join(" ")} failed`)}}function D5Q(A){return A.startsWith("file://")}function U5Q(A){return $5Q(A)}function Y5Q(A,Q){return l51("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function p51(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!D5Q(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",B=U5Q(A.gitUrl),w=I5Q(A.seedContentPath);if(!c51(w))throw Error(`Seed content path not found: ${w}`);if(!c51(B))A.logger.debug("Creating local bare content remote",{remotePath:B,branch:Q}),A5Q(B,{recursive:!0}),Fz(process.cwd(),["init","--bare",`--initial-branch=${Q}`,B]);if(Y5Q(B,Q)){A.logger.debug("Content remote already initialized",{remotePath:B,branch:Q});return}A.logger.debug("Seeding local content remote",{remotePath:B,seedPath:w,branch:Q});let $=Q5Q(f5Q(w5Q(),"directory-sync-seed-"));try{Fz($,["init",`--initial-branch=${Q}`]),Fz($,["config","user.name",A.authorName??"Brain"]),Fz($,["config","user.email",A.authorEmail??"brain@localhost"]),e6Q(w,$,{recursive:!0}),Fz($,["add","."]),Fz($,["commit","-m","seed content remote"]),Fz($,["remote","add","origin",A.gitUrl]),Fz($,["push","-u","origin",Q])}finally{B5Q($,{recursive:!0,force:!0})}}function i51(A,Q,B,w,$){let{subscribe:f}=A.messaging;f("entity:export:request",async(I)=>{try{return{success:!0,data:await Q().exportEntities(I.payload.entityTypes)}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Export failed"}}}),f("entity:import:request",async(I)=>{try{let D=Q(),U=I.payload.paths,Y=await D.importEntities(U);if(U&&U.length>0)await D.removeOrphanedEntities();return{success:!0,data:Y}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Import failed"}}}),f("sync:status:request",async()=>{try{let D=await Q().getStatus();return{success:!0,data:{syncPath:D.syncPath,isInitialized:D.exists,watchEnabled:D.watching}}}catch(I){return{success:!1,error:I instanceof Error?I.message:"Status check failed"}}}),f("sync:configure:request",async(I)=>{try{return await B({syncPath:I.payload.syncPath}),{success:!0,data:{syncPath:I.payload.syncPath,configured:!0}}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Configuration failed"}}}),f("git-sync:get-repo-info",async()=>{if(!$?.repo)return{success:!1,error:"Git not configured"};return{success:!0,data:{repo:$.repo,branch:$.branch??"main"}}}),w.debug("Registered message handlers")}aA();WA();aA();WA();function r51(A,Q){return oQ(A,"history","Get version history for an entity from git. Without sha: returns commit list. With sha: returns entity content at that version.",H.object({entityType:H.string().describe("Entity type (e.g. post, note, link)"),id:H.string().describe("Entity ID"),sha:H.string().optional().describe("Commit SHA to retrieve content at. Omit to list commit history."),limit:H.number().int().positive().optional().default(10).describe("Max commits to return (list mode only)")}),async(B)=>{let w=`${B.entityType}/${B.id}.md`;try{if(B.sha){let f=await Q.show(B.sha,w);return Y8({sha:B.sha,entityType:B.entityType,id:B.id,content:f},`Content at ${B.sha.slice(0,7)}`)}let $=await Q.log(w,B.limit);if($.length===0)return Y8({commits:[]},`No history found for ${B.entityType}/${B.id}`);return Y8({commits:$,entityType:B.entityType,id:B.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return H$($ instanceof Error?$.message:"History lookup failed")}})}function d51(A,Q,B,w){let $=[oQ(B,"sync","Sync brain entities with the filesystem. Use this for refresh, pull, sync, or backup-to-git requests. Pulls from git if configured, then imports files. Git commit and push happen automatically after imports complete.",H.object({}),async(f,I)=>{try{let D=I.channelId?`${I.interfaceType}:${I.channelId}`:`plugin:${B}`,U={interfaceType:I.interfaceType,channelId:I.channelId};if(w){let J=await Q.jobs.enqueue({type:"sync-request",data:{source:D,interfaceType:U.interfaceType,channelId:U.channelId},toolContext:I});return Y8({jobId:J,status:"queued",gitPulled:!0},"Sync queued: git pull and filesystem scan will run in the background")}let Y=await A.queueSyncBatch(Q,D,U);if(!Y)return Y8({gitPulled:!1},"No files to sync");return Y8({batchId:Y.batchId,importOperations:Y.importOperationsCount,totalFiles:Y.totalFiles,gitPulled:!1},`Sync started: ${Y.importOperationsCount} import jobs queued for ${Y.totalFiles} files`)}catch(D){return H$(D instanceof Error?D.message:"Sync failed")}},{cli:{name:"sync"}}),oQ(B,"status","Get sync and git repository status \u2014 last sync time, watching state, pending git changes. Use this for status questions, not for actually syncing or backing up.",H.object({}),async()=>{try{let f=await A.getStatus(),I={syncPath:f.syncPath,lastSync:f.lastSync?.toISOString(),watching:f.watching};if(w){let D=await w.getStatus();I.git={isRepo:D.isRepo,branch:D.branch,hasChanges:D.hasChanges,ahead:D.ahead,behind:D.behind,remote:D.remote}}return Y8(I)}catch(f){return H$(f instanceof Error?f.message:"Status check failed")}},{visibility:"public"})];if(w)$.push(r51(B,w));return $}var n51={name:"@brains/directory-sync",private:!0,version:"0.2.0-alpha.127",description:"Directory-based entity synchronization plugin for Brains",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":{types:"./src/index.ts",import:"./src/index.ts"}},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",clean:"rm -rf .turbo"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",chokidar:"^3.5.3","simple-git":"^3.21.0"},devDependencies:{"@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},peerDependencies:{}};class BvA extends YB{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",n51,A,_l)}requireDirectorySync(){if(!this.directorySync)throw Error("DirectorySync service not initialized");return this.directorySync}hasGitSync(){return this.gitSync!==void 0}async onRegister(A){let{logger:Q,entityService:B}=A;A.templates.register({status:{name:"status",description:"Directory synchronization status",schema:vl,basePrompt:"",formatter:new MwA,requiredPermission:"anchor"}});let w=this.config.syncPath??A.dataDir;this.directorySync=new ql({syncPath:w,autoSync:this.config.autoSync,watchInterval:this.config.watchInterval,includeMetadata:this.config.includeMetadata,entityTypes:this.config.entityTypes,deleteOnFileRemoval:this.config.deleteOnFileRemoval,entityService:B,logger:Q});try{await this.directorySync.initializeDirectory(),this.logger.debug("Directory structure initialized",{path:w})}catch(I){throw this.logger.error("Failed to initialize directory",I),I}await this.registerJobHandlers(A);let $=this.requireDirectorySync();if(_51(A,$,this.logger,this.config.entityTypes),this.config.autoSync)v51(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 p51({gitUrl:this.config.git.gitUrl,branch:this.config.git.branch,seedContentPath:this.config.seedContentPath,bootstrapFromSeed:this.config.git.bootstrapFromSeed,authorName:this.config.git.authorName,authorEmail:this.config.git.authorEmail,logger:this.logger.child("ContentRemoteBootstrap")});let I=this.config.syncPath??A.dataDir;if(this.gitSync=new n_A({logger:this.logger.child("GitSync"),dataDir:I,repo:this.config.git.repo,gitUrl:this.config.git.gitUrl,branch:this.config.git.branch,authToken:this.config.git.authToken,authorName:this.config.git.authorName,authorEmail:this.config.git.authorEmail}),await this.gitSync.initialize(),this.logger.info("Git integration enabled",{repo:this.config.git.repo}),A.jobs.registerHandler("sync-request",new bwA(this.logger.child("DirectorySyncRequestJobHandler"),A,this.requireDirectorySync(),this.gitSync)),this.gitCleanups.push(m51(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(u51(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)h51(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);i51(A,()=>this.requireDirectorySync(),(I)=>this.configure(I),this.logger,this.config.git)}async getTools(){let A=this.requireDirectorySync();return d51(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 ql({...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){j51(A,this.requireDirectorySync(),this.logger)}}function LM(A={}){return new BvA(A)}aA();WA();var o51={name:"@brains/email-resend",private:!0,version:"0.2.0-alpha.127",description:"Generic email delivery adapter for Resend",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/email-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var W5Q=H.object({apiKey:H.string().min(1).optional(),from:H.string().min(1).optional()});class s51 extends YB{fetchImpl;constructor(A={},Q={}){super("email-resend",o51,A,W5Q);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(e0A,async(B)=>{let w=fE0.parse(B.payload);try{return{success:!0,data:await this.sendWithResend(w)}}catch($){if(w.sensitivity==="secret")Q.warn("Email delivery failed for a secret message");else Q.warn("Email delivery failed",{to:w.to,subject:w.subject,error:$ instanceof Error?$.message:String($)});return{success:!1,error:"Email delivery failed"}}})}async sendWithResend(A){let Q=this.config.apiKey,B=this.config.from;if(!Q||!B)return{status:"failed"};let w=await this.fetchImpl("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${Q}`,"Content-Type":"application/json"},body:JSON.stringify({from:B,to:A.to,subject:A.subject,text:A.text,...A.html?{html:A.html}:{}})});if(!w.ok)throw Error("Resend email request failed");let $=await w.json();return $.id?{status:"sent",id:$.id}:{status:"sent"}}}function vwA(A={}){return new s51(A)}aA();import{render as YK1}from"preact-render-to-string";import{h as $C}from"preact";function a51(A){var Q,B,w="";if(typeof A=="string"||typeof A=="number")w+=A;else if(typeof A=="object")if(Array.isArray(A)){var $=A.length;for(Q=0;Q<$;Q++)A[Q]&&(B=a51(A[Q]))&&(w&&(w+=" "),w+=B)}else for(B in A)A[B]&&(w&&(w+=" "),w+=B);return w}function L_(){for(var A,Q,B=0,w="",$=arguments.length;B<$;B++)(A=arguments[B])&&(Q=a51(A))&&(w&&(w+=" "),w+=Q);return w}var H5Q=(A)=>{let Q=K5Q(A),{conflictingClassGroups:B,conflictingClassGroupModifiers:w}=A;return{getClassGroupId:(I)=>{let D=I.split("-");if(D[0]===""&&D.length!==1)D.shift();return B$1(D,Q)||G5Q(I)},getConflictingClassGroupIds:(I,D)=>{let U=B[I]||[];if(D&&w[I])return[...U,...w[I]];return U}}},B$1=(A,Q)=>{if(A.length===0)return Q.classGroupId;let B=A[0],w=Q.nextPart.get(B),$=w?B$1(A.slice(1),w):void 0;if($)return $;if(Q.validators.length===0)return;let f=A.join("-");return Q.validators.find(({validator:I})=>I(f))?.classGroupId},t51=/^\[(.+)\]$/,G5Q=(A)=>{if(t51.test(A)){let Q=t51.exec(A)[1],B=Q?.substring(0,Q.indexOf(":"));if(B)return"arbitrary.."+B}},K5Q=(A)=>{let{theme:Q,prefix:B}=A,w={nextPart:new Map,validators:[]};return Z5Q(Object.entries(A.classGroups),B).forEach(([f,I])=>{$vA(I,w,f,Q)}),w},$vA=(A,Q,B,w)=>{A.forEach(($)=>{if(typeof $==="string"){let f=$===""?Q:e51(Q,$);f.classGroupId=B;return}if(typeof $==="function"){if(F5Q($)){$vA($(w),Q,B,w);return}Q.validators.push({validator:$,classGroupId:B});return}Object.entries($).forEach(([f,I])=>{$vA(I,e51(Q,f),B,w)})})},e51=(A,Q)=>{let B=A;return Q.split("-").forEach((w)=>{if(!B.nextPart.has(w))B.nextPart.set(w,{nextPart:new Map,validators:[]});B=B.nextPart.get(w)}),B},F5Q=(A)=>A.isThemeGetter,Z5Q=(A,Q)=>{if(!Q)return A;return A.map(([B,w])=>{let $=w.map((f)=>{if(typeof f==="string")return Q+f;if(typeof f==="object")return Object.fromEntries(Object.entries(f).map(([I,D])=>[Q+I,D]));return f});return[B,$]})},N5Q=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,B=new Map,w=new Map,$=(f,I)=>{if(B.set(f,I),Q++,Q>A)Q=0,w=B,B=new Map};return{get(f){let I=B.get(f);if(I!==void 0)return I;if((I=w.get(f))!==void 0)return $(f,I),I},set(f,I){if(B.has(f))B.set(f,I);else $(f,I)}}};var z5Q=(A)=>{let{separator:Q,experimentalParseClassName:B}=A,w=Q.length===1,$=Q[0],f=Q.length,I=(D)=>{let U=[],Y=0,J=0,X;for(let L=0;L<D.length;L++){let M=D[L];if(Y===0){if(M===$&&(w||D.slice(L,L+f)===Q)){U.push(D.slice(J,L)),J=L+f;continue}if(M==="/"){X=L;continue}}if(M==="[")Y++;else if(M==="]")Y--}let G=U.length===0?D:D.substring(J),Z=G.startsWith("!"),N=Z?G.substring(1):G,V=X&&X>J?X-J:void 0;return{modifiers:U,hasImportantModifier:Z,baseClassName:N,maybePostfixModifierPosition:V}};if(B)return(D)=>B({className:D,parseClassName:I});return I},q5Q=(A)=>{if(A.length<=1)return A;let Q=[],B=[];return A.forEach((w)=>{if(w[0]==="[")Q.push(...B.sort(),w),B=[];else B.push(w)}),Q.push(...B.sort()),Q},L5Q=(A)=>({cache:N5Q(A.cacheSize),parseClassName:z5Q(A),...H5Q(A)}),V5Q=/\s+/,E5Q=(A,Q)=>{let{parseClassName:B,getClassGroupId:w,getConflictingClassGroupIds:$}=Q,f=[],I=A.trim().split(V5Q),D="";for(let U=I.length-1;U>=0;U-=1){let Y=I[U],{modifiers:J,hasImportantModifier:X,baseClassName:G,maybePostfixModifierPosition:Z}=B(Y),N=Boolean(Z),V=w(N?G.substring(0,Z):G);if(!V){if(!N){D=Y+(D.length>0?" "+D:D);continue}if(V=w(G),!V){D=Y+(D.length>0?" "+D:D);continue}N=!1}let L=q5Q(J).join(":"),M=X?L+"!":L,O=M+V;if(f.includes(O))continue;f.push(O);let E=$(V,N);for(let S=0;S<E.length;++S){let T=E[S];f.push(M+T)}D=Y+(D.length>0?" "+D:D)}return D};function M5Q(){let A=0,Q,B,w="";while(A<arguments.length)if(Q=arguments[A++]){if(B=w$1(Q))w&&(w+=" "),w+=B}return w}var w$1=(A)=>{if(typeof A==="string")return A;let Q,B="";for(let w=0;w<A.length;w++)if(A[w]){if(Q=w$1(A[w]))B&&(B+=" "),B+=Q}return B};function A$1(A,...Q){let B,w,$,f=I;function I(U){let Y=Q.reduce((J,X)=>X(J),A());return B=L5Q(Y),w=B.cache.get,$=B.cache.set,f=D,D(U)}function D(U){let Y=w(U);if(Y)return Y;let J=E5Q(U,B);return $(U,J),J}return function(){return f(M5Q.apply(null,arguments))}}var T8=(A)=>{let Q=(B)=>B[A]||[];return Q.isThemeGetter=!0,Q},$$1=/^\[(?:([a-z-]+):)?(.+)\]$/i,C5Q=/^\d+\/\d+$/,O5Q=new Set(["px","full","screen"]),R5Q=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,b5Q=/\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$/,P5Q=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,k5Q=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,j5Q=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,KF=(A)=>V_(A)||O5Q.has(A)||C5Q.test(A),Zz=(A)=>E_(A,"length",h5Q),V_=(A)=>Boolean(A)&&!Number.isNaN(Number(A)),wvA=(A)=>E_(A,"number",V_),yl=(A)=>Boolean(A)&&Number.isInteger(Number(A)),_5Q=(A)=>A.endsWith("%")&&V_(A.slice(0,-1)),rQ=(A)=>$$1.test(A),Nz=(A)=>R5Q.test(A),v5Q=new Set(["length","size","percentage"]),y5Q=(A)=>E_(A,v5Q,f$1),T5Q=(A)=>E_(A,"position",f$1),x5Q=new Set(["image","url"]),S5Q=(A)=>E_(A,x5Q,u5Q),g5Q=(A)=>E_(A,"",m5Q),Tl=()=>!0,E_=(A,Q,B)=>{let w=$$1.exec(A);if(w){if(w[1])return typeof Q==="string"?w[1]===Q:Q.has(w[1]);return B(w[2])}return!1},h5Q=(A)=>b5Q.test(A)&&!P5Q.test(A),f$1=()=>!1,m5Q=(A)=>k5Q.test(A),u5Q=(A)=>j5Q.test(A);var Q$1=()=>{let A=T8("colors"),Q=T8("spacing"),B=T8("blur"),w=T8("brightness"),$=T8("borderColor"),f=T8("borderRadius"),I=T8("borderSpacing"),D=T8("borderWidth"),U=T8("contrast"),Y=T8("grayscale"),J=T8("hueRotate"),X=T8("invert"),G=T8("gap"),Z=T8("gradientColorStops"),N=T8("gradientColorStopPositions"),V=T8("inset"),L=T8("margin"),M=T8("opacity"),O=T8("padding"),E=T8("saturate"),S=T8("scale"),T=T8("sepia"),y=T8("skew"),_=T8("space"),x=T8("translate"),g=()=>["auto","contain","none"],n=()=>["auto","hidden","clip","visible","scroll"],m=()=>["auto",rQ,Q],BA=()=>[rQ,Q],a=()=>["",KF,Zz],j=()=>["auto",V_,rQ],R=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],P=()=>["solid","dashed","dotted","double","none"],c=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],l=()=>["start","end","center","between","around","evenly","stretch"],e=()=>["","0",rQ],s=()=>["auto","avoid","all","avoid-page","page","left","right","column"],XA=()=>[V_,rQ];return{cacheSize:500,separator:":",theme:{colors:[Tl],spacing:[KF,Zz],blur:["none","",Nz,rQ],brightness:XA(),borderColor:[A],borderRadius:["none","","full",Nz,rQ],borderSpacing:BA(),borderWidth:a(),contrast:XA(),grayscale:e(),hueRotate:XA(),invert:e(),gap:BA(),gradientColorStops:[A],gradientColorStopPositions:[_5Q,Zz],inset:m(),margin:m(),opacity:XA(),padding:BA(),saturate:XA(),scale:XA(),sepia:e(),skew:XA(),space:BA(),translate:BA()},classGroups:{aspect:[{aspect:["auto","square","video",rQ]}],container:["container"],columns:[{columns:[Nz]}],"break-after":[{"break-after":s()}],"break-before":[{"break-before":s()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:[...R(),rQ]}],overflow:[{overflow:n()}],"overflow-x":[{"overflow-x":n()}],"overflow-y":[{"overflow-y":n()}],overscroll:[{overscroll:g()}],"overscroll-x":[{"overscroll-x":g()}],"overscroll-y":[{"overscroll-y":g()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:[V]}],"inset-x":[{"inset-x":[V]}],"inset-y":[{"inset-y":[V]}],start:[{start:[V]}],end:[{end:[V]}],top:[{top:[V]}],right:[{right:[V]}],bottom:[{bottom:[V]}],left:[{left:[V]}],visibility:["visible","invisible","collapse"],z:[{z:["auto",yl,rQ]}],basis:[{basis:m()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",rQ]}],grow:[{grow:e()}],shrink:[{shrink:e()}],order:[{order:["first","last","none",yl,rQ]}],"grid-cols":[{"grid-cols":[Tl]}],"col-start-end":[{col:["auto",{span:["full",yl,rQ]},rQ]}],"col-start":[{"col-start":j()}],"col-end":[{"col-end":j()}],"grid-rows":[{"grid-rows":[Tl]}],"row-start-end":[{row:["auto",{span:[yl,rQ]},rQ]}],"row-start":[{"row-start":j()}],"row-end":[{"row-end":j()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",rQ]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",rQ]}],gap:[{gap:[G]}],"gap-x":[{"gap-x":[G]}],"gap-y":[{"gap-y":[G]}],"justify-content":[{justify:["normal",...l()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...l(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...l(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[O]}],px:[{px:[O]}],py:[{py:[O]}],ps:[{ps:[O]}],pe:[{pe:[O]}],pt:[{pt:[O]}],pr:[{pr:[O]}],pb:[{pb:[O]}],pl:[{pl:[O]}],m:[{m:[L]}],mx:[{mx:[L]}],my:[{my:[L]}],ms:[{ms:[L]}],me:[{me:[L]}],mt:[{mt:[L]}],mr:[{mr:[L]}],mb:[{mb:[L]}],ml:[{ml:[L]}],"space-x":[{"space-x":[_]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[_]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",rQ,Q]}],"min-w":[{"min-w":[rQ,Q,"min","max","fit"]}],"max-w":[{"max-w":[rQ,Q,"none","full","min","max","fit","prose",{screen:[Nz]},Nz]}],h:[{h:[rQ,Q,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[rQ,Q,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[rQ,Q,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[rQ,Q,"auto","min","max","fit"]}],"font-size":[{text:["base",Nz,Zz]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",wvA]}],"font-family":[{font:[Tl]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:["tighter","tight","normal","wide","wider","widest",rQ]}],"line-clamp":[{"line-clamp":["none",V_,wvA]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",KF,rQ]}],"list-image":[{"list-image":["none",rQ]}],"list-style-type":[{list:["none","disc","decimal",rQ]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[A]}],"placeholder-opacity":[{"placeholder-opacity":[M]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[A]}],"text-opacity":[{"text-opacity":[M]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...P(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",KF,Zz]}],"underline-offset":[{"underline-offset":["auto",KF,rQ]}],"text-decoration-color":[{decoration:[A]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:BA()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",rQ]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",rQ]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[M]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...R(),T5Q]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",y5Q]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},S5Q]}],"bg-color":[{bg:[A]}],"gradient-from-pos":[{from:[N]}],"gradient-via-pos":[{via:[N]}],"gradient-to-pos":[{to:[N]}],"gradient-from":[{from:[Z]}],"gradient-via":[{via:[Z]}],"gradient-to":[{to:[Z]}],rounded:[{rounded:[f]}],"rounded-s":[{"rounded-s":[f]}],"rounded-e":[{"rounded-e":[f]}],"rounded-t":[{"rounded-t":[f]}],"rounded-r":[{"rounded-r":[f]}],"rounded-b":[{"rounded-b":[f]}],"rounded-l":[{"rounded-l":[f]}],"rounded-ss":[{"rounded-ss":[f]}],"rounded-se":[{"rounded-se":[f]}],"rounded-ee":[{"rounded-ee":[f]}],"rounded-es":[{"rounded-es":[f]}],"rounded-tl":[{"rounded-tl":[f]}],"rounded-tr":[{"rounded-tr":[f]}],"rounded-br":[{"rounded-br":[f]}],"rounded-bl":[{"rounded-bl":[f]}],"border-w":[{border:[D]}],"border-w-x":[{"border-x":[D]}],"border-w-y":[{"border-y":[D]}],"border-w-s":[{"border-s":[D]}],"border-w-e":[{"border-e":[D]}],"border-w-t":[{"border-t":[D]}],"border-w-r":[{"border-r":[D]}],"border-w-b":[{"border-b":[D]}],"border-w-l":[{"border-l":[D]}],"border-opacity":[{"border-opacity":[M]}],"border-style":[{border:[...P(),"hidden"]}],"divide-x":[{"divide-x":[D]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[D]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[M]}],"divide-style":[{divide:P()}],"border-color":[{border:[$]}],"border-color-x":[{"border-x":[$]}],"border-color-y":[{"border-y":[$]}],"border-color-s":[{"border-s":[$]}],"border-color-e":[{"border-e":[$]}],"border-color-t":[{"border-t":[$]}],"border-color-r":[{"border-r":[$]}],"border-color-b":[{"border-b":[$]}],"border-color-l":[{"border-l":[$]}],"divide-color":[{divide:[$]}],"outline-style":[{outline:["",...P()]}],"outline-offset":[{"outline-offset":[KF,rQ]}],"outline-w":[{outline:[KF,Zz]}],"outline-color":[{outline:[A]}],"ring-w":[{ring:a()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[A]}],"ring-opacity":[{"ring-opacity":[M]}],"ring-offset-w":[{"ring-offset":[KF,Zz]}],"ring-offset-color":[{"ring-offset":[A]}],shadow:[{shadow:["","inner","none",Nz,g5Q]}],"shadow-color":[{shadow:[Tl]}],opacity:[{opacity:[M]}],"mix-blend":[{"mix-blend":[...c(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":c()}],filter:[{filter:["","none"]}],blur:[{blur:[B]}],brightness:[{brightness:[w]}],contrast:[{contrast:[U]}],"drop-shadow":[{"drop-shadow":["","none",Nz,rQ]}],grayscale:[{grayscale:[Y]}],"hue-rotate":[{"hue-rotate":[J]}],invert:[{invert:[X]}],saturate:[{saturate:[E]}],sepia:[{sepia:[T]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[B]}],"backdrop-brightness":[{"backdrop-brightness":[w]}],"backdrop-contrast":[{"backdrop-contrast":[U]}],"backdrop-grayscale":[{"backdrop-grayscale":[Y]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[J]}],"backdrop-invert":[{"backdrop-invert":[X]}],"backdrop-opacity":[{"backdrop-opacity":[M]}],"backdrop-saturate":[{"backdrop-saturate":[E]}],"backdrop-sepia":[{"backdrop-sepia":[T]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":[I]}],"border-spacing-x":[{"border-spacing-x":[I]}],"border-spacing-y":[{"border-spacing-y":[I]}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["none","all","","colors","opacity","shadow","transform",rQ]}],duration:[{duration:XA()}],ease:[{ease:["linear","in","out","in-out",rQ]}],delay:[{delay:XA()}],animate:[{animate:["none","spin","ping","pulse","bounce",rQ]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[S]}],"scale-x":[{"scale-x":[S]}],"scale-y":[{"scale-y":[S]}],rotate:[{rotate:[yl,rQ]}],"translate-x":[{"translate-x":[x]}],"translate-y":[{"translate-y":[x]}],"skew-x":[{"skew-x":[y]}],"skew-y":[{"skew-y":[y]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",rQ]}],accent:[{accent:["auto",A]}],appearance:[{appearance:["none","auto"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",rQ]}],"caret-color":[{caret:[A]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":BA()}],"scroll-mx":[{"scroll-mx":BA()}],"scroll-my":[{"scroll-my":BA()}],"scroll-ms":[{"scroll-ms":BA()}],"scroll-me":[{"scroll-me":BA()}],"scroll-mt":[{"scroll-mt":BA()}],"scroll-mr":[{"scroll-mr":BA()}],"scroll-mb":[{"scroll-mb":BA()}],"scroll-ml":[{"scroll-ml":BA()}],"scroll-p":[{"scroll-p":BA()}],"scroll-px":[{"scroll-px":BA()}],"scroll-py":[{"scroll-py":BA()}],"scroll-ps":[{"scroll-ps":BA()}],"scroll-pe":[{"scroll-pe":BA()}],"scroll-pt":[{"scroll-pt":BA()}],"scroll-pr":[{"scroll-pr":BA()}],"scroll-pb":[{"scroll-pb":BA()}],"scroll-pl":[{"scroll-pl":BA()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",rQ]}],fill:[{fill:[A,"none"]}],"stroke-w":[{stroke:[KF,Zz,wvA]}],stroke:[{stroke:[A,"none"]}],sr:["sr-only","not-sr-only"],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-s","border-w-e","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-s","border-color-e","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]}}},c5Q=(A,{cacheSize:Q,prefix:B,separator:w,experimentalParseClassName:$,extend:f={},override:I={}})=>{xl(A,"cacheSize",Q),xl(A,"prefix",B),xl(A,"separator",w),xl(A,"experimentalParseClassName",$);for(let D in I)l5Q(A[D],I[D]);for(let D in f)p5Q(A[D],f[D]);return A},xl=(A,Q,B)=>{if(B!==void 0)A[Q]=B},l5Q=(A,Q)=>{if(Q)for(let B in Q)xl(A,B,Q[B])},p5Q=(A,Q)=>{if(Q)for(let B in Q){let w=Q[B];if(w!==void 0)A[B]=(A[B]||[]).concat(w)}},ywA=(A,...Q)=>typeof A==="function"?A$1(Q$1,A,...Q):A$1(()=>c5Q(Q$1(),A),...Q);var i5Q=ywA({extend:{classGroups:{"font-size":[{text:["display-2xl","display-xl","display-lg","display-md","display-sm","heading-lg","heading-md","heading-sm","body-xl","body-lg","body-md","body-sm","body-xs","label-md","label-sm","label-xs"]}]}}});function B2(...A){return i5Q(L_(A))}var I$1=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,D$1=L_,dw=(A,Q)=>(B)=>{var w;if((Q===null||Q===void 0?void 0:Q.variants)==null)return D$1(A,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className);let{variants:$,defaultVariants:f}=Q,I=Object.keys($).map((Y)=>{let J=B===null||B===void 0?void 0:B[Y],X=f===null||f===void 0?void 0:f[Y];if(J===null)return null;let G=I$1(J)||I$1(X);return $[Y][G]}),D=B&&Object.entries(B).reduce((Y,J)=>{let[X,G]=J;if(G===void 0)return Y;return Y[X]=G,Y},{}),U=Q===null||Q===void 0?void 0:(w=Q.compoundVariants)===null||w===void 0?void 0:w.reduce((Y,J)=>{let{class:X,className:G,...Z}=J;return Object.entries(Z).every((N)=>{let[V,L]=N;return Array.isArray(L)?L.includes({...f,...D}[V]):{...f,...D}[V]===L})?[...Y,X,G]:Y},[]);return D$1(A,I,U,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className)};import{jsxDEV as fvA}from"preact/jsx-dev-runtime";var U$1=dw("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 IvA({variant:A,title:Q,children:B,className:w}){return fvA("div",{className:B2(U$1({variant:A}),w),role:"alert",children:[Q&&fvA("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),fvA("div",{className:B2(Q&&"mt-1","text-sm text-current opacity-75"),children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{jsxDEV as r5Q}from"preact/jsx-dev-runtime";var Y$1=dw("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 VM({variant:A,size:Q,className:B,children:w,ssrOnClick:$,type:f="button",...I}){return r5Q("button",{type:f,className:B2(Y$1({variant:A,size:Q}),B),...I,...$&&{onclick:$},children:w},void 0,!1,void 0,this)}import{jsxDEV as d5Q}from"preact/jsx-dev-runtime";var J$1=dw("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 E$({href:A,children:Q,variant:B,size:w,external:$=!1,className:f,"aria-label":I}){let D=$?{target:"_blank",rel:"noopener noreferrer"}:{};return d5Q("a",{href:A,className:B2(J$1({variant:B,size:w}),f),"aria-label":I,...D,children:Q},void 0,!1,void 0,this)}import{jsxDEV as TwA}from"preact/jsx-dev-runtime";var X$1=dw("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"}}),n5Q={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function M_({variant:A,size:Q,className:B}){let w=n5Q[Q??"md"];return TwA("button",{onclick:"toggleTheme()",type:"button",className:B2(X$1({variant:A,size:Q}),B),"aria-label":"Toggle dark mode",children:TwA("svg",{className:B2(w,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[TwA("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),TwA("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 DvA}from"preact/jsx-dev-runtime";var W$1=dw("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function xwA({items:A,className:Q,linkClassName:B="hover:text-accent transition-colors",orientation:w,children:$}){if(A.length===0&&!$)return null;let f=[...A].sort((I,D)=>I.priority-D.priority);return DvA("ul",{className:B2(W$1({orientation:w}),Q),children:[f.map((I)=>DvA("li",{children:DvA("a",{href:I.href,className:B,children:I.label},void 0,!1,void 0,this)},I.href,!1,void 0,this)),$]},void 0,!0,void 0,this)}import{jsxDEV as ERw}from"preact/jsx-dev-runtime";import{jsxDEV as ORw}from"preact/jsx-dev-runtime";import{createContext as o5Q,h as s5Q}from"preact";import{useContext as a5Q}from"preact/hooks";var UvA=o5Q(null);function C_({headCollector:A,children:Q}){return s5Q(UvA.Provider,{value:A},Q)}function H$1(){return a5Q(UvA)}function ZQ(A){let Q=H$1();if(Q)Q.setHeadProps(A);return null}import{createContext as ODQ,h as RDQ}from"preact";import{useContext as bDQ}from"preact/hooks";FzA();var Ef1=U1(Vf1(),1),MDQ=new Hh({gfm:!0,breaks:!0}),CDQ={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 jyA(A,Q){let{imageRenderer:B}=Q??{},$=(B?new Hh({gfm:!0,breaks:!0}).use({renderer:{image(f,I,D){return B(f,I,D)??!1}}}):MDQ).parse(A);return $=$.replace(/<\/blockquote>\s*<p>(\u2014|--|\u2013)([\s\S]*?)<\/p>/g,`</blockquote>
|
|
4666
4666
|
<cite class="block-attribution"><span class="emdash">$1</span>$2</cite>`),Ef1.default($,CDQ)}var Mf1=ODQ(null);function c_({imageRenderer:A,children:Q}){return RDQ(Mf1.Provider,{value:A??null},Q)}function Cf1(){return bDQ(Mf1)}function MF(){let A=Cf1();return(Q)=>jyA(Q,A?{imageRenderer:A}:void 0)}var PDQ=/<pre><code class="language-mermaid">([\s\S]*?)<\/code><\/pre>/g,kDQ={"&":"&","<":"<",">":">",""":'"',"'":"'"},jDQ=/&(?:amp|lt|gt|quot|#39);/g;function _DQ(A){return A.replace(jDQ,(Q)=>kDQ[Q]??Q)}function _yA(A){return A.replace(PDQ,(Q,B)=>{return`<div class="mermaid">${_DQ(B)}</div>`})}var Of1=/<!--\s*\.slide:\s*(.*?)\s*-->/g;function Rf1(A){let Q={};for(let w of A.matchAll(Of1)){let $=w[1]??"";for(let I of $.matchAll(/([\w-]+)=["']([^"']*?)["']/g)){let D=I[1],U=I[2];if(D&&U!==void 0)Q[D]=U}let f=$.replace(/([\w-]+)=["']([^"']*?)["']/g,"").trim();if(f)for(let I of f.matchAll(/(?:^|\s)([\w-]+)(?=\s|$)/g)){let D=I[1];if(D)Q[D]="true"}}let B=A.replace(Of1,"").replace(/^\n+/,"").replace(/\n{3,}/g,`
|
|
4667
4667
|
|
|
4668
4668
|
`).trim();return{attributes:Q,markdown:B}}var vDQ=/<!--\s*\.break\s*-->/;function bf1(A){let Q=A.split(vDQ);return Q.length>1?Q:null}import{jsxDEV as KH}from"preact/jsx-dev-runtime";var vyA=({markdown:A,deck:Q})=>{let B=MF(),$=A.split(/^---$/gm).map((J)=>J.trim()).map((J)=>{let{attributes:X,markdown:G}=Rf1(J),Z=bf1(G),N;if(Z)N=`<div class="slide-columns">${Z.map((L)=>`<div class="slide-column">${_yA(B(L.trim()))}</div>`).join("")}</div>`;else N=_yA(B(G));return{attributes:X,htmlContent:N}}),f=$.some((J)=>J.htmlContent.includes('class="mermaid"')),I=Q?.frontmatter?.title??Q?.metadata?.title,D=Q?.frontmatter?.description??Q?.metadata?.description,U=Q?.ogImageUrl??Q?.coverImageUrl,Y=$.map(({attributes:J,htmlContent:X},G)=>KH("section",{...J,dangerouslySetInnerHTML:{__html:X}},G,!1,void 0,this));return KH("section",{className:"presentation-section",children:[I&&KH(ZQ,{title:I,...D?{description:D}:{},...U?{ogImage:U}:{},ogType:"article"},void 0,!1,void 0,this),KH("link",{rel:"stylesheet",href:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.css"},void 0,!1,void 0,this),KH("div",{className:"reveal",children:KH("div",{className:"slides",children:Y},void 0,!1,void 0,this)},void 0,!1,void 0,this),KH("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&&KH("script",{src:"https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js",defer:!0},void 0,!1,void 0,this),KH("script",{dangerouslySetInnerHTML:{__html:`
|
|
@@ -5649,13 +5649,13 @@ ${A.map((f)=>({url:`${Q}${f.path}`,lastmod:B,changefreq:f.path==="/"?"daily":"we
|
|
|
5649
5649
|
`+$:B,I=RH(this.outputDir,"styles","main.css");await this.cssProcessor.process(f,I,this.workingDir,this.outputDir,this.logger);let D=await o9.readFile(I,"utf-8"),U=w.length>0?w:Q;if(U.length>0){let Y=U.join(`
|
|
5650
5650
|
`)+`
|
|
5651
5651
|
|
|
5652
|
-
`+D;await o9.writeFile(I,Y,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=RH(process.cwd(),"public");try{await o9.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await o9.readdir(A,{withFileTypes:!0});for(let B of Q){let w=RH(A,B.name),$=RH(this.outputDir,B.name);if(B.isDirectory())await this.copyDirectory(w,$);else await o9.copyFile(w,$),this.logger.debug(`Copied static asset: ${B.name}`)}this.logger.debug("Static assets copied successfully")}async writeInlineStaticAssets(A){if(!A)return;let Q=Object.entries(A);if(Q.length===0)return;this.logger.debug(`Writing ${Q.length} inline static asset(s) from SitePackage`),await Promise.all(Q.map(async([B,w])=>{let $=B.startsWith("/")?B.slice(1):B,f=RH(this.outputDir,$);await o9.mkdir(SLQ(f),{recursive:!0}),await o9.writeFile(f,w,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await o9.mkdir(Q,{recursive:!0});let B=await o9.readdir(A,{withFileTypes:!0});for(let w of B){let $=RH(A,w.name),f=RH(Q,w.name);if(w.isDirectory())await this.copyDirectory($,f);else await o9.copyFile($,f)}}}function WSA(A){return new JK1(A)}I5();WA();WA();I5();var XK1=H.object({environment:H.enum(["preview","production"]),outputDir:H.string(),workingDir:H.string().optional(),sharedImagesDir:H.string().default("./dist/images"),enableContentGeneration:H.boolean().default(!1),cleanBeforeBuild:H.boolean().default(!0),siteConfig:EI,layouts:H.record(H.any()),themeCSS:H.string().optional()}),Ohw=H.object({success:H.boolean(),outputDir:H.string(),filesGenerated:H.number(),routesBuilt:H.number(),errors:H.array(H.string()).optional(),warnings:H.array(H.string()).optional()});function WK1(A){let Q=A.list(),B=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:B}}function HK1(A,Q,B){let w=Q.getProfile(),$=B.getNavigationItems("primary"),f=B.getNavigationItems("secondary");return{...A,...w.socialLinks!==void 0&&{socialLinks:w.socialLinks},navigation:{primary:$,secondary:f},copyright:A.copyright??"Powered by Rizom"}}I5();C7();I5();WA();var gLQ=H.object({id:H.string(),entityType:H.string(),content:H.string(),metadata:H.object({slug:H.string()}).passthrough()}).passthrough(),hLQ=H.object({content:H.string(),metadata:H.object({width:H.number().optional(),height:H.number().optional()}).passthrough()});async function W5A(A,Q){let B=Q.urlGenerator??Z7.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((S)=>W5A(S,{...Q,urlGenerator:B})));if(typeof A!=="object")return A;let w={},$=Object.entries(A),f=await Promise.all($.map(([,S])=>W5A(S,{...Q,urlGenerator:B})));for(let S=0;S<$.length;S++){let T=$[S];if(T)w[T[0]]=f[S]}let I=gLQ.safeParse(A);if(!I.success)return w;let D=I.data,U=D.entityType,Y=D.metadata.slug,J=Q.pipelineContext.entityDisplay?.[U],X=J?J.label:U.charAt(0).toUpperCase()+U.slice(1),G=J?J.pluralName??J.label.toLowerCase()+"s":LI(U),Z=`/${G}`,N=G.charAt(0).toUpperCase()+G.slice(1),V=qg(D),L=await mLQ(V,Q),M=Tt(D)??V,O=await uLQ(M,Q);return{...w,...D,url:B.generateUrl(U,Y),typeLabel:X,listUrl:Z,listLabel:N,...L,...O&&{ogImageUrl:O}}}async function mLQ(A,Q){let B=A?Q.imageBuildService?.get(A):void 0;if(B)return{coverImageUrl:B.src,coverImageWidth:B.width,coverImageHeight:B.height,...B.srcset&&{coverImageSrcset:B.srcset,coverImageSizes:B.sizes}};let w=await KK1(A,Q.pipelineContext.services.entityService);if(!w)return{};return{coverImageUrl:w.url,...w.width&&{coverImageWidth:w.width},...w.height&&{coverImageHeight:w.height}}}async function uLQ(A,Q){if(!A)return;let B=Q.imageBuildService?.get(A);if(B)return GK1(B.src,Q.siteUrl);let w=await KK1(A,Q.pipelineContext.services.entityService);if(!w)return;if(w.url.startsWith("data:"))return;return GK1(w.url,Q.siteUrl)}function GK1(A,Q){if(/^https?:\/\//i.test(A)||A.startsWith("data:"))return A;if(!Q)return A;return`${Q.replace(/\/$/,"")}/${A.replace(/^\//,"")}`}async function KK1(A,Q){if(!A)return;let B=await Q.getEntity({entityType:"image",id:A}),w=hLQ.safeParse(B);if(!w.success)return;return{url:w.data.content,...w.data.metadata.width&&{width:w.data.metadata.width},...w.data.metadata.height&&{height:w.data.metadata.height}}}async function FK1(A,Q){let B=new Set;try{let w=A.getEntityTypes();for(let $ of w){if($==="image")continue;let f=await A.listEntities({entityType:$});for(let I of f){let D=qg(I);if(D)B.add(D);let U=Tt(I);if(U)B.add(U)}}}catch(w){Q.warn("Failed to collect image IDs for pre-resolution",{error:y0(w)})}return[...B]}async function ZK1(A,Q,B,w,$){if(!A.template)return A.content??null;let f=A.template,I=A.dataQuery?{dataParams:A.dataQuery,fallback:A.content,publishedOnly:B,visibilityScope:w}:{savedContent:{entityType:"site-content",entityId:`${Q.id}:${A.id}`},fallback:A.content,visibilityScope:w},D=await $.pipelineContext.services.resolveTemplateContent(f,I);if(!D)return null;return W5A(D,{pipelineContext:$.pipelineContext,imageBuildService:$.imageBuildService,siteUrl:$.siteUrl,urlGenerator:Z7.getInstance()})}function NK1(A){return{routes:A.routes,siteConfig:{title:A.siteMetadata.title,description:A.siteMetadata.description,...A.siteMetadata.url&&{url:A.siteMetadata.url},...A.siteMetadata.copyright&&{copyright:A.siteMetadata.copyright},...A.siteMetadata.themeMode&&{themeMode:A.siteMetadata.themeMode},...A.siteMetadata.analyticsScript&&{analyticsScript:A.siteMetadata.analyticsScript}},headScripts:A.buildOptions.headScripts,...A.buildOptions.staticAssets&&{staticAssets:A.buildOptions.staticAssets},getContent:async(Q,B)=>{let w=A.parsedOptions.environment==="production";return ZK1(B,Q,w,"public",{pipelineContext:A.pipelineContext,imageBuildService:A.imageBuildService,siteUrl:A.siteMetadata.url})},getViewTemplate:(Q)=>{return A.pipelineContext.services.getViewTemplate(Q)},layouts:A.parsedOptions.layouts,getSiteLayoutInfo:async()=>{return HK1(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 cLQ}from"path";async function zK1(A){let Q=A.parsedOptions.workingDir??cLQ(A.parsedOptions.outputDir,".preact-work"),B=A.staticSiteBuilderFactory({logger:A.logger.child("StaticSiteBuilder"),workingDir:Q,outputDir:A.parsedOptions.outputDir});if(A.parsedOptions.cleanBeforeBuild)await B.clean();return B}async function qK1(A){await new J5A({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 LK1(A){let Q=new Y5A(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),B=await FK1(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(B.length>0)await Q.resolveAll(B);return Q}async function VK1(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(B)=>{Q?.report(B).catch(()=>{})})}function EK1(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function MK1(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function CK1(A){let Q=XK1.parse(A.buildOptions),B=R9.from(A.progress),w=[];try{await B?.report({message:"Starting site build",progress:0,total:100}),await B?.report({message:"Generating dynamic routes",progress:10,total:100}),await qK1({pipelineContext:A.pipelineContext,publishedOnly:Q.environment==="production"});let $=await zK1({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),f=WK1(A.pipelineContext.routeRegistry);w.push(...f.warnings);let{routes:I}=f;await B?.report({message:`Building ${I.length} routes`,progress:20,total:100}),await B?.report({message:"Resolving images",progress:25,total:100});let D=await LK1({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),U=NK1({routes:I,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:D,siteMetadata:Q.siteConfig});return await VK1({staticSiteBuilder:$,buildContext:U,reporter:B}),await B?.report({message:"Site build complete",progress:100,total:100}),EK1({outputDir:Q.outputDir,routesBuilt:I.length,warnings:w})}catch($){let f=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:f,originalError:$}),MK1({outputDir:Q.outputDir,errorMessage:f.message})}}class zD{static instance=null;static defaultStaticSiteBuilderFactory=WSA;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){zD.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,B,w,$=void 0){return zD.instance??=new zD(A,zD.defaultStaticSiteBuilderFactory,Q,B,w,$),zD.instance}static resetInstance(){zD.instance=null}static createFresh(A,Q,B,w,$,f=void 0){return new zD(A,$??zD.defaultStaticSiteBuilderFactory,Q,B,w,f)}constructor(A,Q,B,w,$,f){this.pipelineContext={logger:A,services:B,routeRegistry:w,profileService:$,entityDisplay:f},this.staticSiteBuilderFactory=Q,Z7.getInstance().configure(f)}async build(A,Q){return CK1({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}WA();class HSA{config;context;pluginId;logger;debounces=new Map;unsubscribeFunctions=[];constructor(A,Q,B,w){this.config=A;this.context=Q;this.pluginId=B;this.logger=w}requestBuild(A){let Q=A??(this.config.previewOutputDir?"preview":"production"),B=this.debounces.get(Q);if(!B)B=new VL(()=>{this.enqueueBuild(Q)},this.config.rebuildDebounce),this.debounces.set(Q,B);B.trigger()}setupAutoRebuild(){let A=new Set(["note"]),Q=async(w)=>{let{entityType:$}=w.payload;if(!A.has($))this.logger.debug(`Entity type ${$} will trigger rebuild`),this.requestBuild();return{success:!0}},B=["entity:created","entity:updated","entity:deleted"];for(let w of B)this.unsubscribeFunctions.push(this.context.messaging.subscribe(w,Q));this.logger.debug(`Auto-rebuild enabled (${this.config.rebuildDebounce}ms debounce), excluding types: ${[...A].join(", ")}`)}dispose(){for(let A of this.debounces.values())A.dispose();this.debounces.clear();for(let A of this.unsubscribeFunctions)A();this.unsubscribeFunctions=[]}async enqueueBuild(A){let Q=A==="production"?this.config.productionOutputDir:this.config.previewOutputDir;this.logger.debug(`Triggering ${A} site rebuild`);try{await this.context.jobs.enqueue({type:"site-build",data:{environment:A,outputDir:Q,workingDir:this.config.workingDir,enableContentGeneration:!0,metadata:{trigger:"debounced-rebuild",timestamp:new Date().toISOString()}},options:{priority:0,source:this.pluginId,metadata:{operationType:"content_operations"},deduplication:"skip"}}),this.logger.debug("Site rebuild enqueued")}catch(B){this.logger.error("Failed to enqueue site rebuild",{error:B})}}}I5();function lLQ(A,Q){return A.map((B)=>({...B,template:B.template.includes(":")?B.template:`${Q}:${B.template}`}))}function H5A(A,Q,B){for(let w of A)B.register({...w,pluginId:Q,sections:w.sections?lLQ(w.sections,Q):[]})}function OK1(A,Q,B){A.messaging.subscribe("plugin:site-builder:route:register",async(w)=>{try{let $=Lo.parse(w.payload),{routes:f,pluginId:I}=$;return H5A(f,I,Q),{success:!0}}catch($){return B.error("Failed to register routes",{error:$}),{success:!1,error:"Failed to register routes"}}}),A.messaging.subscribe("plugin:site-builder:route:unregister",async(w)=>{try{let $=Vo.parse(w.payload),{paths:f,pluginId:I}=$;if(f)for(let D of f)Q.unregister(D);else if(I)Q.unregisterByPlugin(I);return{success:!0}}catch($){return B.error("Failed to unregister routes",{error:$}),{success:!1,error:"Failed to unregister routes"}}}),A.messaging.subscribe("plugin:site-builder:route:list",async(w)=>{try{let $=Eo.parse(w.payload);return{success:!0,data:{routes:Q.list($.pluginId?$:void 0)}}}catch($){return B.error("Failed to list routes",{error:$}),{success:!1,error:"Failed to list routes"}}}),A.messaging.subscribe("plugin:site-builder:route:get",async(w)=>{try{let $=Mo.parse(w.payload);return{success:!0,data:{route:Q.get($.path)}}}catch($){return B.error("Failed to get route",{error:$}),{success:!1,error:"Failed to get route"}}}),A.messaging.subscribe("site-builder:routes:list",async()=>{return{success:!0,data:Q.list()}})}import{promises as RK1}from"fs";import{join as bK1}from"path";async function pLQ(A,Q,B){let w=A.siteConfig.url??"https://example.com",$=Q.list(),f=JSA(w,A.environment);await RK1.writeFile(bK1(A.outputDir,"robots.txt"),f,"utf-8"),B.info(`Generated robots.txt for ${A.environment} environment`);let I=XSA($,w);await RK1.writeFile(bK1(A.outputDir,"sitemap.xml"),I,"utf-8"),B.info(`Generated sitemap.xml with ${$.length} URLs`)}function PK1(A){let{context:Q,routeRegistry:B,logger:w}=A;Q.messaging.subscribe("site:build:completed",async($)=>{try{let f=$.payload;return w.info(`Received site:build:completed event for ${f.environment} environment - generating SEO files`),await pLQ(f,B,w),{success:!0}}catch(f){return w.error("Failed to generate SEO files",f),{success:!1}}})}aA();WA();I5();var kK1=H.object({environment:H.enum(["preview","production"]).optional(),outputDir:H.string(),workingDir:H.string().optional(),enableContentGeneration:H.boolean().optional(),siteConfig:EI.optional()});I5();I5();async function fi(A,Q){try{let B=await A({type:Hx,payload:void 0});if("success"in B&&B.success&&B.data){let w=EI.safeParse(B.data);if(w.success)return EI.parse({...Q,...w.data})}}catch{}return Q}class GSA extends ZB{sendMessage;cfg;constructor(A,Q,B){super(A,{schema:kK1,jobTypeName:"site-build"});this.sendMessage=Q;this.cfg=B}async process(A,Q,B){let w=A.environment??"preview",$=A.enableContentGeneration??!1;try{this.logger.debug("Starting site build job",{jobId:Q,environment:w,outputDir:A.outputDir}),await B.report({progress:0,total:100,message:`Starting site build for ${w} environment`});let f=B.createSub({scale:{start:10,end:90}}),I=await fi(this.sendMessage,A.siteConfig??this.cfg.defaultSiteConfig),D=await this.cfg.siteBuilder.build({outputDir:A.outputDir,workingDir:A.workingDir,sharedImagesDir:this.cfg.sharedImagesDir,enableContentGeneration:$,environment:w,cleanBeforeBuild:!0,siteConfig:I,layouts:this.cfg.layouts,themeCSS:this.cfg.themeCSS,slots:this.cfg.slots,headScripts:this.cfg.getHeadScripts?.(),...this.cfg.staticAssets&&{staticAssets:this.cfg.staticAssets}},f.toCallback());if(await B.report({progress:100,total:100,message:`Site build completed: ${D.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:w,routesBuilt:D.routesBuilt,success:D.success}),D.success){this.logger.info(`Emitting site:build:completed event for ${w} environment`);let U=w==="preview"?this.cfg.previewUrl??this.cfg.siteUrl:this.cfg.siteUrl;await this.sendMessage({type:"site:build:completed",payload:{outputDir:A.outputDir,environment:w,routesBuilt:D.routesBuilt,siteConfig:{...I,url:U},generateEntityUrl:(Y,J)=>Z7.getInstance().generateUrl(Y,J)},broadcast:!0})}return{success:D.success,routesBuilt:D.routesBuilt,outputDir:A.outputDir,environment:w,...D.errors&&{errors:D.errors},...D.warnings&&{warnings:D.warnings}}}catch(f){throw this.logger.error("Site build job failed",f),f}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}WA();I5();var iLQ=H.object({slot:H.enum(RL).optional().default("primary"),limit:H.number().optional()});class KSA{routeRegistry;logger;id="site:navigation";name="Site Navigation DataSource";description="Provides navigation items for site menus";constructor(A,Q){this.routeRegistry=A;this.logger=Q;this.logger.debug("NavigationDataSource initialized")}async fetch(A,Q,B){let w=iLQ.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:w});let $=this.routeRegistry.getNavigationItems(w.slot),f=w.limit?$.slice(0,w.limit):$,I=f.map((U)=>({label:U.label,href:U.href}));this.logger.debug("NavigationDataSource returning",{slot:w.slot,itemCount:f.length,items:I});let D={navigation:I};return Q.parse(D)}}I5();aA();WA();var rLQ=H.object({environment:H.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function jK1(A,Q){return[oQ(A,"build-site","Build a static site from registered routes. Call this for every user build/rebuild request, including repeated requests like 'build it again' or 'one more build'.",rLQ,async(B)=>{return Q(B.environment),{success:!0,message:`Site build requested${B.environment?` for ${B.environment}`:""} (debounced)`,data:{}}},{cli:{name:"build"}})]}WA();I5();var _K1=H.object({previewOutputDir:H.string().describe("Output directory for preview builds").default("./dist/site-preview"),productionOutputDir:H.string().describe("Output directory for production builds").default("./dist/site-production"),sharedImagesDir:H.string().describe("Shared directory for optimized images (used by both preview and production)").default("./dist/images"),workingDir:H.string().optional().describe("Working directory for builds").default("./.preact-work"),siteInfo:EI.default({title:"Brain",description:"A knowledge management system"}),themeCSS:H.string().describe("Custom CSS theme overrides to inject into builds").optional(),analyticsScript:H.string().describe("Analytics tracking script to inject into page head (e.g., Cloudflare Web Analytics)").optional(),templates:H.any().optional().describe("Template definitions to register"),routes:H.array(bL).optional().describe("Routes to register"),layouts:H.record(H.any()).optional().describe("Layout components (at least 'default' required)"),autoRebuild:H.boolean().default(!0).describe("Automatically rebuild site when content changes"),rebuildDebounce:H.number().min(100).describe("Debounce time in ms before triggering site rebuild after content changes").default(5000),entityDisplay:H.record(H.object({label:H.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:H.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')"),layout:H.string().optional().describe("Layout name for this entity type's generated routes (defaults to 'default')"),paginate:H.boolean().optional().describe("Enable pagination for list pages"),pageSize:H.number().optional().describe("Items per page (default: 10)"),navigation:H.object({show:H.boolean().optional().describe("Show in navigation"),slot:H.enum(RL).optional().describe("Navigation slot (primary or secondary)"),priority:H.number().min(0).max(100).optional().describe("Navigation priority (0-100)")}).optional().describe("Navigation settings for this entity type")})).optional().describe("Display metadata per entity type \u2014 label, plural name, layout, pagination, navigation slot. Consulted when auto-generating routes for active entity plugins."),staticAssets:H.record(H.string()).optional().describe("Static files to write to the output directory at build time. Keys are output paths (e.g. '/canvases/tree.js'), values are file contents as strings. Typically supplied by a SitePackage via text imports.")});var vK1={name:"@brains/site-builder-plugin",private:!0,version:"0.2.0-alpha.125",description:"Static site generation plugin for Brain system",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint .",clean:"rm -rf dist"},dependencies:{"@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-engine":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*","@tailwindcss/typography":"^0.5.19",preact:"^10.27.2","preact-render-to-string":"^6.3.1"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",eslint:"^8.56.0",typescript:"^5.3.3"}};class FSA extends YB{siteBuilder;pluginContext;_routeRegistry;_slotRegistry;profileService;layouts;rebuildManager;headScripts=new Map;get routeRegistry(){if(!this._routeRegistry)throw Error("RouteRegistry not initialized - plugin not registered");return this._routeRegistry}constructor(A={}){let Q=A.layouts??{};super("site-builder",vK1,{...A,layouts:Q},_K1);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new X5A(A.logger),this._slotRegistry=new p6A,A.messaging.subscribe("plugin:site-builder:slot:register",async(B)=>{let{slotName:w,pluginId:$,render:f,priority:I}=B.payload;return this._slotRegistry?.register(w,{pluginId:$,render:f,...I!==void 0&&{priority:I}}),{success:!0}}),A.messaging.subscribe("plugin:site-builder:head-script:register",async(B)=>{let{pluginId:w,script:$}=B.payload;return this.headScripts.set(w,$),{success:!0}}),A.entities.registerDataSource(new KSA(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=G4.getInstance(A.entityService,A.logger),OK1(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)H5A(this.config.routes,this.id,this.routeRegistry);let Q={entityService:A.entityService,sendMessage:A.messaging.send,resolveTemplateContent:(B,w)=>A.templates.resolve(B,w),getViewTemplate:(B)=>A.views.get(B),listViewTemplateNames:()=>A.views.list().map((B)=>B.name)};if(this.siteBuilder=zD.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new GSA(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 HSA(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(Gx,async()=>{let B=await this.getInstructions();if(B)A.registerInstructions(B);return{success:!0}}),PK1({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 jK1(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 fi(A.messaging.send,this.config.siteInfo);return{contents:[{uri:"brain://site",mimeType:"application/json",text:JSON.stringify({...Q,domain:A.domain,siteUrl:A.siteUrl,previewUrl:A.previewUrl},null,2)}]}}},{uri:"site://routes",name:"Site Routes",description:"All registered routes with sections and templates",mimeType:"application/json",handler:async()=>{let Q=this.routeRegistry.list();return{contents:[{uri:"site://routes",mimeType:"application/json",text:JSON.stringify(Q.map((B)=>({id:B.id,path:B.path,title:B.title,description:B.description,sections:B.sections.map((w)=>({id:w.id,template:w.template}))})),null,2)}]}}},{uri:"site://templates",name:"View Templates",description:"All registered view templates",mimeType:"application/json",handler:async()=>{let Q=A.views.list();return{contents:[{uri:"site://templates",mimeType:"application/json",text:JSON.stringify(Q.map((B)=>({name:B.name,description:B.description,hasWebRenderer:!!B.renderers.web})),null,2)}]}}}]}getSiteBuilder(){return this.siteBuilder}getSlotRegistry(){return this._slotRegistry}async getInstructions(){let A=this.getContext(),Q="## Site Builder Actions\n- When the user asks to build, rebuild, publish, or build the website/site again, call `site-builder_build-site` immediately.\n- Every repeated build request requires a fresh `site-builder_build-site` call. Do not say a build was started, queued, or requested unless this turn invoked the tool.",B=await fi(A.messaging.send,this.config.siteInfo);return`## Your Site
|
|
5652
|
+
`+D;await o9.writeFile(I,Y,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=RH(process.cwd(),"public");try{await o9.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await o9.readdir(A,{withFileTypes:!0});for(let B of Q){let w=RH(A,B.name),$=RH(this.outputDir,B.name);if(B.isDirectory())await this.copyDirectory(w,$);else await o9.copyFile(w,$),this.logger.debug(`Copied static asset: ${B.name}`)}this.logger.debug("Static assets copied successfully")}async writeInlineStaticAssets(A){if(!A)return;let Q=Object.entries(A);if(Q.length===0)return;this.logger.debug(`Writing ${Q.length} inline static asset(s) from SitePackage`),await Promise.all(Q.map(async([B,w])=>{let $=B.startsWith("/")?B.slice(1):B,f=RH(this.outputDir,$);await o9.mkdir(SLQ(f),{recursive:!0}),await o9.writeFile(f,w,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await o9.mkdir(Q,{recursive:!0});let B=await o9.readdir(A,{withFileTypes:!0});for(let w of B){let $=RH(A,w.name),f=RH(Q,w.name);if(w.isDirectory())await this.copyDirectory($,f);else await o9.copyFile($,f)}}}function WSA(A){return new JK1(A)}I5();WA();WA();I5();var XK1=H.object({environment:H.enum(["preview","production"]),outputDir:H.string(),workingDir:H.string().optional(),sharedImagesDir:H.string().default("./dist/images"),enableContentGeneration:H.boolean().default(!1),cleanBeforeBuild:H.boolean().default(!0),siteConfig:EI,layouts:H.record(H.any()),themeCSS:H.string().optional()}),Ohw=H.object({success:H.boolean(),outputDir:H.string(),filesGenerated:H.number(),routesBuilt:H.number(),errors:H.array(H.string()).optional(),warnings:H.array(H.string()).optional()});function WK1(A){let Q=A.list(),B=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:B}}function HK1(A,Q,B){let w=Q.getProfile(),$=B.getNavigationItems("primary"),f=B.getNavigationItems("secondary");return{...A,...w.socialLinks!==void 0&&{socialLinks:w.socialLinks},navigation:{primary:$,secondary:f},copyright:A.copyright??"Powered by Rizom"}}I5();C7();I5();WA();var gLQ=H.object({id:H.string(),entityType:H.string(),content:H.string(),metadata:H.object({slug:H.string()}).passthrough()}).passthrough(),hLQ=H.object({content:H.string(),metadata:H.object({width:H.number().optional(),height:H.number().optional()}).passthrough()});async function W5A(A,Q){let B=Q.urlGenerator??Z7.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((S)=>W5A(S,{...Q,urlGenerator:B})));if(typeof A!=="object")return A;let w={},$=Object.entries(A),f=await Promise.all($.map(([,S])=>W5A(S,{...Q,urlGenerator:B})));for(let S=0;S<$.length;S++){let T=$[S];if(T)w[T[0]]=f[S]}let I=gLQ.safeParse(A);if(!I.success)return w;let D=I.data,U=D.entityType,Y=D.metadata.slug,J=Q.pipelineContext.entityDisplay?.[U],X=J?J.label:U.charAt(0).toUpperCase()+U.slice(1),G=J?J.pluralName??J.label.toLowerCase()+"s":LI(U),Z=`/${G}`,N=G.charAt(0).toUpperCase()+G.slice(1),V=qg(D),L=await mLQ(V,Q),M=Tt(D)??V,O=await uLQ(M,Q);return{...w,...D,url:B.generateUrl(U,Y),typeLabel:X,listUrl:Z,listLabel:N,...L,...O&&{ogImageUrl:O}}}async function mLQ(A,Q){let B=A?Q.imageBuildService?.get(A):void 0;if(B)return{coverImageUrl:B.src,coverImageWidth:B.width,coverImageHeight:B.height,...B.srcset&&{coverImageSrcset:B.srcset,coverImageSizes:B.sizes}};let w=await KK1(A,Q.pipelineContext.services.entityService);if(!w)return{};return{coverImageUrl:w.url,...w.width&&{coverImageWidth:w.width},...w.height&&{coverImageHeight:w.height}}}async function uLQ(A,Q){if(!A)return;let B=Q.imageBuildService?.get(A);if(B)return GK1(B.src,Q.siteUrl);let w=await KK1(A,Q.pipelineContext.services.entityService);if(!w)return;if(w.url.startsWith("data:"))return;return GK1(w.url,Q.siteUrl)}function GK1(A,Q){if(/^https?:\/\//i.test(A)||A.startsWith("data:"))return A;if(!Q)return A;return`${Q.replace(/\/$/,"")}/${A.replace(/^\//,"")}`}async function KK1(A,Q){if(!A)return;let B=await Q.getEntity({entityType:"image",id:A}),w=hLQ.safeParse(B);if(!w.success)return;return{url:w.data.content,...w.data.metadata.width&&{width:w.data.metadata.width},...w.data.metadata.height&&{height:w.data.metadata.height}}}async function FK1(A,Q){let B=new Set;try{let w=A.getEntityTypes();for(let $ of w){if($==="image")continue;let f=await A.listEntities({entityType:$});for(let I of f){let D=qg(I);if(D)B.add(D);let U=Tt(I);if(U)B.add(U)}}}catch(w){Q.warn("Failed to collect image IDs for pre-resolution",{error:y0(w)})}return[...B]}async function ZK1(A,Q,B,w,$){if(!A.template)return A.content??null;let f=A.template,I=A.dataQuery?{dataParams:A.dataQuery,fallback:A.content,publishedOnly:B,visibilityScope:w}:{savedContent:{entityType:"site-content",entityId:`${Q.id}:${A.id}`},fallback:A.content,visibilityScope:w},D=await $.pipelineContext.services.resolveTemplateContent(f,I);if(!D)return null;return W5A(D,{pipelineContext:$.pipelineContext,imageBuildService:$.imageBuildService,siteUrl:$.siteUrl,urlGenerator:Z7.getInstance()})}function NK1(A){return{routes:A.routes,siteConfig:{title:A.siteMetadata.title,description:A.siteMetadata.description,...A.siteMetadata.url&&{url:A.siteMetadata.url},...A.siteMetadata.copyright&&{copyright:A.siteMetadata.copyright},...A.siteMetadata.themeMode&&{themeMode:A.siteMetadata.themeMode},...A.siteMetadata.analyticsScript&&{analyticsScript:A.siteMetadata.analyticsScript}},headScripts:A.buildOptions.headScripts,...A.buildOptions.staticAssets&&{staticAssets:A.buildOptions.staticAssets},getContent:async(Q,B)=>{let w=A.parsedOptions.environment==="production";return ZK1(B,Q,w,"public",{pipelineContext:A.pipelineContext,imageBuildService:A.imageBuildService,siteUrl:A.siteMetadata.url})},getViewTemplate:(Q)=>{return A.pipelineContext.services.getViewTemplate(Q)},layouts:A.parsedOptions.layouts,getSiteLayoutInfo:async()=>{return HK1(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 cLQ}from"path";async function zK1(A){let Q=A.parsedOptions.workingDir??cLQ(A.parsedOptions.outputDir,".preact-work"),B=A.staticSiteBuilderFactory({logger:A.logger.child("StaticSiteBuilder"),workingDir:Q,outputDir:A.parsedOptions.outputDir});if(A.parsedOptions.cleanBeforeBuild)await B.clean();return B}async function qK1(A){await new J5A({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 LK1(A){let Q=new Y5A(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),B=await FK1(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(B.length>0)await Q.resolveAll(B);return Q}async function VK1(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(B)=>{Q?.report(B).catch(()=>{})})}function EK1(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function MK1(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function CK1(A){let Q=XK1.parse(A.buildOptions),B=R9.from(A.progress),w=[];try{await B?.report({message:"Starting site build",progress:0,total:100}),await B?.report({message:"Generating dynamic routes",progress:10,total:100}),await qK1({pipelineContext:A.pipelineContext,publishedOnly:Q.environment==="production"});let $=await zK1({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),f=WK1(A.pipelineContext.routeRegistry);w.push(...f.warnings);let{routes:I}=f;await B?.report({message:`Building ${I.length} routes`,progress:20,total:100}),await B?.report({message:"Resolving images",progress:25,total:100});let D=await LK1({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),U=NK1({routes:I,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:D,siteMetadata:Q.siteConfig});return await VK1({staticSiteBuilder:$,buildContext:U,reporter:B}),await B?.report({message:"Site build complete",progress:100,total:100}),EK1({outputDir:Q.outputDir,routesBuilt:I.length,warnings:w})}catch($){let f=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:f,originalError:$}),MK1({outputDir:Q.outputDir,errorMessage:f.message})}}class zD{static instance=null;static defaultStaticSiteBuilderFactory=WSA;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){zD.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,B,w,$=void 0){return zD.instance??=new zD(A,zD.defaultStaticSiteBuilderFactory,Q,B,w,$),zD.instance}static resetInstance(){zD.instance=null}static createFresh(A,Q,B,w,$,f=void 0){return new zD(A,$??zD.defaultStaticSiteBuilderFactory,Q,B,w,f)}constructor(A,Q,B,w,$,f){this.pipelineContext={logger:A,services:B,routeRegistry:w,profileService:$,entityDisplay:f},this.staticSiteBuilderFactory=Q,Z7.getInstance().configure(f)}async build(A,Q){return CK1({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}WA();class HSA{config;context;pluginId;logger;debounces=new Map;unsubscribeFunctions=[];constructor(A,Q,B,w){this.config=A;this.context=Q;this.pluginId=B;this.logger=w}requestBuild(A){let Q=A??(this.config.previewOutputDir?"preview":"production"),B=this.debounces.get(Q);if(!B)B=new VL(()=>{this.enqueueBuild(Q)},this.config.rebuildDebounce),this.debounces.set(Q,B);B.trigger()}setupAutoRebuild(){let A=new Set(["note"]),Q=async(w)=>{let{entityType:$}=w.payload;if(!A.has($))this.logger.debug(`Entity type ${$} will trigger rebuild`),this.requestBuild();return{success:!0}},B=["entity:created","entity:updated","entity:deleted"];for(let w of B)this.unsubscribeFunctions.push(this.context.messaging.subscribe(w,Q));this.logger.debug(`Auto-rebuild enabled (${this.config.rebuildDebounce}ms debounce), excluding types: ${[...A].join(", ")}`)}dispose(){for(let A of this.debounces.values())A.dispose();this.debounces.clear();for(let A of this.unsubscribeFunctions)A();this.unsubscribeFunctions=[]}async enqueueBuild(A){let Q=A==="production"?this.config.productionOutputDir:this.config.previewOutputDir;this.logger.debug(`Triggering ${A} site rebuild`);try{await this.context.jobs.enqueue({type:"site-build",data:{environment:A,outputDir:Q,workingDir:this.config.workingDir,enableContentGeneration:!0,metadata:{trigger:"debounced-rebuild",timestamp:new Date().toISOString()}},options:{priority:0,source:this.pluginId,metadata:{operationType:"content_operations"},deduplication:"skip"}}),this.logger.debug("Site rebuild enqueued")}catch(B){this.logger.error("Failed to enqueue site rebuild",{error:B})}}}I5();function lLQ(A,Q){return A.map((B)=>({...B,template:B.template.includes(":")?B.template:`${Q}:${B.template}`}))}function H5A(A,Q,B){for(let w of A)B.register({...w,pluginId:Q,sections:w.sections?lLQ(w.sections,Q):[]})}function OK1(A,Q,B){A.messaging.subscribe("plugin:site-builder:route:register",async(w)=>{try{let $=Lo.parse(w.payload),{routes:f,pluginId:I}=$;return H5A(f,I,Q),{success:!0}}catch($){return B.error("Failed to register routes",{error:$}),{success:!1,error:"Failed to register routes"}}}),A.messaging.subscribe("plugin:site-builder:route:unregister",async(w)=>{try{let $=Vo.parse(w.payload),{paths:f,pluginId:I}=$;if(f)for(let D of f)Q.unregister(D);else if(I)Q.unregisterByPlugin(I);return{success:!0}}catch($){return B.error("Failed to unregister routes",{error:$}),{success:!1,error:"Failed to unregister routes"}}}),A.messaging.subscribe("plugin:site-builder:route:list",async(w)=>{try{let $=Eo.parse(w.payload);return{success:!0,data:{routes:Q.list($.pluginId?$:void 0)}}}catch($){return B.error("Failed to list routes",{error:$}),{success:!1,error:"Failed to list routes"}}}),A.messaging.subscribe("plugin:site-builder:route:get",async(w)=>{try{let $=Mo.parse(w.payload);return{success:!0,data:{route:Q.get($.path)}}}catch($){return B.error("Failed to get route",{error:$}),{success:!1,error:"Failed to get route"}}}),A.messaging.subscribe("site-builder:routes:list",async()=>{return{success:!0,data:Q.list()}})}import{promises as RK1}from"fs";import{join as bK1}from"path";async function pLQ(A,Q,B){let w=A.siteConfig.url??"https://example.com",$=Q.list(),f=JSA(w,A.environment);await RK1.writeFile(bK1(A.outputDir,"robots.txt"),f,"utf-8"),B.info(`Generated robots.txt for ${A.environment} environment`);let I=XSA($,w);await RK1.writeFile(bK1(A.outputDir,"sitemap.xml"),I,"utf-8"),B.info(`Generated sitemap.xml with ${$.length} URLs`)}function PK1(A){let{context:Q,routeRegistry:B,logger:w}=A;Q.messaging.subscribe("site:build:completed",async($)=>{try{let f=$.payload;return w.info(`Received site:build:completed event for ${f.environment} environment - generating SEO files`),await pLQ(f,B,w),{success:!0}}catch(f){return w.error("Failed to generate SEO files",f),{success:!1}}})}aA();WA();I5();var kK1=H.object({environment:H.enum(["preview","production"]).optional(),outputDir:H.string(),workingDir:H.string().optional(),enableContentGeneration:H.boolean().optional(),siteConfig:EI.optional()});I5();I5();async function fi(A,Q){try{let B=await A({type:Hx,payload:void 0});if("success"in B&&B.success&&B.data){let w=EI.safeParse(B.data);if(w.success)return EI.parse({...Q,...w.data})}}catch{}return Q}class GSA extends ZB{sendMessage;cfg;constructor(A,Q,B){super(A,{schema:kK1,jobTypeName:"site-build"});this.sendMessage=Q;this.cfg=B}async process(A,Q,B){let w=A.environment??"preview",$=A.enableContentGeneration??!1;try{this.logger.debug("Starting site build job",{jobId:Q,environment:w,outputDir:A.outputDir}),await B.report({progress:0,total:100,message:`Starting site build for ${w} environment`});let f=B.createSub({scale:{start:10,end:90}}),I=await fi(this.sendMessage,A.siteConfig??this.cfg.defaultSiteConfig),D=await this.cfg.siteBuilder.build({outputDir:A.outputDir,workingDir:A.workingDir,sharedImagesDir:this.cfg.sharedImagesDir,enableContentGeneration:$,environment:w,cleanBeforeBuild:!0,siteConfig:I,layouts:this.cfg.layouts,themeCSS:this.cfg.themeCSS,slots:this.cfg.slots,headScripts:this.cfg.getHeadScripts?.(),...this.cfg.staticAssets&&{staticAssets:this.cfg.staticAssets}},f.toCallback());if(await B.report({progress:100,total:100,message:`Site build completed: ${D.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:w,routesBuilt:D.routesBuilt,success:D.success}),D.success){this.logger.info(`Emitting site:build:completed event for ${w} environment`);let U=w==="preview"?this.cfg.previewUrl??this.cfg.siteUrl:this.cfg.siteUrl;await this.sendMessage({type:"site:build:completed",payload:{outputDir:A.outputDir,environment:w,routesBuilt:D.routesBuilt,siteConfig:{...I,url:U},generateEntityUrl:(Y,J)=>Z7.getInstance().generateUrl(Y,J)},broadcast:!0})}return{success:D.success,routesBuilt:D.routesBuilt,outputDir:A.outputDir,environment:w,...D.errors&&{errors:D.errors},...D.warnings&&{warnings:D.warnings}}}catch(f){throw this.logger.error("Site build job failed",f),f}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}WA();I5();var iLQ=H.object({slot:H.enum(RL).optional().default("primary"),limit:H.number().optional()});class KSA{routeRegistry;logger;id="site:navigation";name="Site Navigation DataSource";description="Provides navigation items for site menus";constructor(A,Q){this.routeRegistry=A;this.logger=Q;this.logger.debug("NavigationDataSource initialized")}async fetch(A,Q,B){let w=iLQ.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:w});let $=this.routeRegistry.getNavigationItems(w.slot),f=w.limit?$.slice(0,w.limit):$,I=f.map((U)=>({label:U.label,href:U.href}));this.logger.debug("NavigationDataSource returning",{slot:w.slot,itemCount:f.length,items:I});let D={navigation:I};return Q.parse(D)}}I5();aA();WA();var rLQ=H.object({environment:H.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function jK1(A,Q){return[oQ(A,"build-site","Build a static site from registered routes. Call this for every user build/rebuild request, including repeated requests like 'build it again' or 'one more build'.",rLQ,async(B)=>{return Q(B.environment),{success:!0,message:`Site build requested${B.environment?` for ${B.environment}`:""} (debounced)`,data:{}}},{cli:{name:"build"}})]}WA();I5();var _K1=H.object({previewOutputDir:H.string().describe("Output directory for preview builds").default("./dist/site-preview"),productionOutputDir:H.string().describe("Output directory for production builds").default("./dist/site-production"),sharedImagesDir:H.string().describe("Shared directory for optimized images (used by both preview and production)").default("./dist/images"),workingDir:H.string().optional().describe("Working directory for builds").default("./.preact-work"),siteInfo:EI.default({title:"Brain",description:"A knowledge management system"}),themeCSS:H.string().describe("Custom CSS theme overrides to inject into builds").optional(),analyticsScript:H.string().describe("Analytics tracking script to inject into page head (e.g., Cloudflare Web Analytics)").optional(),templates:H.any().optional().describe("Template definitions to register"),routes:H.array(bL).optional().describe("Routes to register"),layouts:H.record(H.any()).optional().describe("Layout components (at least 'default' required)"),autoRebuild:H.boolean().default(!0).describe("Automatically rebuild site when content changes"),rebuildDebounce:H.number().min(100).describe("Debounce time in ms before triggering site rebuild after content changes").default(5000),entityDisplay:H.record(H.object({label:H.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:H.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')"),layout:H.string().optional().describe("Layout name for this entity type's generated routes (defaults to 'default')"),paginate:H.boolean().optional().describe("Enable pagination for list pages"),pageSize:H.number().optional().describe("Items per page (default: 10)"),navigation:H.object({show:H.boolean().optional().describe("Show in navigation"),slot:H.enum(RL).optional().describe("Navigation slot (primary or secondary)"),priority:H.number().min(0).max(100).optional().describe("Navigation priority (0-100)")}).optional().describe("Navigation settings for this entity type")})).optional().describe("Display metadata per entity type \u2014 label, plural name, layout, pagination, navigation slot. Consulted when auto-generating routes for active entity plugins."),staticAssets:H.record(H.string()).optional().describe("Static files to write to the output directory at build time. Keys are output paths (e.g. '/canvases/tree.js'), values are file contents as strings. Typically supplied by a SitePackage via text imports.")});var vK1={name:"@brains/site-builder-plugin",private:!0,version:"0.2.0-alpha.127",description:"Static site generation plugin for Brain system",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint .",clean:"rm -rf dist"},dependencies:{"@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-engine":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*","@tailwindcss/typography":"^0.5.19",preact:"^10.27.2","preact-render-to-string":"^6.3.1"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",eslint:"^8.56.0",typescript:"^5.3.3"}};class FSA extends YB{siteBuilder;pluginContext;_routeRegistry;_slotRegistry;profileService;layouts;rebuildManager;headScripts=new Map;get routeRegistry(){if(!this._routeRegistry)throw Error("RouteRegistry not initialized - plugin not registered");return this._routeRegistry}constructor(A={}){let Q=A.layouts??{};super("site-builder",vK1,{...A,layouts:Q},_K1);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new X5A(A.logger),this._slotRegistry=new p6A,A.messaging.subscribe("plugin:site-builder:slot:register",async(B)=>{let{slotName:w,pluginId:$,render:f,priority:I}=B.payload;return this._slotRegistry?.register(w,{pluginId:$,render:f,...I!==void 0&&{priority:I}}),{success:!0}}),A.messaging.subscribe("plugin:site-builder:head-script:register",async(B)=>{let{pluginId:w,script:$}=B.payload;return this.headScripts.set(w,$),{success:!0}}),A.entities.registerDataSource(new KSA(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=G4.getInstance(A.entityService,A.logger),OK1(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)H5A(this.config.routes,this.id,this.routeRegistry);let Q={entityService:A.entityService,sendMessage:A.messaging.send,resolveTemplateContent:(B,w)=>A.templates.resolve(B,w),getViewTemplate:(B)=>A.views.get(B),listViewTemplateNames:()=>A.views.list().map((B)=>B.name)};if(this.siteBuilder=zD.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new GSA(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 HSA(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(Gx,async()=>{let B=await this.getInstructions();if(B)A.registerInstructions(B);return{success:!0}}),PK1({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 jK1(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 fi(A.messaging.send,this.config.siteInfo);return{contents:[{uri:"brain://site",mimeType:"application/json",text:JSON.stringify({...Q,domain:A.domain,siteUrl:A.siteUrl,previewUrl:A.previewUrl},null,2)}]}}},{uri:"site://routes",name:"Site Routes",description:"All registered routes with sections and templates",mimeType:"application/json",handler:async()=>{let Q=this.routeRegistry.list();return{contents:[{uri:"site://routes",mimeType:"application/json",text:JSON.stringify(Q.map((B)=>({id:B.id,path:B.path,title:B.title,description:B.description,sections:B.sections.map((w)=>({id:w.id,template:w.template}))})),null,2)}]}}},{uri:"site://templates",name:"View Templates",description:"All registered view templates",mimeType:"application/json",handler:async()=>{let Q=A.views.list();return{contents:[{uri:"site://templates",mimeType:"application/json",text:JSON.stringify(Q.map((B)=>({name:B.name,description:B.description,hasWebRenderer:!!B.renderers.web})),null,2)}]}}}]}getSiteBuilder(){return this.siteBuilder}getSlotRegistry(){return this._slotRegistry}async getInstructions(){let A=this.getContext(),Q="## Site Builder Actions\n- When the user asks to build, rebuild, publish, or build the website/site again, call `site-builder_build-site` immediately.\n- Every repeated build request requires a fresh `site-builder_build-site` call. Do not say a build was started, queued, or requested unless this turn invoked the tool.",B=await fi(A.messaging.send,this.config.siteInfo);return`## Your Site
|
|
5653
5653
|
${[`**Title:** ${B.title}`,`**Description:** ${B.description}`,A.domain&&`**Domain:** ${A.domain}`,A.siteUrl&&`**URL:** ${A.siteUrl}`].filter(Boolean).join(`
|
|
5654
5654
|
`)}
|
|
5655
5655
|
|
|
5656
5656
|
## Site Builder Actions
|
|
5657
5657
|
- When the user asks to build, rebuild, publish, or build the website/site again, call \`site-builder_build-site\` immediately.
|
|
5658
|
-
- 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(),zD.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function fC(A={}){return new FSA(A)}aA();I5();WA();aA();I5();var yK1=H.object({}),Ii=A2.extend({id:H.literal("site-info"),entityType:H.literal("site-info"),metadata:yK1}),ZSA=Oo,Nv=EI.omit({url:!0,analyticsScript:!0});aA();class bH extends q2{constructor(){super({entityType:"site-info",schema:Ii,frontmatterSchema:Nv,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=Nv.parse(A);return this.buildMarkdown("",Q)}parseSiteInfoBody(A){return this.parseFrontmatter(A)}fromMarkdown(A){return{content:A,entityType:"site-info"}}extractMetadata(A){return{}}generateFrontMatter(A){let Q=this.parseFrontmatter(A.content);return this.buildMarkdown("",Q)}}class PH{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,B){return PH.instance??=new PH(A,Q,B),PH.instance}static resetInstance(){PH.instance=null}static createFresh(A,Q,B){return new PH(A,Q,B)}constructor(A,Q,B){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new bH;let w=PH.getDefaultSiteInfo();this.defaultSiteInfo={...w,...B}}async initialize(){try{if(!await this.entityService.getEntity({entityType:"site-info",id:"site-info"})){if(await this.entityService.getEntity({entityType:"site-info",id:"site-info"}))return;this.logger.info("No site info found, creating default site info");let B=this.adapter.createSiteInfoContent(this.defaultSiteInfo);await this.entityService.createEntity({entity:{id:"site-info",entityType:"site-info",content:B,metadata:{}}}),this.logger.info("Default site info created successfully")}}catch(A){this.logger.error("Failed to initialize site info",{error:A})}}async getSiteInfo(){try{let A=await this.entityService.getEntity({entityType:"site-info",id:"site-info"});if(A)return this.adapter.parseSiteInfoBody(A.content)}catch(A){this.logger.debug("Site info not found, using defaults",{error:A})}return this.defaultSiteInfo}}var nLQ=new bH;class G5A{logger;id="site-info:entities";name="Site Info DataSource";description="Provides site metadata (title, description, CTA) and profile social links";constructor(A){this.logger=A}async fetch(A,Q,B){let{entityService:w}=B,$;try{let D=await w.getEntity({entityType:"site-info",id:"site-info"});$=D?nLQ.parseSiteInfoBody(D.content):{title:"Brain",description:"A knowledge management system"}}catch{$={title:"Brain",description:"A knowledge management system"}}let f;try{let D=await w.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(D)f=D.metadata.socialLinks}catch{}let I={...$,socialLinks:f,copyright:$.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:I.title,hasSocialLinks:!!I.socialLinks}),Q.parse(I)}}var TK1={name:"@brains/site-info",private:!0,version:"0.2.0-alpha.125",description:"Site info entity \u2014 site metadata, title, description, CTA",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/entity-service":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var sLQ=new bH;class NSA extends _Q{entityType="site-info";schema=Ii;adapter=sLQ;defaultSiteInfo;constructor(A){super("site-info",TK1);this.defaultSiteInfo=A?.siteInfo??{}}getEntityTypeConfig(){return{embeddable:!1}}getDataSources(){return[new G5A(this.logger.child("SiteInfoDataSource"))]}async onRegister(A){let Q=PH.createFresh(A.entityService,this.logger,this.defaultSiteInfo);A.messaging.subscribe(Hx,async()=>{return{success:!0,data:await Q.getSiteInfo()}}),A.messaging.subscribe("entity:updated",async(B)=>{if(B.payload.entityType==="site-info"){let $=await Q.getSiteInfo();await A.messaging.send({type:Gx,payload:$,broadcast:!0})}return{success:!0}}),A.messaging.subscribe("sync:initial:completed",async()=>{return await Q.initialize(),{success:!0}})}}function IC(A){return new NSA(A)}var aLQ=new bH;async function Di(A){let B=(await A.listEntities({entityType:"site-info",options:{limit:1}}))[0];if(!B)throw Error("Site info not found \u2014 create a site-info entity");return aLQ.parseSiteInfoBody(B.content)}WA();var tLQ=Nv.extend({navigation:H.object({primary:H.array(H.object({label:H.string(),href:H.string(),priority:H.number()})),secondary:H.array(H.object({label:H.string(),href:H.string(),priority:H.number()}))}),copyright:H.string(),socialLinks:H.array(H.object({platform:H.enum(["github","instagram","linkedin","email","website"]).describe("Social media platform"),url:H.string().describe("Profile or contact URL"),label:H.string().optional().describe("Optional display label")})).optional().describe("Social media links from profile entity")});aA();WA();var xK1={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 SK1={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 gK1={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 hK1={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 mK1={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 uK1={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 cK1={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 lK1={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 pK1={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 UVQ=H.object({type:H.string()}).catchall(H.unknown()),YVQ=H.object({lexicon:H.literal(1),id:H.string(),defs:H.object({main:H.object({type:H.literal("record"),key:H.string().min(1),record:H.object({type:H.literal("object"),required:H.array(H.string()).optional(),properties:H.record(UVQ)})})})});function kH(A){return YVQ.parse(A)}var Kw={"ai.rizom.brain.card":kH(xK1),"ai.rizom.brain.deck":kH(SK1),"ai.rizom.brain.link":kH(gK1),"ai.rizom.brain.note":kH(hK1),"ai.rizom.brain.post":kH(mK1),"ai.rizom.brain.project":kH(uK1),"ai.rizom.brain.series":kH(cK1),"ai.rizom.brain.socialPost":kH(lK1),"ai.rizom.brain.topic":kH(pK1)},JVQ="Additive optional fields are compatible; required-field, type, or constraint changes require a migration plan or new NSID.";function cF(A){return{status:"approved",version:"1.0.0",revision:1,owner:"Rizom",steward:"Rizom protocol registry",projectionPackage:A,compatibility:JVQ}}var XVQ={"ai.rizom.brain.card":cF("@brains/atproto"),"ai.rizom.brain.deck":cF("@brains/decks"),"ai.rizom.brain.link":cF("@brains/link"),"ai.rizom.brain.note":cF("@brains/note"),"ai.rizom.brain.post":cF("@brains/blog"),"ai.rizom.brain.project":cF("@brains/portfolio"),"ai.rizom.brain.series":cF("@brains/series"),"ai.rizom.brain.socialPost":cF("@brains/social-media"),"ai.rizom.brain.topic":cF("@brains/topics")};function DC(){return Object.values(Kw)}function LSA(A){return Kw[A]}function VSA(){return Object.entries(XVQ).map(([A,Q])=>({id:A,...Q}))}function qSA(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}var WVQ=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;function HVQ(A){let Q=H.string(),B=A.maxLength!==void 0?Q.max(A.maxLength):Q;if(A.knownValues)B=B.refine((w)=>A.knownValues?.includes(w),{message:`expected one of ${A.knownValues.join(", ")}`});if(A.format==="datetime")B=B.refine((w)=>WVQ.test(w)&&!Number.isNaN(Date.parse(w)),{message:"expected datetime"});if(A.format==="uri")B=B.refine((w)=>{try{return new URL(w),!0}catch{return!1}},{message:"expected uri"});return B}function iK1(A){switch(A.type){case"string":return HVQ(A);case"integer":return H.number().int();case"boolean":return H.boolean();case"array":{let Q=A.items?iK1(A.items):H.unknown(),B=H.array(Q);if(A.maxLength!==void 0)B=B.max(A.maxLength);return B}case"object":return GVQ(A);case"blob":return H.custom(qSA,{message:"expected blob"});default:return H.unknown()}}function rK1(A){let Q=new Set(A.required??[]),B={};for(let[w,$]of Object.entries(A.properties??{})){let f=iK1($);B[w]=Q.has(w)?f:f.optional()}return B}function GVQ(A){return H.object(rK1(A)).passthrough()}function zSA(A,Q,B,w=[]){let $=Object.keys(A).filter((f)=>!Q.has(f));if($.length===0)return;B.addIssue({code:H.ZodIssueCode.custom,path:w,message:`unrecognized field(s): ${$.join(", ")}`})}function KVQ(A,Q){if(zSA(A,new Set(["$type","siteUrl","brain","anchor","skills","model","version","createdAt","updatedAt"]),Q),qSA(A.brain))zSA(A.brain,new Set(["did","name","role","purpose","values"]),Q,["brain"]);if(qSA(A.anchor))zSA(A.anchor,new Set(["did","name","kind"]),Q,["anchor"])}function jH(A){let Q=H.object({...rK1(A.defs.main.record),$type:H.literal(A.id).optional()}).passthrough();return A.id==="ai.rizom.brain.card"?Q.superRefine(KVQ):Q}var FVQ={"ai.rizom.brain.card":jH(Kw["ai.rizom.brain.card"]),"ai.rizom.brain.deck":jH(Kw["ai.rizom.brain.deck"]),"ai.rizom.brain.link":jH(Kw["ai.rizom.brain.link"]),"ai.rizom.brain.note":jH(Kw["ai.rizom.brain.note"]),"ai.rizom.brain.post":jH(Kw["ai.rizom.brain.post"]),"ai.rizom.brain.project":jH(Kw["ai.rizom.brain.project"]),"ai.rizom.brain.series":jH(Kw["ai.rizom.brain.series"]),"ai.rizom.brain.socialPost":jH(Kw["ai.rizom.brain.socialPost"]),"ai.rizom.brain.topic":jH(Kw["ai.rizom.brain.topic"])};function ZVQ(A,Q,B){let w=B.path.join(".");if(w==="$type")return`AT Protocol record $type must match lexicon id: ${String(Q.$type)} !== ${A.id}`;if(B.code==="invalid_type"&&B.received==="undefined")return`Missing required AT Protocol record field: ${w}`;if(B.code==="invalid_type")return`Invalid AT Protocol record field ${w}: expected ${B.expected}`;if(B.code==="too_big")return`Invalid AT Protocol record field ${w}: exceeds maxLength ${B.maximum}`;if(B.code==="custom")return`Invalid AT Protocol record field ${w}: ${B.message}`;if(B.code==="unrecognized_keys")return`Unrecognized AT Protocol record field(s): ${B.keys.join(", ")}`;return`Invalid AT Protocol record field ${w}: ${B.message}`}function cz(A,Q){let B=jH(A).safeParse(Q);if(B.success)return;let w=B.error.issues[0];if(!w)throw B.error;throw Error(ZVQ(A,Q,w))}var K5A="atproto:brain-card-discovered",dK1="atproto:brain-discovered",nK1="atproto:brain-card-refreshed",oK1=H.object({repoDid:H.string().min(1),uri:H.string().min(1),cid:H.string().min(1),record:FVQ["ai.rizom.brain.card"]}).strict(),Bcw=H.object({agentId:H.string().min(1),name:H.string().min(1),url:H.string().url(),status:H.enum(["discovered","approved"]),repoDid:H.string().min(1).optional(),brainDid:H.string().min(1).optional(),anchorDid:H.string().min(1).optional(),cardUri:H.string().min(1).optional(),cardCid:H.string().min(1).optional()}).strict();class o6{static instance;projections=new Map;registrationCounts=new Map;static getInstance(){return this.instance??=new o6,this.instance}static createFresh(){return new o6}static resetInstance(){this.instance=void 0}register(A){this.validateProjection(A);let Q=this.projections.get(A.entityType);if(Q){if(!this.isEquivalentProjection(Q,A))throw Error(`AT Protocol projection already registered for entity type ${A.entityType}`);return this.registrationCounts.set(A.entityType,(this.registrationCounts.get(A.entityType)??1)+1),this.createUnregister(A.entityType)}return this.projections.set(A.entityType,A),this.registrationCounts.set(A.entityType,1),this.createUnregister(A.entityType)}get(A){return this.projections.get(A)}has(A){return this.projections.has(A)}list(){return Array.from(this.projections.values())}listLexicons(){return this.list().map((A)=>A.lexicon)}createUnregister(A){let Q=!0;return()=>{if(!Q)return;Q=!1;let B=this.registrationCounts.get(A)??0;if(B<=1){this.registrationCounts.delete(A),this.projections.delete(A);return}this.registrationCounts.set(A,B-1)}}isEquivalentProjection(A,Q){return A.entityType===Q.entityType&&A.collection===Q.collection&&A.lexicon.id===Q.lexicon.id&&A.validate===Q.validate}validateProjection(A){if(A.collection!==A.lexicon.id)throw Error(`AT Protocol projection collection must match lexicon id: ${A.collection} !== ${A.lexicon.id}`);if(!A.lexicon.defs.main.key)throw Error(`AT Protocol projection lexicon must define a record key: ${A.collection}`)}}qD();qv();WA();var ESA=H.object({defaultPrompt:H.string().default("Write a blog post about my recent work and insights"),paginate:H.boolean().default(!0),pageSize:H.number().default(10)});aA();WA();o8();var qVQ=H.object({prompt:H.string().optional(),title:H.string().optional(),content:H.string().optional(),excerpt:H.string().optional(),coverImageId:H.string().optional(),seriesName:H.string().optional(),seriesIndex:H.number().optional(),skipAi:H.boolean().optional()}),Kcw=VI.extend({title:H.string().optional(),slug:H.string().optional()});class MSA extends L7{constructor(A,Q){super(A,Q,{schema:qVQ,jobTypeName:"blog-generation",entityType:"post"})}async generate(A,Q){let{prompt:B,coverImageId:w,seriesName:$,seriesIndex:f,skipAi:I}=A,{title:D,content:U,excerpt:Y}=A;if(I){if(!D)this.failEarly("Title is required when skipAi is true");U=U??`## Introduction
|
|
5658
|
+
- 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(),zD.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function fC(A={}){return new FSA(A)}aA();I5();WA();aA();I5();var yK1=H.object({}),Ii=A2.extend({id:H.literal("site-info"),entityType:H.literal("site-info"),metadata:yK1}),ZSA=Oo,Nv=EI.omit({url:!0,analyticsScript:!0});aA();class bH extends q2{constructor(){super({entityType:"site-info",schema:Ii,frontmatterSchema:Nv,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=Nv.parse(A);return this.buildMarkdown("",Q)}parseSiteInfoBody(A){return this.parseFrontmatter(A)}fromMarkdown(A){return{content:A,entityType:"site-info"}}extractMetadata(A){return{}}generateFrontMatter(A){let Q=this.parseFrontmatter(A.content);return this.buildMarkdown("",Q)}}class PH{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,B){return PH.instance??=new PH(A,Q,B),PH.instance}static resetInstance(){PH.instance=null}static createFresh(A,Q,B){return new PH(A,Q,B)}constructor(A,Q,B){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new bH;let w=PH.getDefaultSiteInfo();this.defaultSiteInfo={...w,...B}}async initialize(){try{if(!await this.entityService.getEntity({entityType:"site-info",id:"site-info"})){if(await this.entityService.getEntity({entityType:"site-info",id:"site-info"}))return;this.logger.info("No site info found, creating default site info");let B=this.adapter.createSiteInfoContent(this.defaultSiteInfo);await this.entityService.createEntity({entity:{id:"site-info",entityType:"site-info",content:B,metadata:{}}}),this.logger.info("Default site info created successfully")}}catch(A){this.logger.error("Failed to initialize site info",{error:A})}}async getSiteInfo(){try{let A=await this.entityService.getEntity({entityType:"site-info",id:"site-info"});if(A)return this.adapter.parseSiteInfoBody(A.content)}catch(A){this.logger.debug("Site info not found, using defaults",{error:A})}return this.defaultSiteInfo}}var nLQ=new bH;class G5A{logger;id="site-info:entities";name="Site Info DataSource";description="Provides site metadata (title, description, CTA) and profile social links";constructor(A){this.logger=A}async fetch(A,Q,B){let{entityService:w}=B,$;try{let D=await w.getEntity({entityType:"site-info",id:"site-info"});$=D?nLQ.parseSiteInfoBody(D.content):{title:"Brain",description:"A knowledge management system"}}catch{$={title:"Brain",description:"A knowledge management system"}}let f;try{let D=await w.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(D)f=D.metadata.socialLinks}catch{}let I={...$,socialLinks:f,copyright:$.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:I.title,hasSocialLinks:!!I.socialLinks}),Q.parse(I)}}var TK1={name:"@brains/site-info",private:!0,version:"0.2.0-alpha.127",description:"Site info entity \u2014 site metadata, title, description, CTA",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/entity-service":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var sLQ=new bH;class NSA extends _Q{entityType="site-info";schema=Ii;adapter=sLQ;defaultSiteInfo;constructor(A){super("site-info",TK1);this.defaultSiteInfo=A?.siteInfo??{}}getEntityTypeConfig(){return{embeddable:!1}}getDataSources(){return[new G5A(this.logger.child("SiteInfoDataSource"))]}async onRegister(A){let Q=PH.createFresh(A.entityService,this.logger,this.defaultSiteInfo);A.messaging.subscribe(Hx,async()=>{return{success:!0,data:await Q.getSiteInfo()}}),A.messaging.subscribe("entity:updated",async(B)=>{if(B.payload.entityType==="site-info"){let $=await Q.getSiteInfo();await A.messaging.send({type:Gx,payload:$,broadcast:!0})}return{success:!0}}),A.messaging.subscribe("sync:initial:completed",async()=>{return await Q.initialize(),{success:!0}})}}function IC(A){return new NSA(A)}var aLQ=new bH;async function Di(A){let B=(await A.listEntities({entityType:"site-info",options:{limit:1}}))[0];if(!B)throw Error("Site info not found \u2014 create a site-info entity");return aLQ.parseSiteInfoBody(B.content)}WA();var tLQ=Nv.extend({navigation:H.object({primary:H.array(H.object({label:H.string(),href:H.string(),priority:H.number()})),secondary:H.array(H.object({label:H.string(),href:H.string(),priority:H.number()}))}),copyright:H.string(),socialLinks:H.array(H.object({platform:H.enum(["github","instagram","linkedin","email","website"]).describe("Social media platform"),url:H.string().describe("Profile or contact URL"),label:H.string().optional().describe("Optional display label")})).optional().describe("Social media links from profile entity")});aA();WA();var xK1={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 SK1={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 gK1={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 hK1={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 mK1={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 uK1={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 cK1={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 lK1={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 pK1={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 UVQ=H.object({type:H.string()}).catchall(H.unknown()),YVQ=H.object({lexicon:H.literal(1),id:H.string(),defs:H.object({main:H.object({type:H.literal("record"),key:H.string().min(1),record:H.object({type:H.literal("object"),required:H.array(H.string()).optional(),properties:H.record(UVQ)})})})});function kH(A){return YVQ.parse(A)}var Kw={"ai.rizom.brain.card":kH(xK1),"ai.rizom.brain.deck":kH(SK1),"ai.rizom.brain.link":kH(gK1),"ai.rizom.brain.note":kH(hK1),"ai.rizom.brain.post":kH(mK1),"ai.rizom.brain.project":kH(uK1),"ai.rizom.brain.series":kH(cK1),"ai.rizom.brain.socialPost":kH(lK1),"ai.rizom.brain.topic":kH(pK1)},JVQ="Additive optional fields are compatible; required-field, type, or constraint changes require a migration plan or new NSID.";function cF(A){return{status:"approved",version:"1.0.0",revision:1,owner:"Rizom",steward:"Rizom protocol registry",projectionPackage:A,compatibility:JVQ}}var XVQ={"ai.rizom.brain.card":cF("@brains/atproto"),"ai.rizom.brain.deck":cF("@brains/decks"),"ai.rizom.brain.link":cF("@brains/link"),"ai.rizom.brain.note":cF("@brains/note"),"ai.rizom.brain.post":cF("@brains/blog"),"ai.rizom.brain.project":cF("@brains/portfolio"),"ai.rizom.brain.series":cF("@brains/series"),"ai.rizom.brain.socialPost":cF("@brains/social-media"),"ai.rizom.brain.topic":cF("@brains/topics")};function DC(){return Object.values(Kw)}function LSA(A){return Kw[A]}function VSA(){return Object.entries(XVQ).map(([A,Q])=>({id:A,...Q}))}function qSA(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}var WVQ=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;function HVQ(A){let Q=H.string(),B=A.maxLength!==void 0?Q.max(A.maxLength):Q;if(A.knownValues)B=B.refine((w)=>A.knownValues?.includes(w),{message:`expected one of ${A.knownValues.join(", ")}`});if(A.format==="datetime")B=B.refine((w)=>WVQ.test(w)&&!Number.isNaN(Date.parse(w)),{message:"expected datetime"});if(A.format==="uri")B=B.refine((w)=>{try{return new URL(w),!0}catch{return!1}},{message:"expected uri"});return B}function iK1(A){switch(A.type){case"string":return HVQ(A);case"integer":return H.number().int();case"boolean":return H.boolean();case"array":{let Q=A.items?iK1(A.items):H.unknown(),B=H.array(Q);if(A.maxLength!==void 0)B=B.max(A.maxLength);return B}case"object":return GVQ(A);case"blob":return H.custom(qSA,{message:"expected blob"});default:return H.unknown()}}function rK1(A){let Q=new Set(A.required??[]),B={};for(let[w,$]of Object.entries(A.properties??{})){let f=iK1($);B[w]=Q.has(w)?f:f.optional()}return B}function GVQ(A){return H.object(rK1(A)).passthrough()}function zSA(A,Q,B,w=[]){let $=Object.keys(A).filter((f)=>!Q.has(f));if($.length===0)return;B.addIssue({code:H.ZodIssueCode.custom,path:w,message:`unrecognized field(s): ${$.join(", ")}`})}function KVQ(A,Q){if(zSA(A,new Set(["$type","siteUrl","brain","anchor","skills","model","version","createdAt","updatedAt"]),Q),qSA(A.brain))zSA(A.brain,new Set(["did","name","role","purpose","values"]),Q,["brain"]);if(qSA(A.anchor))zSA(A.anchor,new Set(["did","name","kind"]),Q,["anchor"])}function jH(A){let Q=H.object({...rK1(A.defs.main.record),$type:H.literal(A.id).optional()}).passthrough();return A.id==="ai.rizom.brain.card"?Q.superRefine(KVQ):Q}var FVQ={"ai.rizom.brain.card":jH(Kw["ai.rizom.brain.card"]),"ai.rizom.brain.deck":jH(Kw["ai.rizom.brain.deck"]),"ai.rizom.brain.link":jH(Kw["ai.rizom.brain.link"]),"ai.rizom.brain.note":jH(Kw["ai.rizom.brain.note"]),"ai.rizom.brain.post":jH(Kw["ai.rizom.brain.post"]),"ai.rizom.brain.project":jH(Kw["ai.rizom.brain.project"]),"ai.rizom.brain.series":jH(Kw["ai.rizom.brain.series"]),"ai.rizom.brain.socialPost":jH(Kw["ai.rizom.brain.socialPost"]),"ai.rizom.brain.topic":jH(Kw["ai.rizom.brain.topic"])};function ZVQ(A,Q,B){let w=B.path.join(".");if(w==="$type")return`AT Protocol record $type must match lexicon id: ${String(Q.$type)} !== ${A.id}`;if(B.code==="invalid_type"&&B.received==="undefined")return`Missing required AT Protocol record field: ${w}`;if(B.code==="invalid_type")return`Invalid AT Protocol record field ${w}: expected ${B.expected}`;if(B.code==="too_big")return`Invalid AT Protocol record field ${w}: exceeds maxLength ${B.maximum}`;if(B.code==="custom")return`Invalid AT Protocol record field ${w}: ${B.message}`;if(B.code==="unrecognized_keys")return`Unrecognized AT Protocol record field(s): ${B.keys.join(", ")}`;return`Invalid AT Protocol record field ${w}: ${B.message}`}function cz(A,Q){let B=jH(A).safeParse(Q);if(B.success)return;let w=B.error.issues[0];if(!w)throw B.error;throw Error(ZVQ(A,Q,w))}var K5A="atproto:brain-card-discovered",dK1="atproto:brain-discovered",nK1="atproto:brain-card-refreshed",oK1=H.object({repoDid:H.string().min(1),uri:H.string().min(1),cid:H.string().min(1),record:FVQ["ai.rizom.brain.card"]}).strict(),Bcw=H.object({agentId:H.string().min(1),name:H.string().min(1),url:H.string().url(),status:H.enum(["discovered","approved"]),repoDid:H.string().min(1).optional(),brainDid:H.string().min(1).optional(),anchorDid:H.string().min(1).optional(),cardUri:H.string().min(1).optional(),cardCid:H.string().min(1).optional()}).strict();class o6{static instance;projections=new Map;registrationCounts=new Map;static getInstance(){return this.instance??=new o6,this.instance}static createFresh(){return new o6}static resetInstance(){this.instance=void 0}register(A){this.validateProjection(A);let Q=this.projections.get(A.entityType);if(Q){if(!this.isEquivalentProjection(Q,A))throw Error(`AT Protocol projection already registered for entity type ${A.entityType}`);return this.registrationCounts.set(A.entityType,(this.registrationCounts.get(A.entityType)??1)+1),this.createUnregister(A.entityType)}return this.projections.set(A.entityType,A),this.registrationCounts.set(A.entityType,1),this.createUnregister(A.entityType)}get(A){return this.projections.get(A)}has(A){return this.projections.has(A)}list(){return Array.from(this.projections.values())}listLexicons(){return this.list().map((A)=>A.lexicon)}createUnregister(A){let Q=!0;return()=>{if(!Q)return;Q=!1;let B=this.registrationCounts.get(A)??0;if(B<=1){this.registrationCounts.delete(A),this.projections.delete(A);return}this.registrationCounts.set(A,B-1)}}isEquivalentProjection(A,Q){return A.entityType===Q.entityType&&A.collection===Q.collection&&A.lexicon.id===Q.lexicon.id&&A.validate===Q.validate}validateProjection(A){if(A.collection!==A.lexicon.id)throw Error(`AT Protocol projection collection must match lexicon id: ${A.collection} !== ${A.lexicon.id}`);if(!A.lexicon.defs.main.key)throw Error(`AT Protocol projection lexicon must define a record key: ${A.collection}`)}}qD();qv();WA();var ESA=H.object({defaultPrompt:H.string().default("Write a blog post about my recent work and insights"),paginate:H.boolean().default(!0),pageSize:H.number().default(10)});aA();WA();o8();var qVQ=H.object({prompt:H.string().optional(),title:H.string().optional(),content:H.string().optional(),excerpt:H.string().optional(),coverImageId:H.string().optional(),seriesName:H.string().optional(),seriesIndex:H.number().optional(),skipAi:H.boolean().optional()}),Kcw=VI.extend({title:H.string().optional(),slug:H.string().optional()});class MSA extends L7{constructor(A,Q){super(A,Q,{schema:qVQ,jobTypeName:"blog-generation",entityType:"post"})}async generate(A,Q){let{prompt:B,coverImageId:w,seriesName:$,seriesIndex:f,skipAi:I}=A,{title:D,content:U,excerpt:Y}=A;if(I){if(!D)this.failEarly("Title is required when skipAi is true");U=U??`## Introduction
|
|
5659
5659
|
|
|
5660
5660
|
Add your introduction here.
|
|
5661
5661
|
|
|
@@ -5875,7 +5875,7 @@ ${B.content}`,templateName:"blog:excerpt"})})}aA();qv();qD();function lVQ(A){let
|
|
|
5875
5875
|
letter-spacing: 0.02em;
|
|
5876
5876
|
}
|
|
5877
5877
|
.printable-footer a { color: inherit; text-decoration: none; overflow-wrap: anywhere; }
|
|
5878
|
-
`}},void 0,!1,void 0,this),s9("header",{className:"printable-hero",children:[s9("div",{className:"printable-masthead",children:Q.brandLabel&&s9("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this),s9("div",{children:[s9("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.excerpt&&s9("p",{className:"printable-excerpt",children:Q.excerpt},void 0,!1,void 0,this),s9("div",{className:"printable-meta",children:[Q.author&&s9("span",{children:["By ",Q.author]},void 0,!0,void 0,this),B&&s9("span",{children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q.coverImageUrl&&s9("figure",{className:"printable-cover-wrap",children:s9("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this)},void 0,!1,void 0,this),s9(M$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Q.canonicalUrl||Q.brandLabel)&&s9("footer",{className:"printable-footer",children:[s9("span",{children:Q.brandLabel??"Printable PDF"},void 0,!1,void 0,this),Q.canonicalUrl&&s9("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 CEQ=26214400,OEQ=60000;class TSA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??WX}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==z5A)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let B=REQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await LEQ(MEQ(EEQ(),"brain-blog-printable-"));try{let $=await VD({outputDir:w,mediaPath:`/_media/printable/post/${Q.id}`,template:GF1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ED({rootDir:w});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:CEQ,timeoutMs:OEQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${bEQ(Q)}-printable.pdf`}}finally{await f.close()}}finally{await VEQ(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=jB(A.content),B=q8.parse(Q);if(!B.coverImageId)return;let w=await this.context.entityService.getEntity({entityType:"image",id:B.coverImageId});return w?.content.startsWith("data:image/")?w.content:void 0}}function REQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=q8.parse(B);return{title:$.title,body:w,...$.excerpt?{excerpt:$.excerpt}:{},...$.author?{author:$.author}:{},...$.publishedAt?{publishedAt:$.publishedAt}:{},...$.canonicalUrl?{canonicalUrl:$.canonicalUrl}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function bEQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}import{mkdtemp as vEQ,rm as yEQ}from"fs/promises";import{tmpdir as TEQ}from"os";import{join as xEQ}from"path";WA();qD();WA();import{jsxDEV as _EQ}from"preact/jsx-dev-runtime";var Gi="og-image",PEQ="blog:og-image",KF1=H.object({title:H.string().min(1),excerpt:H.string().optional(),author:H.string().optional(),publishedAt:H.string().optional(),brandLabel:H.string().optional(),coverImageUrl:H.string().optional()}),FF1={name:PEQ,pluginId:"blog",schema:KF1,renderers:{image:jEQ}};function kEQ(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 jEQ(A){let Q=KF1.parse(A);return _EQ(CF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Journal",title:Q.title,subtitle:Q.excerpt,meta:[Q.author],tag:kEQ(Q.publishedAt)},void 0,!1,void 0,this)}var SEQ={width:1200,height:630},gEQ=60000;class xSA{context;screenshotPng;constructor(A,Q={}){this.context=A;this.screenshotPng=Q.screenshotPng??Hi}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==Gi)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let B=hEQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await vEQ(xEQ(TEQ(),"brain-blog-og-image-"));try{let $=await VD({outputDir:w,mediaPath:`/_media/og/post/${Q.id}`,template:FF1,format:"image",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ED({rootDir:w});try{return{type:"image",data:await this.screenshotPng(f.urlFor($.urlPath),SEQ,{timeoutMs:gEQ,fullPage:!1,omitBackground:!1}),mimeType:"image/png",filename:`${mEQ(Q)}-og.png`}}finally{await f.close()}}finally{await yEQ(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=jB(A.content),B=q8.parse(Q);if(!B.coverImageId)return;let w=await this.context.entityService.getEntity({entityType:"image",id:B.coverImageId});return w?.content.startsWith("data:image/")?w.content:void 0}}function hEQ(A,Q={}){let{frontmatter:B}=jB(A.content),w=q8.parse(B);return{title:w.title,...w.excerpt?{excerpt:w.excerpt}:{},...w.author?{author:w.author}:{},...w.publishedAt?{publishedAt:w.publishedAt}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function mEQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}var ZF1={name:"@brains/blog",private:!0,version:"0.2.0-alpha.125",description:"AI-powered blog post generation from existing brain content",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/contracts":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class SSA extends _Q{entityType=pF.entityType;schema=zv;adapter=pF;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("blog",ZF1,A,ESA)}getEntityTypeConfig(){return{weight:2,publish:{publishStatuses:["queued","published"]}}}createGenerationHandler(A){return new MSA(this.logger.child("BlogGenerationJobHandler"),A)}getTemplates(){return AF1()}getDataSources(){return[new OSA(this.logger.child("BlogDataSource"))]}async onRegister(A){let{RSSDataSource:Q}=await Promise.resolve().then(() => (qF1(),zF1));A.entities.registerDataSource(new Q(this.logger.child("RSSDataSource"))),QF1(A,this.logger),BF1(A,this.logger),$F1(A,this.logger),fF1(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("post",z5A,new TSA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("post",Gi,new xSA(A)),this.deferPublishAssetRegistration(A),this.unregisterAtprotoProjection=o6.getInstance().register(PSA()),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:Gi,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 gSA(A={}){return new SSA(A)}qD();qv();aA();WA();WA();t$();aA();var aU=H.object({title:H.string(),slug:H.string(),coverImageId:H.string().optional()}),LF1=aU.pick({title:!0,slug:!0}),lz=A2.extend({metadata:LF1}),q5A=lz.extend({frontmatter:aU}),L5A=q5A.extend({description:H.string().optional(),postCount:H.number(),coverImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()}),VF1=H.object({description:H.string().optional()});function JC(A){return new lB(VF1,{title:A,mappings:[{key:"description",label:"Description",type:"string"}]})}aA();class hSA extends q2{constructor(){super({entityType:"series",schema:lz,frontmatterSchema:aU,supportsCoverImage:!0,bodyFormatter:JC("")})}toMarkdown(A){let Q,B={};try{Q=this.parseFrontMatter(A.content,aU).coverImageId,B=JC(A.metadata.title).parse(this.extractBody(A.content))}catch{}let w={title:A.metadata.title,slug:A.metadata.slug,...Q&&{coverImageId:Q}},f=JC(A.metadata.title).format(B);return this.buildMarkdown(f,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,aU);return{content:A,entityType:"series",metadata:{title:Q.title,slug:Q.slug}}}parseBody(A){try{let Q=this.parseFrontMatter(A,aU);return JC(Q.title).parse(this.extractBody(A))}catch{return{}}}generateFrontMatter(){return""}}var pz=new hSA;aA();WA();JU();WA();var lEQ=H.object({seriesName:H.string().optional(),seriesIndex:H.number().optional()});function V5A(A){let Q=lEQ.safeParse(A);return Q.success?Q.data:{}}function XC(A){return V5A(A.metadata).seriesName}function EF1(A){return V5A(A.metadata).seriesIndex}function MF1(A,Q){let B=EF1(A)??Number.MAX_SAFE_INTEGER,w=EF1(Q)??Number.MAX_SAFE_INTEGER;return B-w}class mSA{entityService;logger;constructor(A,Q){this.entityService=A;this.logger=Q}async syncAllSeries(){this.logger.debug("Syncing series from all entity types");let A=await this.collectSeriesNames();this.logger.debug(`Found ${A.size} unique series`);let Q=await this.entityService.listEntities({entityType:"series"}),B=new Map(Q.map(($)=>[$.id,$])),w=new Set;for(let $ of A){let f=X1($);w.add(f);let I=B.get(f),D=I?.content??this.createSeriesContent($),U=gB(D);if(I?.contentHash===U)continue;let Y={id:f,entityType:"series",content:D,contentHash:U,created:I?.created??new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:$,slug:X1($)}};await this.entityService.upsertEntity({entity:Y}),this.logger.debug(`Upserted series: ${$}`)}for(let $ of Q)if(!w.has($.id))await this.entityService.deleteEntity({entityType:"series",id:$.id}),this.logger.debug(`Deleted orphaned series: ${$.id}`)}async handleEntityChange(A,Q){let B=XC(A);if(B)await this.ensureSeriesExists(B);if(Q&&Q!==B)await this.cleanupOrphanedSeries(Q)}async handleEntityDeleted(){await this.syncAllSeries()}async ensureSeriesExists(A){let Q=X1(A);if(await this.entityService.getEntity({entityType:"series",id:Q}))return;let w=this.createSeriesContent(A),$={id:Q,entityType:"series",content:w,contentHash:gB(w),created:new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:A,slug:X1(A)}};await this.entityService.upsertEntity({entity:$}),this.logger.debug(`Created series: ${A}`)}async cleanupOrphanedSeries(A){let Q=X1(A);if(!await this.entityService.getEntity({entityType:"series",id:Q}))return;if(!await this.hasSeriesReferences(A))await this.entityService.deleteEntity({entityType:"series",id:Q}),this.logger.debug(`Deleted orphaned series: ${A}`)}async hasSeriesReferences(A){let Q=this.entityService.getEntityTypes();for(let B of Q){if(B==="series")continue;if((await this.entityService.listEntities({entityType:B,options:{filter:{metadata:{seriesName:A}},limit:1}})).length>0)return!0}return!1}async collectSeriesNames(){let A=new Set,Q=this.entityService.getEntityTypes();for(let B of Q){if(B==="series")continue;let w=await this.entityService.listEntities({entityType:B});for(let $ of w){let f=XC($);if(f)A.add(f)}}return A}createSeriesContent(A){let Q={title:A,slug:X1(A)};return k9("",Q)}}aA();WA();var pEQ=H.object({entityType:H.literal("series"),query:H.object({id:H.string().optional(),limit:H.number().optional(),page:H.number().optional(),pageSize:H.number().optional()}).passthrough()}),iEQ=H.object({type:H.enum(["list","detail"]),seriesName:H.string().optional()});function rEQ(A){let Q=iEQ.safeParse(A);if(Q.success)return{type:Q.data.type,seriesName:Q.data.seriesName};let B=pEQ.safeParse(A);if(B.success){let{query:w}=B.data;if(w.id)return{type:"detail",seriesSlug:w.id};return{type:"list"}}throw Error('Invalid series query format. Expected { type: "list"|"detail" } or { entityType: "series", query: { id?: string } }')}function CF1(A){let Q=b2(A.content,aU);return q5A.parse({...A,frontmatter:Q.metadata})}class uSA{logger;id="series:entities";name="Series DataSource";description="Fetches series list and detail data";constructor(A){this.logger=A}async fetch(A,Q,B){let w=rEQ(A),$=B.entityService;if(w.type==="list")return this.fetchSeriesList(Q,$);if(w.seriesName)return this.fetchSeriesDetail(w.seriesName,Q,$);if(w.seriesSlug)return this.fetchSeriesDetailBySlug(w.seriesSlug,Q,$);throw Error("Invalid series query: must specify seriesName or slug for detail")}async fetchSeriesList(A,Q){let B=await Q.listEntities({entityType:"series"}),w=await this.countEntitiesPerSeries(Q),$=B.map((f)=>{let I=CF1(f),D=pz.parseBody(f.content);return{...I,description:D.description,postCount:w.get(f.metadata.title)??0}});return this.logger.debug(`Found ${$.length} series entities`),A.parse({series:$})}async fetchSeriesDetail(A,Q,B,w){if(!w)w=(await B.listEntities({entityType:"series",options:{filter:{metadata:{title:A}}}}))[0];if(!w)throw Error(`Series not found: ${A}`);let $=CF1(w),f=pz.parseBody(w.content),I=await this.getSeriesMembers(A,B);return this.logger.debug(`Found ${I.length} entities in series "${A}"`),Q.parse({seriesName:A,posts:I,series:{...$,description:f.description,postCount:I.length},description:f.description})}async fetchSeriesDetailBySlug(A,Q,B){let $=(await B.listEntities({entityType:"series",options:{filter:{metadata:{slug:A}}}}))[0];if(!$)throw Error(`Series not found with slug: ${A}`);return this.fetchSeriesDetail($.metadata.title,Q,B,$)}async countEntitiesPerSeries(A){let Q=new Map,B=A.getEntityTypes();for(let w of B){if(w==="series")continue;let $=await A.listEntities({entityType:w});for(let f of $){let I=XC(f);if(I)Q.set(I,(Q.get(I)??0)+1)}}return Q}async getSeriesMembers(A,Q){let B=[],w=Q.getEntityTypes();for(let $ of w){if($==="series")continue;let f=await Q.listEntities({entityType:$,options:{filter:{metadata:{seriesName:A}}}});B.push(...f)}return B.sort(MF1),B}}aA();WA();JU();var dEQ=H.object({prompt:H.string().optional(),title:H.string().optional(),seriesId:H.string().optional()}),nEQ=H.object({title:H.string().optional(),excerpt:H.string().optional()});class E5A{logger;context;constructor(A,Q){this.logger=A;this.context=Q}async process(A){let Q=A.seriesId??A.title;if(!Q)return{success:!1,error:"seriesId or title required"};let B=await this.context.entityService.getEntity({entityType:"series",id:Q});if(!B)return{success:!1,error:`Series not found: ${Q}`};let w=await this.gatherMemberSummaries(B.metadata.title);if(w.length===0)return{success:!1,error:`No members found in series: ${B.metadata.title}`};let $=A.prompt??`Series name: ${B.metadata.title}
|
|
5878
|
+
`}},void 0,!1,void 0,this),s9("header",{className:"printable-hero",children:[s9("div",{className:"printable-masthead",children:Q.brandLabel&&s9("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this),s9("div",{children:[s9("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.excerpt&&s9("p",{className:"printable-excerpt",children:Q.excerpt},void 0,!1,void 0,this),s9("div",{className:"printable-meta",children:[Q.author&&s9("span",{children:["By ",Q.author]},void 0,!0,void 0,this),B&&s9("span",{children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q.coverImageUrl&&s9("figure",{className:"printable-cover-wrap",children:s9("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this)},void 0,!1,void 0,this),s9(M$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Q.canonicalUrl||Q.brandLabel)&&s9("footer",{className:"printable-footer",children:[s9("span",{children:Q.brandLabel??"Printable PDF"},void 0,!1,void 0,this),Q.canonicalUrl&&s9("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 CEQ=26214400,OEQ=60000;class TSA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??WX}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==z5A)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let B=REQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await LEQ(MEQ(EEQ(),"brain-blog-printable-"));try{let $=await VD({outputDir:w,mediaPath:`/_media/printable/post/${Q.id}`,template:GF1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ED({rootDir:w});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:CEQ,timeoutMs:OEQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${bEQ(Q)}-printable.pdf`}}finally{await f.close()}}finally{await VEQ(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=jB(A.content),B=q8.parse(Q);if(!B.coverImageId)return;let w=await this.context.entityService.getEntity({entityType:"image",id:B.coverImageId});return w?.content.startsWith("data:image/")?w.content:void 0}}function REQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=q8.parse(B);return{title:$.title,body:w,...$.excerpt?{excerpt:$.excerpt}:{},...$.author?{author:$.author}:{},...$.publishedAt?{publishedAt:$.publishedAt}:{},...$.canonicalUrl?{canonicalUrl:$.canonicalUrl}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function bEQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}import{mkdtemp as vEQ,rm as yEQ}from"fs/promises";import{tmpdir as TEQ}from"os";import{join as xEQ}from"path";WA();qD();WA();import{jsxDEV as _EQ}from"preact/jsx-dev-runtime";var Gi="og-image",PEQ="blog:og-image",KF1=H.object({title:H.string().min(1),excerpt:H.string().optional(),author:H.string().optional(),publishedAt:H.string().optional(),brandLabel:H.string().optional(),coverImageUrl:H.string().optional()}),FF1={name:PEQ,pluginId:"blog",schema:KF1,renderers:{image:jEQ}};function kEQ(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 jEQ(A){let Q=KF1.parse(A);return _EQ(CF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Journal",title:Q.title,subtitle:Q.excerpt,meta:[Q.author],tag:kEQ(Q.publishedAt)},void 0,!1,void 0,this)}var SEQ={width:1200,height:630},gEQ=60000;class xSA{context;screenshotPng;constructor(A,Q={}){this.context=A;this.screenshotPng=Q.screenshotPng??Hi}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==Gi)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let B=hEQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await vEQ(xEQ(TEQ(),"brain-blog-og-image-"));try{let $=await VD({outputDir:w,mediaPath:`/_media/og/post/${Q.id}`,template:FF1,format:"image",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ED({rootDir:w});try{return{type:"image",data:await this.screenshotPng(f.urlFor($.urlPath),SEQ,{timeoutMs:gEQ,fullPage:!1,omitBackground:!1}),mimeType:"image/png",filename:`${mEQ(Q)}-og.png`}}finally{await f.close()}}finally{await yEQ(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=jB(A.content),B=q8.parse(Q);if(!B.coverImageId)return;let w=await this.context.entityService.getEntity({entityType:"image",id:B.coverImageId});return w?.content.startsWith("data:image/")?w.content:void 0}}function hEQ(A,Q={}){let{frontmatter:B}=jB(A.content),w=q8.parse(B);return{title:w.title,...w.excerpt?{excerpt:w.excerpt}:{},...w.author?{author:w.author}:{},...w.publishedAt?{publishedAt:w.publishedAt}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function mEQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}var ZF1={name:"@brains/blog",private:!0,version:"0.2.0-alpha.127",description:"AI-powered blog post generation from existing brain content",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/contracts":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class SSA extends _Q{entityType=pF.entityType;schema=zv;adapter=pF;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("blog",ZF1,A,ESA)}getEntityTypeConfig(){return{weight:2,publish:{publishStatuses:["queued","published"]}}}createGenerationHandler(A){return new MSA(this.logger.child("BlogGenerationJobHandler"),A)}getTemplates(){return AF1()}getDataSources(){return[new OSA(this.logger.child("BlogDataSource"))]}async onRegister(A){let{RSSDataSource:Q}=await Promise.resolve().then(() => (qF1(),zF1));A.entities.registerDataSource(new Q(this.logger.child("RSSDataSource"))),QF1(A,this.logger),BF1(A,this.logger),$F1(A,this.logger),fF1(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("post",z5A,new TSA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("post",Gi,new xSA(A)),this.deferPublishAssetRegistration(A),this.unregisterAtprotoProjection=o6.getInstance().register(PSA()),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:Gi,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 gSA(A={}){return new SSA(A)}qD();qv();aA();WA();WA();t$();aA();var aU=H.object({title:H.string(),slug:H.string(),coverImageId:H.string().optional()}),LF1=aU.pick({title:!0,slug:!0}),lz=A2.extend({metadata:LF1}),q5A=lz.extend({frontmatter:aU}),L5A=q5A.extend({description:H.string().optional(),postCount:H.number(),coverImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()}),VF1=H.object({description:H.string().optional()});function JC(A){return new lB(VF1,{title:A,mappings:[{key:"description",label:"Description",type:"string"}]})}aA();class hSA extends q2{constructor(){super({entityType:"series",schema:lz,frontmatterSchema:aU,supportsCoverImage:!0,bodyFormatter:JC("")})}toMarkdown(A){let Q,B={};try{Q=this.parseFrontMatter(A.content,aU).coverImageId,B=JC(A.metadata.title).parse(this.extractBody(A.content))}catch{}let w={title:A.metadata.title,slug:A.metadata.slug,...Q&&{coverImageId:Q}},f=JC(A.metadata.title).format(B);return this.buildMarkdown(f,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,aU);return{content:A,entityType:"series",metadata:{title:Q.title,slug:Q.slug}}}parseBody(A){try{let Q=this.parseFrontMatter(A,aU);return JC(Q.title).parse(this.extractBody(A))}catch{return{}}}generateFrontMatter(){return""}}var pz=new hSA;aA();WA();JU();WA();var lEQ=H.object({seriesName:H.string().optional(),seriesIndex:H.number().optional()});function V5A(A){let Q=lEQ.safeParse(A);return Q.success?Q.data:{}}function XC(A){return V5A(A.metadata).seriesName}function EF1(A){return V5A(A.metadata).seriesIndex}function MF1(A,Q){let B=EF1(A)??Number.MAX_SAFE_INTEGER,w=EF1(Q)??Number.MAX_SAFE_INTEGER;return B-w}class mSA{entityService;logger;constructor(A,Q){this.entityService=A;this.logger=Q}async syncAllSeries(){this.logger.debug("Syncing series from all entity types");let A=await this.collectSeriesNames();this.logger.debug(`Found ${A.size} unique series`);let Q=await this.entityService.listEntities({entityType:"series"}),B=new Map(Q.map(($)=>[$.id,$])),w=new Set;for(let $ of A){let f=X1($);w.add(f);let I=B.get(f),D=I?.content??this.createSeriesContent($),U=gB(D);if(I?.contentHash===U)continue;let Y={id:f,entityType:"series",content:D,contentHash:U,created:I?.created??new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:$,slug:X1($)}};await this.entityService.upsertEntity({entity:Y}),this.logger.debug(`Upserted series: ${$}`)}for(let $ of Q)if(!w.has($.id))await this.entityService.deleteEntity({entityType:"series",id:$.id}),this.logger.debug(`Deleted orphaned series: ${$.id}`)}async handleEntityChange(A,Q){let B=XC(A);if(B)await this.ensureSeriesExists(B);if(Q&&Q!==B)await this.cleanupOrphanedSeries(Q)}async handleEntityDeleted(){await this.syncAllSeries()}async ensureSeriesExists(A){let Q=X1(A);if(await this.entityService.getEntity({entityType:"series",id:Q}))return;let w=this.createSeriesContent(A),$={id:Q,entityType:"series",content:w,contentHash:gB(w),created:new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:A,slug:X1(A)}};await this.entityService.upsertEntity({entity:$}),this.logger.debug(`Created series: ${A}`)}async cleanupOrphanedSeries(A){let Q=X1(A);if(!await this.entityService.getEntity({entityType:"series",id:Q}))return;if(!await this.hasSeriesReferences(A))await this.entityService.deleteEntity({entityType:"series",id:Q}),this.logger.debug(`Deleted orphaned series: ${A}`)}async hasSeriesReferences(A){let Q=this.entityService.getEntityTypes();for(let B of Q){if(B==="series")continue;if((await this.entityService.listEntities({entityType:B,options:{filter:{metadata:{seriesName:A}},limit:1}})).length>0)return!0}return!1}async collectSeriesNames(){let A=new Set,Q=this.entityService.getEntityTypes();for(let B of Q){if(B==="series")continue;let w=await this.entityService.listEntities({entityType:B});for(let $ of w){let f=XC($);if(f)A.add(f)}}return A}createSeriesContent(A){let Q={title:A,slug:X1(A)};return k9("",Q)}}aA();WA();var pEQ=H.object({entityType:H.literal("series"),query:H.object({id:H.string().optional(),limit:H.number().optional(),page:H.number().optional(),pageSize:H.number().optional()}).passthrough()}),iEQ=H.object({type:H.enum(["list","detail"]),seriesName:H.string().optional()});function rEQ(A){let Q=iEQ.safeParse(A);if(Q.success)return{type:Q.data.type,seriesName:Q.data.seriesName};let B=pEQ.safeParse(A);if(B.success){let{query:w}=B.data;if(w.id)return{type:"detail",seriesSlug:w.id};return{type:"list"}}throw Error('Invalid series query format. Expected { type: "list"|"detail" } or { entityType: "series", query: { id?: string } }')}function CF1(A){let Q=b2(A.content,aU);return q5A.parse({...A,frontmatter:Q.metadata})}class uSA{logger;id="series:entities";name="Series DataSource";description="Fetches series list and detail data";constructor(A){this.logger=A}async fetch(A,Q,B){let w=rEQ(A),$=B.entityService;if(w.type==="list")return this.fetchSeriesList(Q,$);if(w.seriesName)return this.fetchSeriesDetail(w.seriesName,Q,$);if(w.seriesSlug)return this.fetchSeriesDetailBySlug(w.seriesSlug,Q,$);throw Error("Invalid series query: must specify seriesName or slug for detail")}async fetchSeriesList(A,Q){let B=await Q.listEntities({entityType:"series"}),w=await this.countEntitiesPerSeries(Q),$=B.map((f)=>{let I=CF1(f),D=pz.parseBody(f.content);return{...I,description:D.description,postCount:w.get(f.metadata.title)??0}});return this.logger.debug(`Found ${$.length} series entities`),A.parse({series:$})}async fetchSeriesDetail(A,Q,B,w){if(!w)w=(await B.listEntities({entityType:"series",options:{filter:{metadata:{title:A}}}}))[0];if(!w)throw Error(`Series not found: ${A}`);let $=CF1(w),f=pz.parseBody(w.content),I=await this.getSeriesMembers(A,B);return this.logger.debug(`Found ${I.length} entities in series "${A}"`),Q.parse({seriesName:A,posts:I,series:{...$,description:f.description,postCount:I.length},description:f.description})}async fetchSeriesDetailBySlug(A,Q,B){let $=(await B.listEntities({entityType:"series",options:{filter:{metadata:{slug:A}}}}))[0];if(!$)throw Error(`Series not found with slug: ${A}`);return this.fetchSeriesDetail($.metadata.title,Q,B,$)}async countEntitiesPerSeries(A){let Q=new Map,B=A.getEntityTypes();for(let w of B){if(w==="series")continue;let $=await A.listEntities({entityType:w});for(let f of $){let I=XC(f);if(I)Q.set(I,(Q.get(I)??0)+1)}}return Q}async getSeriesMembers(A,Q){let B=[],w=Q.getEntityTypes();for(let $ of w){if($==="series")continue;let f=await Q.listEntities({entityType:$,options:{filter:{metadata:{seriesName:A}}}});B.push(...f)}return B.sort(MF1),B}}aA();WA();JU();var dEQ=H.object({prompt:H.string().optional(),title:H.string().optional(),seriesId:H.string().optional()}),nEQ=H.object({title:H.string().optional(),excerpt:H.string().optional()});class E5A{logger;context;constructor(A,Q){this.logger=A;this.context=Q}async process(A){let Q=A.seriesId??A.title;if(!Q)return{success:!1,error:"seriesId or title required"};let B=await this.context.entityService.getEntity({entityType:"series",id:Q});if(!B)return{success:!1,error:`Series not found: ${Q}`};let w=await this.gatherMemberSummaries(B.metadata.title);if(w.length===0)return{success:!1,error:`No members found in series: ${B.metadata.title}`};let $=A.prompt??`Series name: ${B.metadata.title}
|
|
5879
5879
|
|
|
5880
5880
|
Content in this series:
|
|
5881
5881
|
${w.join(`
|
|
@@ -5887,7 +5887,7 @@ Your task is to write a series description (2-3 sentences) that:
|
|
|
5887
5887
|
3. Is engaging and makes readers want to explore the content
|
|
5888
5888
|
4. Works well as a series overview on a website
|
|
5889
5889
|
|
|
5890
|
-
Be concise and focus on what makes this series unique and valuable.`});async function _F1({entity:A,config:Q}){let B=lz.parse(A),w=pz.parseBody(B.content);return{$type:"ai.rizom.brain.series",title:B.metadata.title,slug:B.metadata.slug,...w.description&&{description:w.description},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"series",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function cSA(){return{entityType:"series",collection:"ai.rizom.brain.series",lexicon:Kw["ai.rizom.brain.series"],validate:!1,buildRecord:_F1}}var vF1={name:"@brains/series",private:!0,version:"0.2.0-alpha.
|
|
5890
|
+
Be concise and focus on what makes this series unique and valuable.`});async function _F1({entity:A,config:Q}){let B=lz.parse(A),w=pz.parseBody(B.content);return{$type:"ai.rizom.brain.series",title:B.metadata.title,slug:B.metadata.slug,...w.description&&{description:w.description},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"series",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function cSA(){return{entityType:"series",collection:"ai.rizom.brain.series",lexicon:Kw["ai.rizom.brain.series"],validate:!1,buildRecord:_F1}}var vF1={name:"@brains/series",private:!0,version:"0.2.0-alpha.127",description:"Cross-content series \u2014 auto-derived from entities with seriesName metadata",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts,.tsx","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/entity-service":"workspace:*","@brains/job-queue":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var yF1=H.discriminatedUnion("mode",[H.object({mode:H.literal("derive"),reason:H.string().optional()}),H.object({mode:H.literal("source"),entityId:H.string(),entityType:H.string(),seriesName:H.string().optional(),previousSeriesName:H.string().optional()})]);class lSA extends _Q{entityType="series";schema=lz;adapter=pz;manager;unregisterAtprotoProjection;constructor(){super("series",vF1)}getEntityTypeConfig(){return{weight:0.5}}createGenerationHandler(A){return new E5A(this.logger.child("SeriesGenerationHandler"),A)}getTemplates(){return{...kF1(),description:jF1}}getDataSources(){return[new uSA(this.logger.child("SeriesDataSource"))]}getDerivedEntityProjections(A){return[{id:"series-projection",targetType:"series",job:{type:"series:project",handler:this.createSeriesProjectionHandler(A)},initialSync:{jobData:{mode:"derive",reason:"initial-sync"},jobOptions:this.getSyncProjectionJobOptions("initial-sync")},sourceChange:{sourceTypes:["*"],events:["entity:created","entity:updated","entity:deleted"],requireInitialSync:!0,jobData:(Q)=>{if(Q.entityType==="series")return null;if(!Q.entity)return null;let B=XC(Q.entity),w=V5A(Q.previousMetadata).seriesName;if(!B&&!w)return null;return{mode:"source",entityId:Q.entity.id,entityType:Q.entity.entityType,...B?{seriesName:B}:{},...w&&w!==B?{previousSeriesName:w}:{}}},jobOptions:(Q)=>{if(!Q.entity)return;return this.getSourceProjectionJobOptions(Q.entity)}}}]}async onRegister(A){this.manager=new mSA(A.entityService,this.logger.child("SeriesManager")),this.unregisterAtprotoProjection=o6.getInstance().register(cSA())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}createSeriesProjectionHandler(A){return{process:async(Q)=>{let B=yF1.parse(Q);if(B.mode==="derive")return await this.projectAll(A),{success:!0};let w=await A.entityService.getEntity({entityType:B.entityType,id:B.entityId});if(w)await this.projectSource(w,B.previousSeriesName);else{let $=this.requireManager();for(let f of[B.seriesName,B.previousSeriesName])if(f)await $.cleanupOrphanedSeries(f)}return{success:!0}},validateAndParse:(Q)=>{let B=yF1.safeParse(Q??{});return B.success?B.data:null}}}requireManager(){if(!this.manager)throw Error("SeriesPlugin not registered");return this.manager}getSyncProjectionJobOptions(A){return{source:this.id,deduplication:"coalesce",deduplicationKey:`series-sync:${A}`,metadata:{operationType:"data_processing",operationTarget:"series"}}}getSourceProjectionJobOptions(A){return{source:this.id,deduplication:"coalesce",deduplicationKey:`series-source:${A.entityType}:${A.id}`,metadata:{operationType:"data_processing",operationTarget:`series:${A.entityType}:${A.id}`}}}async projectSource(A,Q){await this.requireManager().handleEntityChange(A,Q)}async projectAll(A){await this.requireManager().syncAllSeries();let Q=new E5A(this.logger.child("SeriesGenerationHandler"),A),B=await A.entityService.listEntities({entityType:"series"});for(let w of B)try{if(!this.adapter.parseBody(w.content).description)this.logger.info(`Generating description for series: ${w.metadata.title}`),await Q.process({seriesId:w.id})}catch($){this.logger.error(`Failed to generate description for series: ${w.id}`,{error:$})}}}function pSA(){return new lSA}aA();WA();aA();WA();WA();aA();var eEQ=H.enum(["generating","draft","queued","published","failed"]),TF1="publishedAt is required when deck status is published",xF1=(A)=>A.status==="published"&&!A.publishedAt,iSA=(A)=>{if(xF1(A))throw Error(TF1)},tU=H.object({title:H.string(),slug:H.string().optional(),description:H.string().optional(),author:H.string().optional(),status:eEQ,publishedAt:H.string().datetime().optional(),event:H.string().optional(),coverImageId:H.string().optional(),ogImageId:H.string().optional()}),AMQ=tU.pick({title:!0,description:!0,status:!0,publishedAt:!0,coverImageId:!0}).extend({slug:H.string(),error:H.string().optional()}).superRefine((A,Q)=>{if(!xF1(A))return;Q.addIssue({code:H.ZodIssueCode.custom,path:["publishedAt"],message:TF1})}),Vv=A2.extend({entityType:H.literal("deck"),metadata:AMQ}),M5A=Vv.extend({frontmatter:tU,body:H.string(),ogImageUrl:H.string().optional()}),WC=M5A.extend({url:H.string().optional(),typeLabel:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),coverImageUrl:H.string().optional(),ogImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()});class rSA extends q2{constructor(){super({entityType:"deck",schema:Vv,frontmatterSchema:tU,supportsCoverImage:!0})}validateSlideStructure(A){if(!/^---$/gm.test(A))throw Error("Invalid deck: markdown must contain slide separators (---) to be a valid presentation")}toMarkdown(A){let Q=this.extractBody(A.content);this.validateSlideStructure(Q);let B=this.parseFrontMatter(A.content,tU);iSA(B);let w={...B,slug:B.slug??A.metadata.slug};return this.buildMarkdown(Q,w)}fromMarkdown(A){let Q=this.parseFrontmatter(A),B=this.extractBody(A);iSA(Q),this.validateSlideStructure(B);let w=Q.slug??X1(Q.title),$=Q.status;return{entityType:"deck",content:A,metadata:{slug:w,title:Q.title,description:Q.description,status:$,publishedAt:Q.publishedAt,coverImageId:Q.coverImageId}}}generateTitle(A){return A.metadata.title}generateSummary(A){if(A.metadata.description)return A.metadata.description;return`Presentation: ${A.metadata.title}`}generateFrontMatter(A){return this.toMarkdown(A)}buildStub(A){let Q={title:A.title,slug:A.id,status:"generating"};return{content:this.buildMarkdown(`---
|
|
5891
5891
|
`,Q),metadata:{title:A.title,slug:A.id,status:"generating"}}}}var Ki=new rSA;WA();Xw();var QMQ=H.object({markdown:H.string().describe("Markdown content with slide separators (---)"),deck:WC.optional()}),dSA=P1({name:"deck-detail",description:"Render a presentation deck as Reveal.js slides",schema:QMQ,dataSourceId:"decks:entities",requiredPermission:"public",layout:{component:vyA,fullscreen:!0}});Xw();WA();var nSA=H.object({decks:H.array(M5A)}),oSA=H.object({decks:H.array(WC),pageTitle:H.string().optional(),pageLabel:H.string().optional()});import{jsxDEV as sSA}from"preact/jsx-dev-runtime";var BMQ="Presentations",aSA=({decks:A,pageLabel:Q})=>{let B=A.map(($)=>({id:$.id,url:$.url,title:$.frontmatter.title,date:$.frontmatter.publishedAt??$.created,description:$.frontmatter.description}));return sSA("div",{className:"deck-list bg-theme",children:sSA("div",{className:"container mx-auto max-w-[1100px] px-6 py-16 md:px-12 md:py-24",children:sSA(Jp,{label:Q&&Q!=="Decks"?Q:BMQ,items:B},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)};t$();class C5A extends lB{constructor(){super(nSA,{title:"Deck List",mappings:[{key:"decks",label:"Decks",type:"array",itemType:"object"}]})}}var tSA=P1({name:"deck-list",description:"List view of all presentation decks",schema:oSA,dataSourceId:"decks:entities",requiredPermission:"public",formatter:new C5A,layout:{component:aSA}});WA();aA();var wMQ=H.object({title:H.string().max(80).describe("A short, punchy title (2-5 words) that's memorable and evocative"),content:H.string().describe("Full slide deck content in markdown format with slide separators (---). Each slide should have a header and focused content."),description:H.string().describe("A concise 1-2 sentence summary that captures the essence of the talk")}),SF1=P1({name:"decks:generation",description:"Template for AI to generate complete slide decks from prompts",schema:wMQ,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are creating slide decks in a distinctive voice that blends philosophy, technology, and culture.
|
|
5892
5892
|
|
|
5893
5893
|
Your task is to generate a complete slide deck based on the user's prompt.
|
|
@@ -6195,14 +6195,14 @@ ${D}`,templateName:"decks:description"})).description,await this.reportProgress(
|
|
|
6195
6195
|
color: var(--carousel-accent);
|
|
6196
6196
|
font-weight: 600;
|
|
6197
6197
|
}
|
|
6198
|
-
`}},void 0,!1,void 0,this),$.map((Y,J)=>c7("section",{className:`deck-carousel-slide${J===0?" is-cover":""}`,children:[c7("header",{className:"deck-carousel-header",children:c7("span",{className:"deck-carousel-wordmark","aria-label":B??Q,children:[c7("span",{className:"wm-primary",children:f.primary},void 0,!1,void 0,this),f.secondary!==void 0&&c7(YMQ,{children:[c7("span",{className:"wm-dot",children:"."},void 0,!1,void 0,this),c7("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),c7("div",{className:"deck-carousel-body",children:c7("div",{className:"deck-carousel-content",dangerouslySetInnerHTML:{__html:U(Y.markdown)}},void 0,!1,void 0,this)},void 0,!1,void 0,this),c7("footer",{className:"deck-carousel-footer",children:[c7("span",{className:"deck-carousel-footer-meta",children:w??Q},void 0,!1,void 0,this),c7("span",{className:"deck-carousel-counter","aria-label":`Slide ${J+1} of ${I}`,children:[c7("span",{className:"deck-carousel-counter-current",children:String(J+1).padStart(2,"0")},void 0,!1,void 0,this)," / ",c7("span",{children:D},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},J,!0,void 0,this))]},void 0,!0,void 0,this)}import{mkdtemp as JMQ,rm as XMQ}from"fs/promises";import{tmpdir as WMQ}from"os";import{join as HMQ}from"path";WA();var GMQ=26214400,KMQ=60000,cF1=20;class QgA{context;renderPdf;getThemeMode;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??WX,this.getThemeMode=Q.getThemeMode??(async()=>"dark")}async resolve(A){if(A.sourceEntityType!=="deck")return;let Q=await this.context.entityService.getEntity({entityType:"deck",id:A.sourceEntityId});if(!Q)return;let B=FMQ(Q,{brandLabel:this.resolveBrandLabel()});if(B.slides.length>cF1)throw Error(`Refusing to render carousel with ${B.slides.length} slides; maxSlides=${cF1}`);let w=await this.getThemeMode(),$=await JMQ(HMQ(WMQ(),"brain-deck-carousel-"));try{let f=await VD({outputDir:$,mediaPath:`/_media/carousel/${Q.id}`,template:uF1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:w},themeCSS:this.context.themeCSS}),I=await ED({rootDir:$});try{return{type:"document",data:await this.renderPdf(I.urlFor(f.urlPath),{maxBytes:GMQ,timeoutMs:KMQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${ZMQ(Q)}-carousel.pdf`}}finally{await I.close()}}finally{await XMQ($,{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 FMQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=typeof B.title==="string"?B.title:A.metadata.title,f=typeof B.event==="string"&&B.event.length>0?B.event:void 0,I=w.split(/^---$/gm).map((D)=>D.trim()).filter((D)=>D.length>0).map((D)=>({markdown:D}));return{title:$,slides:I,...Q.brandLabel?{brandLabel:Q.brandLabel}:{},...f?{eyebrow:f}:{}}}function ZMQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}WA();import{jsxDEV as qMQ}from"preact/jsx-dev-runtime";var O5A="og-image",NMQ="decks:og-image",lF1=H.object({title:H.string().min(1),description:H.string().optional(),event:H.string().optional(),brandLabel:H.string().optional(),slideCount:H.number().int().positive().optional(),coverImageUrl:H.string().optional()}),pF1={name:NMQ,pluginId:"decks",schema:lF1,renderers:{image:zMQ}};function zMQ(A){let Q=lF1.parse(A),B=Q.slideCount?`${Q.slideCount} slide${Q.slideCount===1?"":"s"}`:void 0;return qMQ(CF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Deck",title:Q.title,subtitle:Q.description,meta:[Q.event],tag:B},void 0,!1,void 0,this)}WA();class BgA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="deck"||A.attachmentType!==O5A)return;let Q=await this.context.entityService.getEntity({entityType:"deck",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B,content:w}=jB(Q.content),$=tU.parse(B),f=LMQ(w),I=this.resolveBrandLabel(),D=await this.resolveCoverImageUrl($.coverImageId),U={title:$.title,...$.description?{description:$.description}:{},...$.event?{event:$.event}:{},...f?{slideCount:f}:{},...D?{coverImageUrl:D}:{},...I?{brandLabel:I}:{}};return{type:"image",data:await YC({mediaPath:`/_media/og/deck/${Q.id}`,template:pF1,content:U,title:U.title,themeMode:"dark",themeCSS:this.context.themeCSS,tmpPrefix:"brain-deck-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${VMQ(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 LMQ(A){return A.split(/^---$/gm).map((Q)=>Q.trim()).filter((Q)=>Q.length>0).length}function VMQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}aA();async function iF1({entity:A,config:Q}){let B=Vv.parse(A),w=b2(B.content,tU),$=w.metadata;return{$type:"ai.rizom.brain.deck",title:$.title,...$.slug&&{slug:$.slug},...$.description&&{description:$.description},body:w.content,format:"text/markdown",...$.author&&{author:$.author},...$.event&&{event:$.event},...$.publishedAt&&{publishedAt:$.publishedAt},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"deck",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function wgA(){return{entityType:"deck",collection:"ai.rizom.brain.deck",lexicon:Kw["ai.rizom.brain.deck"],validate:!1,buildRecord:iF1}}var rF1={name:"@brains/decks",private:!0,version:"0.2.0-alpha.
|
|
6198
|
+
`}},void 0,!1,void 0,this),$.map((Y,J)=>c7("section",{className:`deck-carousel-slide${J===0?" is-cover":""}`,children:[c7("header",{className:"deck-carousel-header",children:c7("span",{className:"deck-carousel-wordmark","aria-label":B??Q,children:[c7("span",{className:"wm-primary",children:f.primary},void 0,!1,void 0,this),f.secondary!==void 0&&c7(YMQ,{children:[c7("span",{className:"wm-dot",children:"."},void 0,!1,void 0,this),c7("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),c7("div",{className:"deck-carousel-body",children:c7("div",{className:"deck-carousel-content",dangerouslySetInnerHTML:{__html:U(Y.markdown)}},void 0,!1,void 0,this)},void 0,!1,void 0,this),c7("footer",{className:"deck-carousel-footer",children:[c7("span",{className:"deck-carousel-footer-meta",children:w??Q},void 0,!1,void 0,this),c7("span",{className:"deck-carousel-counter","aria-label":`Slide ${J+1} of ${I}`,children:[c7("span",{className:"deck-carousel-counter-current",children:String(J+1).padStart(2,"0")},void 0,!1,void 0,this)," / ",c7("span",{children:D},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},J,!0,void 0,this))]},void 0,!0,void 0,this)}import{mkdtemp as JMQ,rm as XMQ}from"fs/promises";import{tmpdir as WMQ}from"os";import{join as HMQ}from"path";WA();var GMQ=26214400,KMQ=60000,cF1=20;class QgA{context;renderPdf;getThemeMode;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??WX,this.getThemeMode=Q.getThemeMode??(async()=>"dark")}async resolve(A){if(A.sourceEntityType!=="deck")return;let Q=await this.context.entityService.getEntity({entityType:"deck",id:A.sourceEntityId});if(!Q)return;let B=FMQ(Q,{brandLabel:this.resolveBrandLabel()});if(B.slides.length>cF1)throw Error(`Refusing to render carousel with ${B.slides.length} slides; maxSlides=${cF1}`);let w=await this.getThemeMode(),$=await JMQ(HMQ(WMQ(),"brain-deck-carousel-"));try{let f=await VD({outputDir:$,mediaPath:`/_media/carousel/${Q.id}`,template:uF1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:w},themeCSS:this.context.themeCSS}),I=await ED({rootDir:$});try{return{type:"document",data:await this.renderPdf(I.urlFor(f.urlPath),{maxBytes:GMQ,timeoutMs:KMQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${ZMQ(Q)}-carousel.pdf`}}finally{await I.close()}}finally{await XMQ($,{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 FMQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=typeof B.title==="string"?B.title:A.metadata.title,f=typeof B.event==="string"&&B.event.length>0?B.event:void 0,I=w.split(/^---$/gm).map((D)=>D.trim()).filter((D)=>D.length>0).map((D)=>({markdown:D}));return{title:$,slides:I,...Q.brandLabel?{brandLabel:Q.brandLabel}:{},...f?{eyebrow:f}:{}}}function ZMQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}WA();import{jsxDEV as qMQ}from"preact/jsx-dev-runtime";var O5A="og-image",NMQ="decks:og-image",lF1=H.object({title:H.string().min(1),description:H.string().optional(),event:H.string().optional(),brandLabel:H.string().optional(),slideCount:H.number().int().positive().optional(),coverImageUrl:H.string().optional()}),pF1={name:NMQ,pluginId:"decks",schema:lF1,renderers:{image:zMQ}};function zMQ(A){let Q=lF1.parse(A),B=Q.slideCount?`${Q.slideCount} slide${Q.slideCount===1?"":"s"}`:void 0;return qMQ(CF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Deck",title:Q.title,subtitle:Q.description,meta:[Q.event],tag:B},void 0,!1,void 0,this)}WA();class BgA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="deck"||A.attachmentType!==O5A)return;let Q=await this.context.entityService.getEntity({entityType:"deck",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B,content:w}=jB(Q.content),$=tU.parse(B),f=LMQ(w),I=this.resolveBrandLabel(),D=await this.resolveCoverImageUrl($.coverImageId),U={title:$.title,...$.description?{description:$.description}:{},...$.event?{event:$.event}:{},...f?{slideCount:f}:{},...D?{coverImageUrl:D}:{},...I?{brandLabel:I}:{}};return{type:"image",data:await YC({mediaPath:`/_media/og/deck/${Q.id}`,template:pF1,content:U,title:U.title,themeMode:"dark",themeCSS:this.context.themeCSS,tmpPrefix:"brain-deck-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${VMQ(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 LMQ(A){return A.split(/^---$/gm).map((Q)=>Q.trim()).filter((Q)=>Q.length>0).length}function VMQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}aA();async function iF1({entity:A,config:Q}){let B=Vv.parse(A),w=b2(B.content,tU),$=w.metadata;return{$type:"ai.rizom.brain.deck",title:$.title,...$.slug&&{slug:$.slug},...$.description&&{description:$.description},body:w.content,format:"text/markdown",...$.author&&{author:$.author},...$.event&&{event:$.event},...$.publishedAt&&{publishedAt:$.publishedAt},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"deck",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function wgA(){return{entityType:"deck",collection:"ai.rizom.brain.deck",lexicon:Kw["ai.rizom.brain.deck"],validate:!1,buildRecord:iF1}}var rF1={name:"@brains/decks",private:!0,version:"0.2.0-alpha.127",description:"Presentation decks plugin for creating and viewing slide presentations",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/image":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/site-info":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class $gA extends _Q{deps;entityType=Ki.entityType;schema=Ki.schema;adapter=Ki;unregisterCarouselAttachmentProvider;unregisterOgImageAttachmentProvider;unregisterAtprotoProjection;constructor(A={}){super("decks",rF1);this.deps=A}createGenerationHandler(A){return new AgA(this.logger.child("DeckGenerationJobHandler"),A)}getTemplates(){return{"deck-detail":dSA,"deck-list":tSA,generation:SF1,description:gF1}}getDataSources(){return[new eSA(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=o6.getInstance().register(wgA()),this.logger.info("Decks plugin registered")}async onShutdown(){this.unregisterCarouselAttachmentProvider?.(),this.unregisterCarouselAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0,this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}deferPublishRegistration(A){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"publish:register",payload:{entityType:"deck",provider:{name:"internal",publish:async()=>({id:"internal"})},config:{executionMode:"provider"}}}),{success:!0}})}subscribeToPublishExecute(A){A.messaging.subscribe("publish:execute",async(Q)=>{let{entityType:B,entityId:w}=Q.payload;if(B!=="deck")return{success:!0};try{let $=await A.entityService.getEntity({entityType:"deck",id:w});if(!$)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:`Deck not found: ${w}`}}),{success:!0};if($.metadata.status==="published")return{success:!0};let f=new Date().toISOString(),I={...$,metadata:{...$.metadata,status:"published",publishedAt:f}};await A.entityService.updateEntity({entity:{...I,content:this.adapter.toMarkdown(I)}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,result:{id:w}}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:y0($)}})}return{success:!0}})}registerCarouselAttachmentProvider(A){let Q={...this.deps,getThemeMode:this.deps.getThemeMode??(async()=>{try{return(await Di(A.entityService)).themeMode??"dark"}catch{return"dark"}})};this.unregisterCarouselAttachmentProvider=A.attachments.register("deck",hF1,new QgA(A,Q))}registerOgImageAttachmentProvider(A){this.unregisterOgImageAttachmentProvider=A.attachments.register("deck",O5A,new BgA(A))}registerEvalHandlers(A){A.eval.registerHandler("generateDeck",async(Q)=>{let B=H.object({prompt:H.string(),event:H.string().optional()}).parse(Q);return A.ai.generate({prompt:`${B.prompt}${B.event?`
|
|
6199
6199
|
|
|
6200
6200
|
Note: This presentation is for "${B.event}".`:""}`,templateName:"decks:generation"})}),A.eval.registerHandler("generateDescription",async(Q)=>{let B=H.object({title:H.string(),content:H.string()}).parse(Q);return A.ai.generate({prompt:`Title: ${B.title}
|
|
6201
6201
|
|
|
6202
6202
|
Content:
|
|
6203
6203
|
${B.content}`,templateName:"decks:description"})})}}function Zi(){return new $gA}aA();WA();WA();J8();var fgA=H.literal("application/pdf"),dF1=H.enum(["pending","draft","failed"]),IgA=H.object({title:H.string().optional(),mimeType:fgA,filename:H.string().min(1),pageCount:H.number().int().min(0).optional(),status:dF1.optional(),processingJobId:H.string().optional(),processingError:H.string().optional(),sourceEntityType:H.string().min(1).optional(),sourceEntityId:H.string().min(1).optional(),sourceUploadId:H.string().optional(),sourceFilename:H.string().optional(),sourceMediaType:H.string().optional(),attachmentType:H.string().min(1).optional(),dedupKey:H.string().min(1).optional()}),Ev=A2.extend({entityType:H.literal("document"),content:H.string().regex(/^data:application\/pdf;base64,.+$/),metadata:IgA});function Ni(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 R5A(A){return`data:application/pdf;base64,${Buffer.from(A).toString("base64")}`}function DgA(A){let Q=Buffer.from(A).toString("latin1"),B=0,w=/\/Type\s*\/Pages\b[^]*?\/Count\s+(\d+)|\/Count\s+(\d+)[^]*?\/Type\s*\/Pages\b/g;for(let f of Q.matchAll(w)){let I=parseInt(f[1]??f[2]??"0",10);if(I>B)B=I}if(B>0)return B;return Q.match(/\/Type\s*\/Page(?!\w)/g)?.length??0}class b5A{entityType="document";schema=Ev;toMarkdown(A){return A.content}fromMarkdown(A){return Ni(A),{entityType:"document",content:A}}extractMetadata(A){return A.metadata}parseFrontMatter(A,Q){return Q.parse({})}generateFrontMatter(A){return""}getBodyTemplate(){return""}createDocumentEntity(A){let{dataUrl:Q,...B}=A,{mimeType:w}=Ni(Q);return{entityType:"document",content:Q,metadata:{mimeType:w,...B}}}}var iF=new b5A;async function igA(A,Q={}){let B=Q.maxBytes??5000000;if(A.byteLength>B)throw Error(`Uploaded PDF is too large for synchronous markdown extraction (${A.byteLength} bytes; max ${B} bytes)`);let $=await(await Promise.resolve().then(() => (B31(),Q31))).getDocument({data:new Uint8Array(A),disableFontFace:!1,useSystemFonts:!0,useWorkerFetch:!1}).promise;try{let f=Q.maxPages??50;if($.numPages>f)throw Error(`Uploaded PDF has ${$.numPages} pages; maximum supported for synchronous markdown extraction is ${f}`);let I=[];for(let U=1;U<=$.numPages;U+=1){let X=(await(await $.getPage(U)).getTextContent()).items.flatMap((G)=>("str"in G)?[G.str]:[]).join(" ").replace(/\s+/g," ").trim();if(X.length>0)I.push(X)}let D=I.join(`
|
|
6204
6204
|
|
|
6205
|
-
`).trim();if(!D)throw Error("Could not extract text from the uploaded PDF");return D}finally{await $.destroy()}}aA();WA();import{createHash as ICQ}from"crypto";var DCQ=26214400,UCQ=20,YCQ=60000,w31=80,JCQ=10,K$A=H.object({renderUrl:H.string().url().optional(),sourceEntityType:H.string().min(1),sourceEntityId:H.string().min(1),attachmentType:H.string().min(1),documentId:H.string().min(1).optional(),title:H.string().min(1).optional(),filename:H.string().min(1).optional(),dedupKey:H.string().min(1).optional(),replace:H.boolean().optional(),pageCount:H.number().int().min(0).optional(),maxPageCount:H.number().int().positive().optional(),maxBytes:H.number().int().positive().optional(),timeoutMs:H.number().int().positive().optional(),width:H.union([H.string(),H.number()]).optional(),height:H.union([H.string(),H.number()]).optional(),format:H.string().optional(),targetEntityType:H.string().min(1).optional(),targetEntityId:H.string().min(1).optional()}),Sv=K$A.refine((A)=>A.targetEntityType===void 0&&A.targetEntityId===void 0||A.targetEntityType!==void 0&&A.targetEntityId!==void 0,{message:"targetEntityType and targetEntityId must be provided together",path:["targetEntityId"]});class F$A extends ZB{context;renderPdf;constructor(A,Q,B={}){super(A,{schema:Sv,jobTypeName:"document-generate"});this.context=Q;this.renderPdf=B.renderPdf??WX}async getDedupKey(A){if(A.dedupKey!==void 0)return A.dedupKey;if(A.renderUrl!==void 0)return`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl}`;let Q=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:resolved-attachment`,B=await this.context.entityService.getEntity({entityType:A.sourceEntityType,id:A.sourceEntityId});return B?`${Q}:${B.contentHash}`:Q}async process(A,Q,B){this.logger.debug("Starting document generation job",{jobId:Q,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});let w=A.maxPageCount??UCQ,$=A.maxBytes??DCQ,f=A.timeoutMs??YCQ;if(A.pageCount!==void 0&&A.pageCount>w)throw Error(`Refusing to render ${A.pageCount} page PDF; maxPageCount=${w}`);let I=await this.getDedupKey(A),D=pi(A,I),U=A.documentId!==void 0||A.filename!==void 0;if(A.replace!==!0){let Y=await this.findDocumentByDedupKey(I,U?D:void 0);if(Y&&(!U||Y.id===D)){if(A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,Y.id,A);return await this.reportProgress(B,{progress:100,message:"Reusing existing generated document"}),{success:!0,documentId:Y.id,reused:!0}}}await this.reportProgress(B,{progress:20,message:"Rendering PDF document"});try{let Y=await this.resolveDocumentAttachment(A,D,{timeoutMs:f,maxBytes:$}),J=Y.data;if(J.byteLength>$)throw Error(`Rendered PDF exceeds maxBytes=${$}: ${J.byteLength} bytes`);let X=DgA(J);if(X>w)throw Error(`Rendered PDF has ${X} pages, exceeding maxPageCount=${w}`);let G=X>0?X:A.pageCount;await this.reportProgress(B,{progress:70,message:"Storing PDF document"});let Z=A.filename??(A.renderUrl===void 0?Y.filename:`${D}.pdf`),N=iF.createDocumentEntity({dataUrl:R5A(J),filename:Z,...A.title&&{title:A.title},...G!==void 0&&{pageCount:G},status:"draft",sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,dedupKey:I});if(await kI({entityService:this.context.entityService,entity:{...N,id:D}}),A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,D,A);return await this.reportProgress(B,{progress:100,message:"PDF document generation complete"}),{success:!0,documentId:D,reused:!1}}catch(Y){let J=y0(Y);throw this.logger.error("Document generation failed",{jobId:Q,error:J}),await fW({entityService:this.context.entityService,entityType:"document",id:D,error:J}),Y}}async resolveDocumentAttachment(A,Q,B){if(A.renderUrl!==void 0)return{type:"document",data:await this.renderPdf(A.renderUrl,{timeoutMs:B.timeoutMs,maxBytes:B.maxBytes,printBackground:!0,preferCSSPageSize:!0,...A.width!==void 0&&{width:A.width},...A.height!==void 0&&{height:A.height},...A.format!==void 0&&{format:A.format}}),mimeType:"application/pdf",filename:A.filename??`${Q}.pdf`};let w=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!w)throw Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`);if(w.type!=="document")throw Error(`Attachment provider returned ${w.type}; expected document`);return w}async findDocumentByDedupKey(A,Q){let B=await this.context.entityService.listEntities({entityType:"document",options:{filter:{metadata:{dedupKey:A}}}});if(B.length>1)this.logger.warn("Multiple documents share dedupKey; using first",{dedupKey:A,count:B.length,ids:B.map(($)=>$.id),preferredDocumentId:Q});let w=B.filter(($)=>$.metadata.status!=="pending"&&$.metadata.status!=="failed");return w.find(($)=>$.id===Q)??w[0]}async attachDocumentToTarget(A,Q,B,w){let $=await this.context.entityService.getEntity({entityType:A,id:Q});if(!$)throw Error(`Target entity not found: ${A}/${Q}`);let{frontmatter:f}=jB($.content),I=Array.isArray(f.documents)?f.documents.filter(WCQ):[],D=w.replace?await this.removeReferencesForSameSourceAttachment(I,B,w):I,U=D.some((Y)=>Y.id===B)?D:[...D,{id:B}];await this.context.entityService.updateEntity({entity:{...$,content:X4($.content,"documents",U)}})}async removeReferencesForSameSourceAttachment(A,Q,B){let w=[];for(let $ of A){if($.id===Q){w.push($);continue}let f=await this.context.entityService.getEntity({entityType:"document",id:$.id});if(!f||!HCQ(f,B))w.push($)}return w}}function pi(A,Q){let B=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl??"resolved-attachment"}`,w=A.documentId??A.filename?.replace(/\.pdf$/i,"")??Q??B,$=A.replace===!0&&A.documentId===void 0?`${w}-${Date.now()}`:w;return XCQ($)}function XCQ(A){let Q=X1(A.replace(/[/:]+/g," "))||`document-${$31(A)}`;if(Q.length<=w31)return Q;let B=`-${$31(A)}`;return`${Q.slice(0,w31-B.length).replace(/-+$/g,"")}${B}`}function $31(A){return ICQ("sha256").update(A).digest("hex").slice(0,JCQ)}function WCQ(A){return typeof A==="object"&&A!==null&&"id"in A&&typeof A.id==="string"&&A.id.length>0}function HCQ(A,Q){return A.metadata.sourceEntityType===Q.sourceEntityType&&A.metadata.sourceEntityId===Q.sourceEntityId&&A.metadata.attachmentType===Q.attachmentType}aA();function rgA(A,Q){return[oQ(A,"generate",'Preview or prepare a PDF document attachment from a source attachment or render URL. For save/regenerate durable document requests, including deck carousel PDFs and printable post/project/product PDFs, prefer system_create with entityType: "document" and from.',K$A,async(B,w)=>{let $=Sv.safeParse(B);if(!$.success)return H$($.error.message);let f=pi($.data),I=await Q({...$.data,documentId:f},w),D=$.data.filename??`${f}.pdf`;return Y8({jobId:I,documentId:f,attachment:{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${encodeURIComponent(f)}`,downloadUrl:`/api/chat/attachments/document?id=${encodeURIComponent(f)}&download=1`,filename:D,source:{entityType:"document",entityId:f,attachmentType:$.data.attachmentType}}})},{cli:{name:"document-generate"}})]}var f31={name:"@brains/document-plugin",private:!0,version:"0.2.0-alpha.
|
|
6205
|
+
`).trim();if(!D)throw Error("Could not extract text from the uploaded PDF");return D}finally{await $.destroy()}}aA();WA();import{createHash as ICQ}from"crypto";var DCQ=26214400,UCQ=20,YCQ=60000,w31=80,JCQ=10,K$A=H.object({renderUrl:H.string().url().optional(),sourceEntityType:H.string().min(1),sourceEntityId:H.string().min(1),attachmentType:H.string().min(1),documentId:H.string().min(1).optional(),title:H.string().min(1).optional(),filename:H.string().min(1).optional(),dedupKey:H.string().min(1).optional(),replace:H.boolean().optional(),pageCount:H.number().int().min(0).optional(),maxPageCount:H.number().int().positive().optional(),maxBytes:H.number().int().positive().optional(),timeoutMs:H.number().int().positive().optional(),width:H.union([H.string(),H.number()]).optional(),height:H.union([H.string(),H.number()]).optional(),format:H.string().optional(),targetEntityType:H.string().min(1).optional(),targetEntityId:H.string().min(1).optional()}),Sv=K$A.refine((A)=>A.targetEntityType===void 0&&A.targetEntityId===void 0||A.targetEntityType!==void 0&&A.targetEntityId!==void 0,{message:"targetEntityType and targetEntityId must be provided together",path:["targetEntityId"]});class F$A extends ZB{context;renderPdf;constructor(A,Q,B={}){super(A,{schema:Sv,jobTypeName:"document-generate"});this.context=Q;this.renderPdf=B.renderPdf??WX}async getDedupKey(A){if(A.dedupKey!==void 0)return A.dedupKey;if(A.renderUrl!==void 0)return`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl}`;let Q=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:resolved-attachment`,B=await this.context.entityService.getEntity({entityType:A.sourceEntityType,id:A.sourceEntityId});return B?`${Q}:${B.contentHash}`:Q}async process(A,Q,B){this.logger.debug("Starting document generation job",{jobId:Q,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});let w=A.maxPageCount??UCQ,$=A.maxBytes??DCQ,f=A.timeoutMs??YCQ;if(A.pageCount!==void 0&&A.pageCount>w)throw Error(`Refusing to render ${A.pageCount} page PDF; maxPageCount=${w}`);let I=await this.getDedupKey(A),D=pi(A,I),U=A.documentId!==void 0||A.filename!==void 0;if(A.replace!==!0){let Y=await this.findDocumentByDedupKey(I,U?D:void 0);if(Y&&(!U||Y.id===D)){if(A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,Y.id,A);return await this.reportProgress(B,{progress:100,message:"Reusing existing generated document"}),{success:!0,documentId:Y.id,reused:!0}}}await this.reportProgress(B,{progress:20,message:"Rendering PDF document"});try{let Y=await this.resolveDocumentAttachment(A,D,{timeoutMs:f,maxBytes:$}),J=Y.data;if(J.byteLength>$)throw Error(`Rendered PDF exceeds maxBytes=${$}: ${J.byteLength} bytes`);let X=DgA(J);if(X>w)throw Error(`Rendered PDF has ${X} pages, exceeding maxPageCount=${w}`);let G=X>0?X:A.pageCount;await this.reportProgress(B,{progress:70,message:"Storing PDF document"});let Z=A.filename??(A.renderUrl===void 0?Y.filename:`${D}.pdf`),N=iF.createDocumentEntity({dataUrl:R5A(J),filename:Z,...A.title&&{title:A.title},...G!==void 0&&{pageCount:G},status:"draft",sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,dedupKey:I});if(await kI({entityService:this.context.entityService,entity:{...N,id:D}}),A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,D,A);return await this.reportProgress(B,{progress:100,message:"PDF document generation complete"}),{success:!0,documentId:D,reused:!1}}catch(Y){let J=y0(Y);throw this.logger.error("Document generation failed",{jobId:Q,error:J}),await fW({entityService:this.context.entityService,entityType:"document",id:D,error:J}),Y}}async resolveDocumentAttachment(A,Q,B){if(A.renderUrl!==void 0)return{type:"document",data:await this.renderPdf(A.renderUrl,{timeoutMs:B.timeoutMs,maxBytes:B.maxBytes,printBackground:!0,preferCSSPageSize:!0,...A.width!==void 0&&{width:A.width},...A.height!==void 0&&{height:A.height},...A.format!==void 0&&{format:A.format}}),mimeType:"application/pdf",filename:A.filename??`${Q}.pdf`};let w=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!w)throw Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`);if(w.type!=="document")throw Error(`Attachment provider returned ${w.type}; expected document`);return w}async findDocumentByDedupKey(A,Q){let B=await this.context.entityService.listEntities({entityType:"document",options:{filter:{metadata:{dedupKey:A}}}});if(B.length>1)this.logger.warn("Multiple documents share dedupKey; using first",{dedupKey:A,count:B.length,ids:B.map(($)=>$.id),preferredDocumentId:Q});let w=B.filter(($)=>$.metadata.status!=="pending"&&$.metadata.status!=="failed");return w.find(($)=>$.id===Q)??w[0]}async attachDocumentToTarget(A,Q,B,w){let $=await this.context.entityService.getEntity({entityType:A,id:Q});if(!$)throw Error(`Target entity not found: ${A}/${Q}`);let{frontmatter:f}=jB($.content),I=Array.isArray(f.documents)?f.documents.filter(WCQ):[],D=w.replace?await this.removeReferencesForSameSourceAttachment(I,B,w):I,U=D.some((Y)=>Y.id===B)?D:[...D,{id:B}];await this.context.entityService.updateEntity({entity:{...$,content:X4($.content,"documents",U)}})}async removeReferencesForSameSourceAttachment(A,Q,B){let w=[];for(let $ of A){if($.id===Q){w.push($);continue}let f=await this.context.entityService.getEntity({entityType:"document",id:$.id});if(!f||!HCQ(f,B))w.push($)}return w}}function pi(A,Q){let B=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl??"resolved-attachment"}`,w=A.documentId??A.filename?.replace(/\.pdf$/i,"")??Q??B,$=A.replace===!0&&A.documentId===void 0?`${w}-${Date.now()}`:w;return XCQ($)}function XCQ(A){let Q=X1(A.replace(/[/:]+/g," "))||`document-${$31(A)}`;if(Q.length<=w31)return Q;let B=`-${$31(A)}`;return`${Q.slice(0,w31-B.length).replace(/-+$/g,"")}${B}`}function $31(A){return ICQ("sha256").update(A).digest("hex").slice(0,JCQ)}function WCQ(A){return typeof A==="object"&&A!==null&&"id"in A&&typeof A.id==="string"&&A.id.length>0}function HCQ(A,Q){return A.metadata.sourceEntityType===Q.sourceEntityType&&A.metadata.sourceEntityId===Q.sourceEntityId&&A.metadata.attachmentType===Q.attachmentType}aA();function rgA(A,Q){return[oQ(A,"generate",'Preview or prepare a PDF document attachment from a source attachment or render URL. For save/regenerate durable document requests, including deck carousel PDFs and printable post/project/product PDFs, prefer system_create with entityType: "document" and from.',K$A,async(B,w)=>{let $=Sv.safeParse(B);if(!$.success)return H$($.error.message);let f=pi($.data),I=await Q({...$.data,documentId:f},w),D=$.data.filename??`${f}.pdf`;return Y8({jobId:I,documentId:f,attachment:{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${encodeURIComponent(f)}`,downloadUrl:`/api/chat/attachments/document?id=${encodeURIComponent(f)}&download=1`,filename:D,source:{entityType:"document",entityId:f,attachmentType:$.data.attachmentType}}})},{cli:{name:"document-generate"}})]}var f31={name:"@brains/document-plugin",private:!0,version:"0.2.0-alpha.127",description:"Document entity type for generated PDFs and publishable document attachments",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/document":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/typescript-config":"workspace:*","bun-types":"latest",typescript:"^5.3.3"}};var KCQ=`data:application/pdf;base64,${Buffer.from(`%PDF-1.4
|
|
6206
6206
|
% Pending document placeholder
|
|
6207
6207
|
%%EOF
|
|
6208
6208
|
`).toString("base64")}`,FCQ=H.object({}),dgA={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};function ZCQ(A,Q){let B=A.title?.trim();if(B)return B;return Q.replace(/\.[^.]+$/,"").trim()||Q}function NCQ(A,Q){return`data:${A};base64,${Q.toString("base64")}`}function zCQ(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 ngA extends YB{entityType=iF.entityType;schema=Ev;adapter=iF;pluginContext;constructor(){super("document",f31,{},FCQ)}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 B=await this.promoteUpload({entityType:this.entityType,...Q.title!==void 0?{title:Q.title}:{},from:Q.upload},A);return B.kind==="handled"?B.result:{success:!1,error:"Document upload save was not handled"}}}),A.jobs.registerHandler("generate",new F$A(this.logger.child("DocumentGenerationJobHandler"),A))}async interceptCreate(A){let Q=this.pluginContext;if(A.from?.kind===dgA.refKind){if(!Q)return{kind:"handled",result:{success:!1,error:"Plugin context not initialized"}};return this.promoteUpload(A,Q)}if(!A.from)return{kind:"continue",input:A};if(!Q)return{kind:"handled",result:{success:!1,error:"Plugin context not initialized"}};let B=Sv.parse({sourceEntityType:A.from.sourceEntityType,sourceEntityId:A.from.sourceEntityId,attachmentType:A.from.attachmentType,...A.title&&{title:A.title},...A.replace===!0&&{replace:!0},...A.targetEntityType&&{targetEntityType:A.targetEntityType},...A.targetEntityId&&{targetEntityId:A.targetEntityId}}),w=await this.getDedupKey(B,Q),$=B.replace===!0?void 0:await this.findExistingDocument(w,Q),f=$?.id??pi(B,w);if(!$)await this.createPendingDocument(Q,{id:f,title:B.title??f,filename:`${f}.pdf`,sourceEntityType:B.sourceEntityType,sourceEntityId:B.sourceEntityId,attachmentType:B.attachmentType,dedupKey:w});let I=await Q.jobs.enqueue({type:"generate",data:{...B,dedupKey:w,documentId:f}}),D=`${f}.pdf`;return{kind:"handled",result:{success:!0,data:{entityId:f,jobId:I,status:"generating",attachment:{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${encodeURIComponent(f)}`,downloadUrl:`/api/chat/attachments/document?id=${encodeURIComponent(f)}&download=1`,filename:D,source:{entityType:"document",entityId:f,attachmentType:B.attachmentType}}}}}}async promoteUpload(A,Q){let B=A.from;if(B?.kind!==dgA.refKind)return{kind:"handled",result:{success:!1,error:"Unsupported upload ref kind"}};let w;try{w=await Q.uploads.scoped(dgA).read(B.id)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}if(w.record.mediaType!=="application/pdf")return{kind:"handled",result:{success:!1,error:"Only PDF uploads can be promoted to document entities"}};let $=ZCQ(A,w.record.filename),f=X1($);if(!f)return{kind:"handled",result:{success:!1,error:"Could not derive a document id from the uploaded filename. Provide a title."}};let I=new Date().toISOString(),D=iF.createDocumentEntity({dataUrl:NCQ(w.record.mediaType,w.content),filename:w.record.filename,title:$,status:"draft",sourceUploadId:B.id,sourceFilename:w.record.filename,sourceMediaType:w.record.mediaType,attachmentType:"uploaded",dedupKey:`upload:${B.kind}:${B.id}`}),U=await Q.entityService.createEntity({entity:{id:f,...D,created:I,updated:I},options:{deduplicateId:!0}});return{kind:"handled",result:{success:!0,data:{entityId:U.entityId,status:"created",attachment:zCQ({entityId:U.entityId,filename:w.record.filename})}}}}async createPendingDocument(A,Q){let B=new Date().toISOString(),w=iF.createDocumentEntity({dataUrl:KCQ,filename:Q.filename,title:Q.title,status:"pending",sourceEntityType:Q.sourceEntityType,sourceEntityId:Q.sourceEntityId,attachmentType:Q.attachmentType,dedupKey:Q.dedupKey});await TL({entityService:A.entityService,entity:{id:Q.id,...w,created:B,updated:B}})}async getDedupKey(A,Q){if(A.dedupKey!==void 0)return A.dedupKey;if(A.renderUrl!==void 0)return`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl}`;let B=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:resolved-attachment`,w=await Q.entityService.getEntity({entityType:A.sourceEntityType,id:A.sourceEntityId});return w?`${B}:${w.contentHash}`:B}async findExistingDocument(A,Q){return(await Q.entityService.listEntities({entityType:"document",options:{filter:{metadata:{dedupKey:A}}}}))[0]}async getInstructions(){return'For durable raw PDF saves/promotions from uploaded PDFs, call system_upload_save with the exact upload object shown in the current turn or conversation "Available upload refs" hint. Do this only after the user explicitly asks to save/import/promote the raw PDF as a document. If that hint is absent, omit upload entirely; never invent upload IDs or placeholder upload refs. Uploaded PDFs are not decks; raw upload promotion preserves the PDF as a document. Do not use entityType: "note" or transform: "extract-markdown" unless the user asks to turn the upload into a note/markdown. For generated/source-derived PDFs, call system_create with entityType: "document" and sourceAttachment. Deck carousel PDFs use sourceAttachment: { sourceEntityType: "deck", sourceEntityId: <deck ID>, attachmentType: "carousel" }. Printable PDFs for blog posts, projects, and products use sourceAttachment with attachmentType: "printable" and sourceEntityType "post", "project", or "product". Omit upload and sourceAttachment entirely for ordinary direct document creates that use content, prompt, or url. Include targetEntityType/targetEntityId when the user asks to attach the saved document to another entity. Use replace: true when they ask to regenerate or replace a saved PDF. Only use document_generate for explicit preview/prepare requests where they need an immediate PDF attachment. Do not use generic attachment types like "document".'}async getTools(){let A=this.pluginContext;if(!A)throw Error("Plugin context not initialized");return rgA(this.id,(Q,B)=>A.jobs.enqueue({type:"generate",data:Q,toolContext:B}))}}function ogA(){return new ngA}aA();WA();WA();aA();var qCQ=H.enum(["generating","failed"]),sF=H.object({title:H.string().optional(),status:qCQ.optional(),error:H.string().optional()}),I31=sF.pick({title:!0,status:!0,error:!0}).extend({title:H.string()}),sz=A2.extend({entityType:H.literal("note"),metadata:I31}),LCQ=sz.extend({frontmatter:sF,body:H.string()});aA();WA();class sgA extends q2{constructor(){super({entityType:"note",schema:sz,frontmatterSchema:sF})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,sF);if(B.title)return this.buildMarkdown(Q,B)}catch{}return Q}fromMarkdown(A){let Q=this.parseMarkdownFrontmatter(A),B=Q.title??this.extractH1(A)??"Untitled";return{content:A,entityType:"note",metadata:{title:B,...Q.status&&{status:Q.status},...Q.error&&{error:Q.error}}}}parseNoteFrontmatter(A){return this.parseMarkdownFrontmatter(A.content)}parseMarkdownFrontmatter(A){try{return this.parseFrontMatter(A,sF)}catch{return{}}}buildStub(A){let Q={title:A.title,status:"generating"};return{content:this.buildMarkdown("",Q),metadata:{title:A.title,status:"generating"}}}createNoteContent(A,Q){try{let B=this.parseFrontMatter(Q,H.record(H.unknown()));if(Object.keys(B).length===0)return Q;let w={...B,title:B.title??A},$=this.extractBody(Q);return this.buildMarkdown($,w)}catch{return Q}}extractH1(A){return A.match(/^#\s+(.+)$/m)?.[1]?.trim()??null}}var az=new sgA;WA();var agA=H.object({defaultPrompt:H.string().default("Create a note summarizing key concepts from my knowledge base")});WA();aA();var D31=H.object({title:H.string().max(80).describe("A clear, descriptive title for the note (3-8 words)"),body:H.string().describe("Note content in markdown format with clear organization and structure")}),tgA=P1({name:"note:generation",description:"Template for AI to generate notes from prompts",schema:D31,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create personal knowledge notes for research and reference.
|
|
@@ -6220,7 +6220,7 @@ title: ${JSON.stringify(A)}
|
|
|
6220
6220
|
---
|
|
6221
6221
|
|
|
6222
6222
|
${Q.trim()}
|
|
6223
|
-
`}var OCQ={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"},RCQ=H.object({uploadId:H.string().min(1),title:H.string().optional()});class AhA extends ZB{context;constructor(A,Q){super(A,{schema:RCQ,jobTypeName:"upload-import"});this.context=Q}async process(A,Q,B){await this.reportProgress(B,{progress:10,message:"Reading uploaded file"});let w=await this.context.uploads.scoped(OCQ).read(A.uploadId);await this.reportProgress(B,{progress:35,message:"Extracting markdown from upload"});let $=await X31({upload:w,...A.title!==void 0?{title:A.title}:{}});await this.reportProgress(B,{progress:80,message:"Saving imported note"});let f=new Date().toISOString(),I=az.fromMarkdown($.content),D=await this.context.entityService.createEntity({entity:{id:$.id,entityType:"note",content:$.content,metadata:{title:$.title,...I.metadata},created:f,updated:f},options:{deduplicateId:!0}});return await this.reportProgress(B,{progress:100,message:"Upload imported as markdown note"}),{entityId:D.entityId,status:"created"}}summarizeDataForLog(A){return{uploadId:A.uploadId,hasTitle:A.title!==void 0}}}aA();async function W31({entity:A,config:Q}){let B=sz.parse(A),w=b2(B.content,sF);return{$type:"ai.rizom.brain.note",title:B.metadata.title,body:w.content,format:"text/markdown",...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"note",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function QhA(){return{entityType:"note",collection:"ai.rizom.brain.note",lexicon:Kw["ai.rizom.brain.note"],validate:!1,buildRecord:W31}}var H31={name:"@brains/note",private:!0,version:"0.2.0-alpha.
|
|
6223
|
+
`}var OCQ={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"},RCQ=H.object({uploadId:H.string().min(1),title:H.string().optional()});class AhA extends ZB{context;constructor(A,Q){super(A,{schema:RCQ,jobTypeName:"upload-import"});this.context=Q}async process(A,Q,B){await this.reportProgress(B,{progress:10,message:"Reading uploaded file"});let w=await this.context.uploads.scoped(OCQ).read(A.uploadId);await this.reportProgress(B,{progress:35,message:"Extracting markdown from upload"});let $=await X31({upload:w,...A.title!==void 0?{title:A.title}:{}});await this.reportProgress(B,{progress:80,message:"Saving imported note"});let f=new Date().toISOString(),I=az.fromMarkdown($.content),D=await this.context.entityService.createEntity({entity:{id:$.id,entityType:"note",content:$.content,metadata:{title:$.title,...I.metadata},created:f,updated:f},options:{deduplicateId:!0}});return await this.reportProgress(B,{progress:100,message:"Upload imported as markdown note"}),{entityId:D.entityId,status:"created"}}summarizeDataForLog(A){return{uploadId:A.uploadId,hasTitle:A.title!==void 0}}}aA();async function W31({entity:A,config:Q}){let B=sz.parse(A),w=b2(B.content,sF);return{$type:"ai.rizom.brain.note",title:B.metadata.title,body:w.content,format:"text/markdown",...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"note",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function QhA(){return{entityType:"note",collection:"ai.rizom.brain.note",lexicon:Kw["ai.rizom.brain.note"],validate:!1,buildRecord:W31}}var H31={name:"@brains/note",private:!0,version:"0.2.0-alpha.127",description:"Personal knowledge capture with markdown-first workflow",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/contracts":"workspace:*","@brains/document":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var G31={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};class BhA extends _Q{entityType=az.entityType;schema=sz;adapter=az;unregisterAtprotoProjection;constructor(A={}){super("note",H31,A,agA)}async interceptCreate(A,Q,B){if(A.from?.kind!==G31.refKind)return{kind:"continue",input:A};if(A.transform!=="extract-markdown")return{kind:"handled",result:{success:!1,error:'Importing an upload as a note requires transform: "extract-markdown"'}};let w=A.from.id,$;try{$=await B.uploads.scoped(G31).readRecord(w)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}try{if(!J31($.mediaType))return{kind:"handled",result:{success:!1,error:"Only text, JSON, and PDF uploads can be imported as markdown notes"}};let f=egA({filename:$.filename,...A.title!==void 0?{title:A.title}:{}}),I=await B.jobs.enqueue({type:"upload-import",data:{uploadId:w,...A.title!==void 0?{title:A.title}:{}}});return{kind:"handled",result:{success:!0,data:{entityId:f.id,status:"generating",jobId:I}}}}catch(f){return{kind:"handled",result:{success:!1,error:f instanceof Error?f.message:"Failed to import upload as markdown"}}}}createGenerationHandler(A){return new Z$A(this.logger.child("NoteGenerationJobHandler"),A)}getTemplates(){return{generation:tgA}}async onRegister(A){A.jobs.registerHandler("upload-import",new AhA(this.logger.child("UploadMarkdownImportJobHandler"),A)),A.eval.registerHandler("generateNote",async(Q)=>{let B=H.object({prompt:H.string()}).parse(Q);return A.ai.generate({prompt:B.prompt,templateName:"note:generation"})}),this.unregisterAtprotoProjection=o6.getInstance().register(QhA())}async getInstructions(){return'To turn an uploaded text or PDF file into an editable markdown note, call system_create with entityType: "note", the exact upload object from the current turn or conversation upload refs hint, and transform: "extract-markdown". Use this only when the user explicitly asks to import, extract, or turn the upload into a note/markdown. Do not use this note-import pattern for raw file saves/promotions such as saving a PDF as a document or saving an image as an image; those use system_upload_save with the raw upload ref and no transform. Omit transform for ordinary direct note creates.'}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function NC(A={}){return new BhA(A)}aA();WA();WA();aA();var K31=H.object({ref:H.string(),label:H.string()}),F31=H.enum(["pending","draft","published"]),aF=H.object({status:F31,title:H.string(),url:H.string().url(),description:H.string().optional(),domain:H.string(),capturedAt:H.string().datetime(),source:K31}),Z31=aF.pick({title:!0,status:!0}),zC=A2.extend({entityType:H.literal("link"),metadata:Z31}),whA=H.object({enableSummarization:H.boolean().default(!0).describe("Generate AI summaries for captured links"),jinaApiKey:H.string().optional().describe("Jina Reader API key for higher rate limits (500 RPM vs 20 RPM without key)")});aA();class tz extends q2{constructor(){super({entityType:"link",schema:zC,frontmatterSchema:aF})}createLinkContent(A){let Q={status:A.status,title:A.title,url:A.url,description:A.description,domain:A.domain,capturedAt:A.capturedAt,source:A.source},B=A.summary??"";return this.buildMarkdown(B,Q)}parseLinkContent(A){return{frontmatter:this.parseFrontMatter(A,aF),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 gv=new tz;aA();WA();var PCQ=H.object({success:H.boolean().describe("Set to true if you can extract meaningful content. Set to false only if the provided content is empty, just an error message, or otherwise unusable."),error:H.string().describe("If success is false, explain why content could not be extracted. Use an empty string when success is true."),title:H.string().max(80).describe("The page title - extract from the content or create a descriptive one. Leave empty string if success is false."),description:H.string().describe("A one-sentence description of what the page is about. Leave empty string if success is false."),summary:H.string().describe("A 1-2 paragraph summary of the main content. Leave empty string if success is false.")}),N31=P1({name:"link:extraction",description:"Extract structured content from webpage markdown",dataSourceId:"shell:ai-content",schema:PCQ,basePrompt:`You are an expert at extracting key information from webpage content.
|
|
6224
6224
|
|
|
6225
6225
|
You will receive webpage content in markdown format. Your job is to extract structured information from it.
|
|
6226
6226
|
|
|
@@ -6242,7 +6242,7 @@ Accuracy rules:
|
|
|
6242
6242
|
|
|
6243
6243
|
`))return{success:!1,error:I.trim(),errorType:"fetch_failed"};return{success:!0,content:I}}catch(B){return this.handleFetchError(B,A)}}handleHttpError(A,Q){if(A===400)return{success:!1,error:`Invalid or non-existent URL: ${Q}`,errorType:"url_not_found"};if(A===404)return{success:!1,error:`Page not found: ${Q}`,errorType:"url_not_found"};if(A>=500)return{success:!1,error:`Server error while fetching ${Q}`,errorType:"url_unreachable"};return{success:!1,error:`HTTP ${A} error while fetching ${Q}`,errorType:"fetch_failed"}}handleFetchError(A,Q){if(A instanceof Error){if(A.name==="AbortError")return{success:!1,error:`Request timeout while fetching ${Q}`,errorType:"url_unreachable"};if(A.message.includes("ENOTFOUND")||A.message.includes("getaddrinfo"))return{success:!1,error:`Domain not found: ${new URL(Q).hostname}`,errorType:"url_not_found"};if(A.message.includes("ECONNREFUSED")||A.message.includes("ETIMEDOUT"))return{success:!1,error:`Could not connect to ${Q}`,errorType:"url_unreachable"};return{success:!1,error:`Failed to fetch ${Q}: ${A.message}`,errorType:"fetch_failed"}}return{success:!1,error:`Unknown error fetching ${Q}`,errorType:"fetch_failed"}}}import{createHash as vCQ}from"crypto";class ez{static URL_PATTERN=/https?:\/\/[^\s<>"{}|\\^`[\]]+?(?=[,;:\s]|$)/gi;static extractUrls(A){let Q=A.match(ez.URL_PATTERN)??[];return[...new Set(Q)]}static normalizeUrl(A){try{let Q=new URL(A),B=Q.pathname.replace(/\/$/,"")||"/";return`${Q.protocol}//${Q.host}${B}`}catch{return A}}static generateEntityId(A){let Q=this.normalizeUrl(A),B=vCQ("sha256").update(Q).digest("hex");try{return`${new URL(Q).hostname.replace(/\./g,"-")}-${B.substring(0,6)}`}catch{return B.substring(0,12)}}static isValidUrl(A){try{let Q=new URL(A);return["http:","https:"].includes(Q.protocol)}catch{return!1}}}aA();WA();o8();var yCQ=H.object({url:H.string().url(),metadata:H.object({interfaceId:H.string().optional(),userId:H.string().optional(),channelId:H.string().optional(),channelName:H.string().optional(),timestamp:H.string().optional()}).optional()}),Kaw=H.object({success:H.boolean(),entityId:H.string().optional(),title:H.string().optional(),url:H.string().optional(),status:H.enum(["pending","draft","published"]).optional(),error:H.string().optional()});class z$A extends ZB{context;linkAdapter;urlFetcher;constructor(A,Q,B){super(A,{schema:yCQ,jobTypeName:"link-capture"});this.context=Q,this.linkAdapter=new tz,this.urlFetcher=new hv(B?.jinaApiKey?{jinaApiKey:B.jinaApiKey}:void 0)}async process(A,Q,B){let{url:w,metadata:$}=A;try{await B.report({progress:qQ.START,total:100,message:"Starting link capture"});let f=ez.generateEntityId(w);await B.report({progress:qQ.INIT,total:100,message:"Checking for existing link"});let I=await this.context.entityService.getEntity({entityType:"link",id:f});if(I){let{frontmatter:Z}=this.linkAdapter.parseLinkContent(I.content),N=I.metadata.status;if(N!=="pending")return this.logger.info("Link already captured, returning existing",{url:w,entityId:f}),{success:!0,entityId:I.id,title:Z.title,url:w,status:N};this.logger.info("Pending link exists, completing extraction",{url:w,entityId:f})}let D=this.resolveSource($),U=new Date().toISOString();await B.report({progress:qQ.FETCH,total:100,message:"Fetching webpage content"});let Y=await this.urlFetcher.fetch(w);if(!Y.success){if(Y.errorType==="url_not_found"||Y.errorType==="url_unreachable"){this.logger.warn("Link URL not accessible",{url:w,errorType:Y.errorType,error:Y.error});let Z=new URL(w).hostname,N=`Could not capture link: ${Y.error}`,V=this.linkAdapter.createLinkContent({status:"pending",title:Z,url:w,description:N,summary:N,domain:Z,capturedAt:U,source:D});return await kI({entityService:this.context.entityService,entity:{id:f,entityType:"link",content:V,metadata:{status:"pending",title:Z}}}),{success:!1,entityId:f,title:Z,url:w,status:"pending",error:N}}}await B.report({progress:qQ.PROCESS,total:100,message:"Extracting content with AI"});let J=await this.context.ai.generate({templateName:"link:extraction",prompt:Y.success?`Extract structured information from this webpage content:
|
|
6244
6244
|
|
|
6245
|
-
${Y.content}`:`The URL ${w} could not be fetched. Return success: false with error: "${Y.error}"`,data:{url:w,hasContent:Y.success},interfacePermissionGrant:"public"});if(this.logger.debug("AI extraction result",{result:J}),await B.report({progress:qQ.EXTRACT,total:100,message:"Processing extraction results"}),J.success===!1||!J.title||!J.description||!J.summary){let Z=J.title||new URL(w).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:w}),await B.report({progress:qQ.SAVE,total:100,message:"Saving link as pending"});let N=this.linkAdapter.createLinkContent({status:"pending",title:Z,url:w,description:J.description,summary:J.summary,domain:new URL(w).hostname,capturedAt:U,source:D}),V=await kI({entityService:this.context.entityService,entity:{id:f,entityType:"link",content:N,metadata:{status:"pending",title:Z}}});return await B.report({progress:qQ.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:V.entityId,title:Z,url:w,status:"pending"}}await B.report({progress:qQ.SAVE,total:100,message:`Saving link: "${J.title}"`});let X=this.linkAdapter.createLinkContent({status:"draft",title:J.title,url:w,description:J.description,summary:J.summary,domain:new URL(w).hostname,capturedAt:U,source:D}),G=await kI({entityService:this.context.entityService,entity:{id:f,entityType:"link",content:X,metadata:{status:"draft",title:J.title}}});return await B.report({progress:qQ.COMPLETE,total:100,message:`Link captured: "${J.title}"`}),{success:!0,entityId:G.entityId,title:J.title,url:w,status:"draft"}}catch(f){return this.logger.error("Link capture job failed",{error:f,jobId:Q,data:A}),K6.failure(f)}}resolveSource(A){let Q=A?.channelId,B=A?.channelName;if(Q)return{ref:`matrix:${Q}`,label:B??Q};let w=A?.interfaceId??"cli";return{ref:`${w}:local`,label:w.toUpperCase()}}summarizeDataForLog(A){return{url:A.url,interfaceId:A.metadata?.interfaceId}}}async function L31({entity:A,config:Q}){let B=zC.parse(A),{frontmatter:w,summary:$}=gv.parseLinkContent(B.content);return{$type:"ai.rizom.brain.link",title:w.title,url:w.url,...w.description&&{description:w.description},...$&&{summary:$},domain:w.domain,capturedAt:w.capturedAt,source:w.source,...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"link",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function YhA(){return{entityType:"link",collection:"ai.rizom.brain.link",lexicon:Kw["ai.rizom.brain.link"],validate:!1,buildRecord:L31}}var V31={name:"@brains/link",private:!0,version:"0.2.0-alpha.
|
|
6245
|
+
${Y.content}`:`The URL ${w} could not be fetched. Return success: false with error: "${Y.error}"`,data:{url:w,hasContent:Y.success},interfacePermissionGrant:"public"});if(this.logger.debug("AI extraction result",{result:J}),await B.report({progress:qQ.EXTRACT,total:100,message:"Processing extraction results"}),J.success===!1||!J.title||!J.description||!J.summary){let Z=J.title||new URL(w).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:w}),await B.report({progress:qQ.SAVE,total:100,message:"Saving link as pending"});let N=this.linkAdapter.createLinkContent({status:"pending",title:Z,url:w,description:J.description,summary:J.summary,domain:new URL(w).hostname,capturedAt:U,source:D}),V=await kI({entityService:this.context.entityService,entity:{id:f,entityType:"link",content:N,metadata:{status:"pending",title:Z}}});return await B.report({progress:qQ.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:V.entityId,title:Z,url:w,status:"pending"}}await B.report({progress:qQ.SAVE,total:100,message:`Saving link: "${J.title}"`});let X=this.linkAdapter.createLinkContent({status:"draft",title:J.title,url:w,description:J.description,summary:J.summary,domain:new URL(w).hostname,capturedAt:U,source:D}),G=await kI({entityService:this.context.entityService,entity:{id:f,entityType:"link",content:X,metadata:{status:"draft",title:J.title}}});return await B.report({progress:qQ.COMPLETE,total:100,message:`Link captured: "${J.title}"`}),{success:!0,entityId:G.entityId,title:J.title,url:w,status:"draft"}}catch(f){return this.logger.error("Link capture job failed",{error:f,jobId:Q,data:A}),K6.failure(f)}}resolveSource(A){let Q=A?.channelId,B=A?.channelName;if(Q)return{ref:`matrix:${Q}`,label:B??Q};let w=A?.interfaceId??"cli";return{ref:`${w}:local`,label:w.toUpperCase()}}summarizeDataForLog(A){return{url:A.url,interfaceId:A.metadata?.interfaceId}}}async function L31({entity:A,config:Q}){let B=zC.parse(A),{frontmatter:w,summary:$}=gv.parseLinkContent(B.content);return{$type:"ai.rizom.brain.link",title:w.title,url:w.url,...w.description&&{description:w.description},...$&&{summary:$},domain:w.domain,capturedAt:w.capturedAt,source:w.source,...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"link",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function YhA(){return{entityType:"link",collection:"ai.rizom.brain.link",lexicon:Kw["ai.rizom.brain.link"],validate:!1,buildRecord:L31}}var V31={name:"@brains/link",private:!0,version:"0.2.0-alpha.127",description:"Web content capture plugin with AI-powered extraction and structured storage",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class JhA extends _Q{entityType=gv.entityType;schema=zC;adapter=gv;shell;unregisterAtprotoProjection;constructor(A={}){super("link",V31,A,whA)}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 z$A(this.logger.child("LinkCaptureJobHandler"),this.context,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0),this.id),Q}async interceptCreate(A,Q,B){if(A.content)try{let f=this.adapter.fromMarkdown(A.content).metadata,I=typeof f?.title==="string"?f.title:void 0,D=typeof f?.status==="string"?f.status:void 0,U=this.extractFirstUrl(A.content);if(I&&D&&U){let Y=X1(U)||X1(I)||`${A.entityType}-${Date.now()}`,J=new Date().toISOString();return{kind:"handled",result:{success:!0,data:{entityId:(await B.entityService.createEntity({entity:{id:Y,entityType:A.entityType,content:A.content,metadata:{title:I,status:D},created:J,updated:J}})).entityId,status:"created"}}}}}catch{}let w=A.url??this.extractFirstUrl(A.content,A.prompt,A.title);if(w){if(!this.shell)throw Error("LinkPlugin shell was not initialized during register()");try{let $=await this.createPendingLink(w,A.title,Q,B),f=await this.shell.getJobQueueService().enqueue({type:"link-capture",data:{url:w,metadata:{interfaceId:Q.interfaceType,userId:Q.userId,...Q.channelId?{channelId:Q.channelId}:{},...Q.channelName?{channelName:Q.channelName}:{},timestamp:new Date().toISOString()}},options:{source:this.id,metadata:{operationType:"data_processing",pluginId:this.id,interfaceType:Q.interfaceType,...Q.channelId?{channelId:Q.channelId}:{}}}});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 z$A(this.logger.child("LinkCaptureJobHandler"),A,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0)}getTemplates(){return{extraction:N31,"link-list":z31,"link-detail":q31}}getDataSources(){return[new UhA(this.logger.child("LinksDataSource"))]}async onRegister(A){this.unregisterAtprotoProjection=o6.getInstance().register(YhA()),A.eval.registerHandler("extractContent",async(Q)=>{let{url:B}=H.object({url:H.string().url()}).parse(Q),$=await new hv(this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0).fetch(B);if(!$.success)return{success:!1,error:$.error,errorType:$.errorType};return A.ai.generate({templateName:"link:extraction",prompt:`Extract structured information from this webpage content:
|
|
6246
6246
|
|
|
6247
6247
|
${$.content}`,data:{url:B,hasContent:!0},interfacePermissionGrant:"public"})})}async createPendingLink(A,Q,B,w){let $=ez.generateEntityId(A),f=new URL(A),I=new Date().toISOString(),D=Q?.trim()?Q.trim():f.hostname,U=this.adapter.createLinkContent({status:"pending",title:D,url:A,description:"Link capture is in progress.",summary:`Pending link capture for ${A}.`,domain:f.hostname,capturedAt:I,source:this.resolveSource(B)});return(await TL({entityService:w.entityService,entity:{id:$,entityType:"link",content:U,metadata:{status:"pending",title:D},created:I,updated:I}})).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[B]=ez.extractUrls(Q);if(B)return B}return}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function E31(A={}){return new JhA(A)}var qC=E31;WA();var uaw=H.object({id:H.string().optional(),metadata:H.object({conversationId:H.string().optional(),interfaceId:H.string().optional(),userId:H.string().optional(),messageId:H.string().optional(),timestamp:H.string().optional()}).optional()});aA();WA();Xw();WA();aA();var M31=H.enum(["generating","draft","published","failed"]),b$=H.object({title:H.string(),slug:H.string().optional(),status:M31,publishedAt:H.string().datetime().optional(),description:H.string(),year:H.number(),coverImageId:H.string().optional(),ogImageId:H.string().optional(),url:H.string().url().optional()}),C31=b$.pick({title:!0,status:!0,publishedAt:!0,year:!0}).extend({slug:H.string(),error:H.string().optional()}),Aq=A2.extend({entityType:H.literal("project"),metadata:C31}),q$A=H.object({context:H.string(),problem:H.string(),solution:H.string(),outcome:H.string()}),ri=Aq.extend({frontmatter:b$,body:H.string(),structuredContent:q$A.optional(),coverImageUrl:H.string().optional(),ogImageUrl:H.string().optional()}),mv=ri.extend({url:H.string().optional(),typeLabel:H.string().optional(),coverImageUrl:H.string().optional(),ogImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()}),xCQ=ri.extend({url:H.string(),typeLabel:H.string(),coverImageUrl:H.string().optional(),ogImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()});aA();WA();t$();class XhA extends lB{constructor(){super(q$A,{title:"Project",mappings:[{key:"context",label:"Context",type:"string"},{key:"problem",label:"Problem",type:"string"},{key:"solution",label:"Solution",type:"string"},{key:"outcome",label:"Outcome",type:"string"}]})}}var WhA=new XhA;class HhA extends q2{constructor(){super({entityType:"project",schema:Aq,frontmatterSchema:b$,supportsCoverImage:!0,bodyFormatter:WhA})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,b$),w={...B,slug:B.slug??A.metadata.slug};return this.buildMarkdown(Q,w)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,b$),B=Q.slug??X1(Q.title);return{content:A,entityType:"project",metadata:{title:Q.title,slug:B,status:Q.status,publishedAt:Q.publishedAt,year:Q.year}}}parseProjectFrontmatter(A){return this.parseFrontMatter(A.content,b$)}parseStructuredContent(A){return WhA.parse(this.extractBody(A.content))}createProjectContent(A,Q){let B=WhA.format(Q);return this.buildMarkdown(B,A)}buildStub(A){let Q=new Date().getUTCFullYear(),B={title:A.title,slug:A.id,status:"generating",description:"",year:Q};return{content:this.buildMarkdown("",B),metadata:{title:A.title,slug:A.id,status:"generating",year:Q}}}}var Qq=new HhA;WA();var GhA=H.object({});import{jsxDEV as PD,Fragment as gCQ}from"preact/jsx-dev-runtime";var SCQ=({project:A})=>{let{frontmatter:Q,url:B,coverImageUrl:w}=A;return PD(PB,{href:B,children:[w&&PD("img",{src:w,alt:Q.title,className:"w-full h-56 object-cover rounded-md mb-4"},void 0,!1,void 0,this),PD(W9,{children:Q.title},void 0,!1,void 0,this),PD("p",{className:"text-theme leading-relaxed",children:Q.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},KhA=({projects:A,pageTitle:Q,pagination:B,baseUrl:w="/projects"})=>{let $=Q??"Projects",f=B?.totalItems??A.length,I=`Browse all ${f} ${f===1?"project":"projects"}`;return PD(gCQ,{children:[PD(ZQ,{title:$,description:I},void 0,!1,void 0,this),PD("div",{className:"project-list bg-theme",children:PD("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[PD("h1",{className:"text-4xl font-bold text-heading mb-12",children:$},void 0,!1,void 0,this),PD("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-8",children:A.map((D)=>PD(SCQ,{project:D},D.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&PD("div",{className:"mt-12",children:PD(bF,{currentPage:B.currentPage,totalPages:B.totalPages,baseUrl:w},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as fw,Fragment as O31}from"preact/jsx-dev-runtime";var hCQ=({prevProject:A,nextProject:Q})=>{if(!A&&!Q)return null;return fw("nav",{className:"pt-12 mt-12 border-t border-theme-muted",children:fw("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[A?fw(PB,{href:A.url,variant:"compact",children:[fw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Previous"},void 0,!1,void 0,this),fw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:A.metadata.title},void 0,!1,void 0,this)]},void 0,!0,void 0,this):fw("div",{},void 0,!1,void 0,this),Q&&fw(PB,{href:Q.url,variant:"compact",className:"md:text-right",children:[fw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Next"},void 0,!1,void 0,this),fw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:Q.metadata.title},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},L$A=({title:A,content:Q})=>{if(!Q)return null;return fw("section",{className:"mb-12",children:[fw("h2",{className:"text-2xl font-bold text-heading mb-4",children:A},void 0,!1,void 0,this),fw(M$,{markdown:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},FhA=({project:A,prevProject:Q,nextProject:B})=>{let{frontmatter:w,structuredContent:$,metadata:f,coverImageUrl:I}=A,D=A.ogImageUrl??I;return fw(O31,{children:[fw(ZQ,{title:w.title,description:w.description,...D?{ogImage:D}:{},ogType:"article"},void 0,!1,void 0,this),fw("article",{className:"project-detail",children:fw("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:fw("div",{className:"max-w-3xl mx-auto",children:[I&&A.coverImageWidth&&A.coverImageHeight&&fw(OF,{src:I,alt:w.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8 shadow-lg"},void 0,!1,void 0,this),fw("h1",{className:"text-4xl md:text-5xl font-bold text-heading leading-tight tracking-tight mb-4",children:w.title},void 0,!1,void 0,this),fw("div",{className:"flex flex-wrap items-center gap-4 text-theme-muted mb-8",children:[fw("span",{className:"text-sm",children:f.year},void 0,!1,void 0,this),w.url&&fw(O31,{children:[fw("span",{className:"text-theme-muted",children:"|"},void 0,!1,void 0,this),fw("a",{href:w.url,target:"_blank",rel:"noopener noreferrer",className:"text-brand hover:text-brand-dark transition-colors",children:"View Project"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),fw("p",{className:"text-lg text-theme mb-12 leading-relaxed",children:w.description},void 0,!1,void 0,this),$&&fw("div",{className:"case-study",children:[fw(L$A,{title:"Context",content:$.context},void 0,!1,void 0,this),fw(L$A,{title:"Problem",content:$.problem},void 0,!1,void 0,this),fw(L$A,{title:"Solution",content:$.solution},void 0,!1,void 0,this),fw(L$A,{title:"Outcome",content:$.outcome},void 0,!1,void 0,this)]},void 0,!0,void 0,this),fw(hCQ,{prevProject:Q,nextProject:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};WA();aA();var mCQ=H.object({title:H.string().max(80).describe("A clear, compelling project title (3-8 words). Should capture the essence of the project."),description:H.string().describe("A 1-2 sentence summary of the project for portfolio cards. Focus on the core value delivered."),context:H.string().describe("Background information: Who was the client/user? What was the situation? What constraints existed? (2-4 paragraphs)"),problem:H.string().describe("The challenge: What specific problem needed solving? What were the pain points? (2-3 paragraphs)"),solution:H.string().describe("The approach: What was built? What technologies/methods were used? How did it work? (3-5 paragraphs)"),outcome:H.string().describe("The results: What impact did this have? What metrics improved? What was learned? (2-3 paragraphs)")}),ZhA=P1({name:"portfolio:generation",description:"Template for AI to generate portfolio project case studies",schema:mCQ,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create a professional portfolio case study based on REAL project information.
|
|
6248
6248
|
|
|
@@ -6418,7 +6418,7 @@ Use the project request as the primary source of truth. If retrieved knowledge c
|
|
|
6418
6418
|
font: 10px/1.45 var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
|
|
6419
6419
|
}
|
|
6420
6420
|
.printable-footer a { color: inherit; text-decoration: none; overflow-wrap: anywhere; }
|
|
6421
|
-
`}},void 0,!1,void 0,this),P$("section",{className:"project-shell",children:[P$("header",{className:"project-hero",children:[P$("div",{className:"project-index",children:[Q.brandLabel&&P$("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this),Q.year&&P$("span",{className:"project-year",children:Q.year},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P$("div",{className:"project-title-panel",children:[P$("span",{className:"printable-kind",children:"Case study dossier"},void 0,!1,void 0,this),P$("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.description&&P$("p",{className:"printable-description",children:Q.description},void 0,!1,void 0,this),P$("div",{className:"printable-meta",children:[Q.year&&P$("span",{children:Q.year},void 0,!1,void 0,this),Q.url&&P$("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&&P$("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this),P$(M$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Q.canonicalUrl||Q.url||Q.brandLabel)&&P$("footer",{className:"printable-footer",children:[P$("span",{children:Q.brandLabel??"Project printable"},void 0,!1,void 0,this),Q.canonicalUrl||Q.url?P$("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 oCQ=26214400,sCQ=60000;class qhA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??WX}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==M$A)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let B=aCQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await iCQ(nCQ(dCQ(),"brain-project-printable-"));try{let $=await VD({outputDir:w,mediaPath:`/_media/printable/project/${Q.id}`,template:P31,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ED({rootDir:w});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:oCQ,timeoutMs:sCQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${tCQ(Q)}-printable.pdf`}}finally{await f.close()}}finally{await rCQ(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=jB(A.content),B=b$.parse(Q);if(!B.coverImageId)return;let w=await this.context.entityService.getEntity({entityType:"image",id:B.coverImageId});return w?.content.startsWith("data:image/")?w.content:void 0}}function aCQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=b$.parse(B);return{title:$.title,body:w,...$.description?{description:$.description}:{},year:$.year,...$.publishedAt?{publishedAt:$.publishedAt}:{},...$.url?{url:$.url,canonicalUrl:$.url}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function tCQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}WA();WA();import{jsxDEV as QOQ}from"preact/jsx-dev-runtime";var C$A="og-image",eCQ="portfolio:og-image",k31=H.object({title:H.string().min(1),description:H.string().optional(),year:H.number().optional(),brandLabel:H.string().optional(),coverImageUrl:H.string().optional()}),j31={name:eCQ,pluginId:"portfolio",schema:k31,renderers:{image:AOQ}};function AOQ(A){let Q=k31.parse(A);return QOQ(CF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Project",title:Q.title,subtitle:Q.description,tag:Q.year},void 0,!1,void 0,this)}class LhA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==C$A)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B}=jB(Q.content),w=b$.parse(B),$=this.resolveBrandLabel(),f=await this.resolveCoverImageUrl(w.coverImageId),I={title:w.title,...w.description?{description:w.description}:{},year:w.year,...f?{coverImageUrl:f}:{},...$?{brandLabel:$}:{}};return{type:"image",data:await YC({mediaPath:`/_media/og/project/${Q.id}`,template:j31,content:I,title:I.title,themeMode:"light",themeCSS:this.context.themeCSS,tmpPrefix:"brain-project-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${BOQ(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 BOQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}var _31={name:"@brains/portfolio",private:!0,version:"0.2.0-alpha.125",description:"Portfolio showcase for projects and case studies",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest",typescript:"^5.3.3"}};var $OQ=H.object({projects:H.array(mv),pageTitle:H.string().optional(),pagination:z7.nullable(),baseUrl:H.string().optional()});function fOQ(A,Q){for(let B of[A,Q]){let w=B?.match(/\b(19\d{2}|20\d{2})\b/);if(w?.[1])return Number(w[1])}return null}class VhA extends _Q{entityType=Qq.entityType;schema=Aq;adapter=Qq;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("portfolio",_31,A,GhA)}async interceptCreate(A,Q,B){if(!A.prompt||A.content)return{kind:"continue",input:A};let w=fOQ(A.title,A.prompt);if(!w)return{kind:"continue",input:A};return{kind:"handled",result:{success:!0,data:{status:"generating",jobId:await B.jobs.enqueue({type:"project:generation",data:{prompt:A.prompt,...A.title?{title:A.title}:{},year:w},toolContext:Q,options:{source:this.id,metadata:{operationType:"content_operations"}}})}}}}createGenerationHandler(A){return new V$A(this.logger.child("ProjectGenerationJobHandler"),A)}getTemplates(){return{"project-list":P1({name:"project-list",description:"Portfolio project list page template",schema:$OQ,dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:KhA}}),"project-detail":P1({name:"project-detail",description:"Individual project case study template",schema:H.object({project:mv,prevProject:mv.nullable(),nextProject:mv.nullable()}),dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:FhA}}),generation:ZhA}}getDataSources(){return[new E$A(this.logger.child("ProjectDataSource"))]}async onRegister(A){this.registerEvalHandlers(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("project",M$A,new qhA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("project",C$A,new LhA(A)),this.deferPublishRegistration(A),this.subscribeToPublishExecute(A),this.unregisterAtprotoProjection=o6.getInstance().register(zhA())}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0,this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}registerEvalHandlers(A){A.eval.registerHandler("generateProject",async(Q)=>{let B=H.object({prompt:H.string(),year:H.number()}).parse(Q);return A.ai.generate({prompt:NhA(B),templateName:"portfolio:generation"})})}deferPublishRegistration(A){let Q={name:"internal",publish:async()=>({id:"internal"})};A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"publish:register",payload:{entityType:"project",provider:Q,config:{executionMode:"provider"}}}),{success:!0}})}subscribeToPublishExecute(A){A.messaging.subscribe("publish:execute",async(Q)=>{let{entityType:B,entityId:w}=Q.payload;if(B!=="project")return{success:!0};try{let $=await A.entityService.getEntity({entityType:"project",id:w});if(!$)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:`Project not found: ${w}`}}),{success:!0};if($.metadata.status==="published")return{success:!0};let f=b2($.content,b$),I=new Date().toISOString(),D=k9(f.content,{...f.metadata,status:"published",publishedAt:I});await A.entityService.updateEntity({entity:{...$,content:D,metadata:{...$.metadata,status:"published",publishedAt:I}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,publishedAt:I}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:y0($)}})}return{success:!0}})}}function EhA(A={}){return new VhA(A)}aA();WA();var IOQ=H.enum(["public","shared","restricted"]),v31=H.object({includeEntityTypes:H.array(H.string()).default([]),minRelevanceScore:H.number().min(0).max(1).default(0.5),mergeSimilarityThreshold:H.number().min(0).max(1).default(0.85),autoMerge:H.boolean().default(!0),extractableStatuses:H.array(H.string()).default(["published"]),enableAutoExtraction:H.boolean().default(!0),extractionVisibility:IOQ.default("public"),sourceChangeBatchDelayMs:H.number().int().min(0).default(1000)});aA();WA();aA();var DOQ=H.object({}),uv=A2.extend({entityType:H.literal("topic"),metadata:DOQ}),xew=H.object({content:H.string()}),y31=H.object({title:H.string().describe("Topic title")});var LC="topics",Iw="topic",MhA="topics-projection",T31="topic:project",O$A="topics-plugin",x31="topics:batch-completed",S31="topics-source-batch";class GX extends q2{constructor(){super({entityType:Iw,schema:uv,frontmatterSchema:y31})}buildFrontmatter(A){return{title:A}}toMarkdown(A){let Q=this.parseTopicBody(A.content);return this.buildMarkdown(Q.content,this.buildFrontmatter(Q.title))}fromMarkdown(A){return{content:A,entityType:Iw}}extractMetadata(A){return{}}generateFrontMatter(A){let Q=this.parseTopicBody(A.content),w=this.buildMarkdown("",this.buildFrontmatter(Q.title)).match(/^---\n[\s\S]*?\n---/);return w?w[0]:""}parseTopicBody(A){if(A.startsWith("---"))try{let Q=this.parseFrontmatter(A);return{content:this.extractBody(A).replace(/\n*## Sources[\s\S]*$/,"").trim(),formatted:A,title:Q.title}}catch{return{content:A,formatted:A,title:"Unknown Topic"}}return{content:A,formatted:A,title:"Unknown Topic"}}createTopicBody(A){return this.buildMarkdown(A.content,this.buildFrontmatter(A.title))}}aA();WA();WA();var UOQ=H.object({title:H.string().max(100),content:H.string(),relevanceScore:H.number().min(0).max(1)}),g31=H.array(UOQ);var YOQ=H.object({topics:g31}),h31=P1({name:"topics:extraction",description:"Extract topics from conversation text",dataSourceId:"shell:ai-content",schema:YOQ,basePrompt:`You are an expert at analyzing content and extracting key topics.
|
|
6421
|
+
`}},void 0,!1,void 0,this),P$("section",{className:"project-shell",children:[P$("header",{className:"project-hero",children:[P$("div",{className:"project-index",children:[Q.brandLabel&&P$("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this),Q.year&&P$("span",{className:"project-year",children:Q.year},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P$("div",{className:"project-title-panel",children:[P$("span",{className:"printable-kind",children:"Case study dossier"},void 0,!1,void 0,this),P$("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.description&&P$("p",{className:"printable-description",children:Q.description},void 0,!1,void 0,this),P$("div",{className:"printable-meta",children:[Q.year&&P$("span",{children:Q.year},void 0,!1,void 0,this),Q.url&&P$("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&&P$("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this),P$(M$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Q.canonicalUrl||Q.url||Q.brandLabel)&&P$("footer",{className:"printable-footer",children:[P$("span",{children:Q.brandLabel??"Project printable"},void 0,!1,void 0,this),Q.canonicalUrl||Q.url?P$("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 oCQ=26214400,sCQ=60000;class qhA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??WX}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==M$A)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let B=aCQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await iCQ(nCQ(dCQ(),"brain-project-printable-"));try{let $=await VD({outputDir:w,mediaPath:`/_media/printable/project/${Q.id}`,template:P31,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ED({rootDir:w});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:oCQ,timeoutMs:sCQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${tCQ(Q)}-printable.pdf`}}finally{await f.close()}}finally{await rCQ(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=jB(A.content),B=b$.parse(Q);if(!B.coverImageId)return;let w=await this.context.entityService.getEntity({entityType:"image",id:B.coverImageId});return w?.content.startsWith("data:image/")?w.content:void 0}}function aCQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=b$.parse(B);return{title:$.title,body:w,...$.description?{description:$.description}:{},year:$.year,...$.publishedAt?{publishedAt:$.publishedAt}:{},...$.url?{url:$.url,canonicalUrl:$.url}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function tCQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}WA();WA();import{jsxDEV as QOQ}from"preact/jsx-dev-runtime";var C$A="og-image",eCQ="portfolio:og-image",k31=H.object({title:H.string().min(1),description:H.string().optional(),year:H.number().optional(),brandLabel:H.string().optional(),coverImageUrl:H.string().optional()}),j31={name:eCQ,pluginId:"portfolio",schema:k31,renderers:{image:AOQ}};function AOQ(A){let Q=k31.parse(A);return QOQ(CF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Project",title:Q.title,subtitle:Q.description,tag:Q.year},void 0,!1,void 0,this)}class LhA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==C$A)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B}=jB(Q.content),w=b$.parse(B),$=this.resolveBrandLabel(),f=await this.resolveCoverImageUrl(w.coverImageId),I={title:w.title,...w.description?{description:w.description}:{},year:w.year,...f?{coverImageUrl:f}:{},...$?{brandLabel:$}:{}};return{type:"image",data:await YC({mediaPath:`/_media/og/project/${Q.id}`,template:j31,content:I,title:I.title,themeMode:"light",themeCSS:this.context.themeCSS,tmpPrefix:"brain-project-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${BOQ(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 BOQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}var _31={name:"@brains/portfolio",private:!0,version:"0.2.0-alpha.127",description:"Portfolio showcase for projects and case studies",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest",typescript:"^5.3.3"}};var $OQ=H.object({projects:H.array(mv),pageTitle:H.string().optional(),pagination:z7.nullable(),baseUrl:H.string().optional()});function fOQ(A,Q){for(let B of[A,Q]){let w=B?.match(/\b(19\d{2}|20\d{2})\b/);if(w?.[1])return Number(w[1])}return null}class VhA extends _Q{entityType=Qq.entityType;schema=Aq;adapter=Qq;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("portfolio",_31,A,GhA)}async interceptCreate(A,Q,B){if(!A.prompt||A.content)return{kind:"continue",input:A};let w=fOQ(A.title,A.prompt);if(!w)return{kind:"continue",input:A};return{kind:"handled",result:{success:!0,data:{status:"generating",jobId:await B.jobs.enqueue({type:"project:generation",data:{prompt:A.prompt,...A.title?{title:A.title}:{},year:w},toolContext:Q,options:{source:this.id,metadata:{operationType:"content_operations"}}})}}}}createGenerationHandler(A){return new V$A(this.logger.child("ProjectGenerationJobHandler"),A)}getTemplates(){return{"project-list":P1({name:"project-list",description:"Portfolio project list page template",schema:$OQ,dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:KhA}}),"project-detail":P1({name:"project-detail",description:"Individual project case study template",schema:H.object({project:mv,prevProject:mv.nullable(),nextProject:mv.nullable()}),dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:FhA}}),generation:ZhA}}getDataSources(){return[new E$A(this.logger.child("ProjectDataSource"))]}async onRegister(A){this.registerEvalHandlers(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("project",M$A,new qhA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("project",C$A,new LhA(A)),this.deferPublishRegistration(A),this.subscribeToPublishExecute(A),this.unregisterAtprotoProjection=o6.getInstance().register(zhA())}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0,this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}registerEvalHandlers(A){A.eval.registerHandler("generateProject",async(Q)=>{let B=H.object({prompt:H.string(),year:H.number()}).parse(Q);return A.ai.generate({prompt:NhA(B),templateName:"portfolio:generation"})})}deferPublishRegistration(A){let Q={name:"internal",publish:async()=>({id:"internal"})};A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"publish:register",payload:{entityType:"project",provider:Q,config:{executionMode:"provider"}}}),{success:!0}})}subscribeToPublishExecute(A){A.messaging.subscribe("publish:execute",async(Q)=>{let{entityType:B,entityId:w}=Q.payload;if(B!=="project")return{success:!0};try{let $=await A.entityService.getEntity({entityType:"project",id:w});if(!$)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:`Project not found: ${w}`}}),{success:!0};if($.metadata.status==="published")return{success:!0};let f=b2($.content,b$),I=new Date().toISOString(),D=k9(f.content,{...f.metadata,status:"published",publishedAt:I});await A.entityService.updateEntity({entity:{...$,content:D,metadata:{...$.metadata,status:"published",publishedAt:I}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,publishedAt:I}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:y0($)}})}return{success:!0}})}}function EhA(A={}){return new VhA(A)}aA();WA();var IOQ=H.enum(["public","shared","restricted"]),v31=H.object({includeEntityTypes:H.array(H.string()).default([]),minRelevanceScore:H.number().min(0).max(1).default(0.5),mergeSimilarityThreshold:H.number().min(0).max(1).default(0.85),autoMerge:H.boolean().default(!0),extractableStatuses:H.array(H.string()).default(["published"]),enableAutoExtraction:H.boolean().default(!0),extractionVisibility:IOQ.default("public"),sourceChangeBatchDelayMs:H.number().int().min(0).default(1000)});aA();WA();aA();var DOQ=H.object({}),uv=A2.extend({entityType:H.literal("topic"),metadata:DOQ}),xew=H.object({content:H.string()}),y31=H.object({title:H.string().describe("Topic title")});var LC="topics",Iw="topic",MhA="topics-projection",T31="topic:project",O$A="topics-plugin",x31="topics:batch-completed",S31="topics-source-batch";class GX extends q2{constructor(){super({entityType:Iw,schema:uv,frontmatterSchema:y31})}buildFrontmatter(A){return{title:A}}toMarkdown(A){let Q=this.parseTopicBody(A.content);return this.buildMarkdown(Q.content,this.buildFrontmatter(Q.title))}fromMarkdown(A){return{content:A,entityType:Iw}}extractMetadata(A){return{}}generateFrontMatter(A){let Q=this.parseTopicBody(A.content),w=this.buildMarkdown("",this.buildFrontmatter(Q.title)).match(/^---\n[\s\S]*?\n---/);return w?w[0]:""}parseTopicBody(A){if(A.startsWith("---"))try{let Q=this.parseFrontmatter(A);return{content:this.extractBody(A).replace(/\n*## Sources[\s\S]*$/,"").trim(),formatted:A,title:Q.title}}catch{return{content:A,formatted:A,title:"Unknown Topic"}}return{content:A,formatted:A,title:"Unknown Topic"}}createTopicBody(A){return this.buildMarkdown(A.content,this.buildFrontmatter(A.title))}}aA();WA();WA();var UOQ=H.object({title:H.string().max(100),content:H.string(),relevanceScore:H.number().min(0).max(1)}),g31=H.array(UOQ);var YOQ=H.object({topics:g31}),h31=P1({name:"topics:extraction",description:"Extract topics from conversation text",dataSourceId:"shell:ai-content",schema:YOQ,basePrompt:`You are an expert at analyzing content and extracting key topics.
|
|
6422
6422
|
|
|
6423
6423
|
Analyze the provided content and extract meaningful topics discussed.
|
|
6424
6424
|
|
|
@@ -6521,13 +6521,13 @@ ${A.incomingTopic.content}`})}}function qOQ(A){if(A.length===0)return"";return A
|
|
|
6521
6521
|
|
|
6522
6522
|
${Q.content}`}).join(`
|
|
6523
6523
|
|
|
6524
|
-
`)}async function VC(A,Q,B,w={}){if(A.length===0)return{created:0,merged:0,skipped:0,batches:0};let $=w.minRelevanceScore??0,f=w.autoMerge??!1,I=w.mergeSimilarityThreshold??0.85,D=w.targetVisibility??"public",U=s31(A),Y=new KX(Q.entityService,B),J=w.topicMergeSynthesizer??new khA(Q,B),X=await j$A(Q.entityService,void 0,D),G=new Map,Z=0,N=0,V=0;for(let M of U){B.info(`Processing batch of ${M.length} entities`);let O=qOQ(M),E=_$A({entityTitle:`Batch of ${M.length} entities`,entityType:"batch",content:O,existingTopicTitles:X});try{let T=(await Q.ai.generate({prompt:E,templateName:"topics:extraction"})).topics.filter((y)=>y.relevanceScore>=$);for(let y of T)try{if(f){let g=await Y.findMergeCandidate({incoming:y,threshold:I,additionalCandidates:Array.from(G.values()),targetVisibility:D});if(g){let n=await J.synthesize({existingTopic:g.topic,incomingTopic:y}),m=await Y.applySynthesizedMerge({existingId:g.topic.id,synthesized:{...n,title:g.title},visibility:D});if(!m)throw Error(`Failed to merge topic: ${y.title}`);G.set(m.id,m),N++;continue}}let _=Y.getTopicIdForTitle(y.title,D);if(G.has(_)){V++;continue}let x=await Y.createTopicOptimistic({title:y.title,content:y.content,visibility:D});if(x.topic)G.set(x.topic.id,x.topic);if(x.created)Z++;else V++}catch(_){B.error("Topic batch item failed",{title:y.title,error:y0(_)})}}catch(S){B.error("Batch topic extraction failed",{batchSize:M.length,promptChars:E.length,error:y0(S)})}}let L={created:Z,merged:N,skipped:V,batches:U.length};if(Z>0||N>0)await Q.messaging.send({type:x31,payload:L,broadcast:!0});return L}aA();WA();var LOQ=H.discriminatedUnion("mode",[H.object({mode:H.literal("derive"),reason:H.string().optional()}),H.object({mode:H.literal("rebuild"),reason:H.string().optional()}),H.object({mode:H.literal("source-batch"),minRelevanceScore:H.number().min(0).max(1).optional()})]);class jhA{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 Bz1(A){let{context:Q,logger:B,config:w}=A;return{process:async($)=>{if($.mode==="derive")return await A.extractAllTopics(),{success:!0};if($.mode==="rebuild")return await A.rebuildAllTopics(),{success:!0};return VOQ({context:Q,logger:B,config:w,sourceBatch:A.sourceBatch,isEntityPublished:A.isEntityPublished,minRelevanceScore:$.minRelevanceScore??w.minRelevanceScore})},validateAndParse:($)=>{let f=LOQ.safeParse($??{});return f.success?f.data:null}}}async function VOQ(A){let Q=A.sourceBatch.drain(),B=await Promise.all(Q.map(async(Y)=>({ref:Y,entity:await A.context.entityService.getEntity({entityType:Y.entityType,id:Y.entityId})}))),w=0,$=0,f=0,I=0,D=[];for(let{ref:Y,entity:J}of B){if(!J){$++;continue}if(J.contentHash!==Y.contentHash){w++;continue}if(!A.isEntityPublished(J)){f++;continue}if(!VN(J.visibility,A.config.extractionVisibility)){I++;continue}D.push(J)}if(D.length===0)return{success:!0,sources:Q.length,created:0,merged:0,skipped:0,batches:0,stale:w,missing:$,unpublished:f,hidden:I};let U=await VC(D,A.context,A.logger,{minRelevanceScore:A.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold,targetVisibility:A.config.extractionVisibility});return{success:!0,sources:Q.length,...U,stale:w,missing:$,unpublished:f,hidden:I}}function wz1(){return{priority:5,source:O$A,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:LC}}}async function $z1(A){let Q=await Iz1(A);if(Q.length===0){A.logger.info("No entities to extract topics from");return}A.logger.info(`Batch topic extraction: ${Q.length} entities`);let B=await VC(Q,A.context,A.logger,{minRelevanceScore:A.config.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold,targetVisibility:A.config.extractionVisibility});A.logger.info("Batch topic extraction complete",B)}async function fz1(A){let Q=await Iz1(A),B=await _hA(Q,A.context,A.logger,A.config);A.logger.info("Topic rebuild complete",B)}async function _hA(A,Q,B,w){let $=new KX(Q.entityService,B),f=await $.listTopics({visibility:w.extractionVisibility});for(let D of f)await $.deleteTopic(D.id);if(A.length===0)return{deleted:f.length,created:0,merged:0,skipped:0,batches:0};let I=await VC(A,Q,B,{minRelevanceScore:w.minRelevanceScore,autoMerge:w.autoMerge,mergeSimilarityThreshold:w.mergeSimilarityThreshold,targetVisibility:w.extractionVisibility});return{deleted:f.length,...I}}async function Iz1(A){let Q=EOQ(A),B=[];for(let w of Q){let $=await A.context.entityService.listEntities({entityType:w,options:{filter:{visibilityScope:A.config.extractionVisibility}}});for(let f of $){if(!A.isEntityPublished(f))continue;B.push(f)}}return B}function EOQ(A){return A.context.entityService.getEntityTypes().filter((B)=>A.shouldProcessEntityType(B))}var pv=H.object({entityType:H.string(),content:H.string(),metadata:H.record(H.unknown()).optional()}),MOQ=pv.extend({minRelevanceScore:H.number().optional()}),COQ=H.object({contentA:pv,contentB:pv,minRelevanceScore:H.number().optional(),threshold:H.number().min(0).max(1).optional()}),si=H.object({title:H.string(),content:H.string()}),OOQ=H.object({existingTopics:H.array(si),incomingTopic:si,threshold:H.number().optional()}),ROQ=H.object({existingTopics:H.array(si).default([]),incomingTopic:si.extend({relevanceScore:H.number().min(0).max(1).optional()}),threshold:H.number().optional()}),bOQ=H.object({entities:H.array(pv).min(1),minRelevanceScore:H.number().optional()}),POQ=H.object({existingTopics:H.array(si).optional(),entities:H.array(pv)}),kOQ=H.object({entities:H.array(pv)});function lv(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:gB(A.content),visibility:"public",metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function Dz1(A){return{title:A.title,relevanceScore:A.relevanceScore}}function jOQ(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function _OQ(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:jOQ(Q)}]}}async function EC(A){let Q=await A.entityService.listEntities({entityType:Iw});await Promise.all(Q.map((B)=>A.entityService.deleteEntity({entityType:Iw,id:B.id})))}async function vOQ(A){for(;;){if((await A.jobs.getActiveJobs(["shell:embedding"])).length===0)return;await new Promise((B)=>setTimeout(B,100))}}function Uz1(A){let{context:Q,logger:B,config:w}=A,$=new PhA(Q,B),f=async(I,D,U="")=>{let Y=lv(I,U);return $.extractFromEntity(Y,D)};Q.eval.registerHandler("extractFromEntity",async(I)=>{await EC(Q);let D=MOQ.parse(I),U=D.minRelevanceScore??w.minRelevanceScore,Y=lv(D);return(await $.extractFromEntity(Y,U)).map((X)=>_OQ(X,Y))}),Q.eval.registerHandler("checkMergeSimilarity",async(I)=>{await EC(Q);let D=COQ.parse(I),U=D.minRelevanceScore??w.minRelevanceScore,Y=D.threshold??w.mergeSimilarityThreshold,[J,X]=await Promise.all([f(D.contentA,U,"-a"),f(D.contentB,U,"-b")]),G=new KX(Q.entityService,B),Z=[];for(let L of J){let M=await G.createTopic(L);if(M)Z.push(M)}let N=(await Promise.all(X.map(async(L)=>{let M=await G.findMergeCandidate({incoming:L,threshold:Y,additionalCandidates:Z});if(!M)return null;return{incomingTitle:L.title,candidateTitle:M.title,candidateScore:M.score}}))).filter((L)=>L!==null),V=N.map((L)=>L.candidateTitle);return{topicsA:J.map(Dz1),topicsB:X.map(Dz1),matchingTitles:V,mergeCandidates:N,wouldMerge:N.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(I)=>{await EC(Q);let D=OOQ.parse(I),U=D.threshold??w.mergeSimilarityThreshold,Y=new KX(Q.entityService,B),J=[];for(let G of D.existingTopics){let Z=await Y.createTopic(G);if(Z)J.push(Z)}let X=await Y.findMergeCandidate({incoming:{title:D.incomingTopic.title},threshold:U,additionalCandidates:J});return{found:X!==null,candidateTitle:X?.title,candidateScore:X?.score}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(I)=>{await EC(Q);let D=ROQ.parse(I),U=new KX(Q.entityService,B);for(let G of D.existingTopics)await U.createTopic({title:G.title,content:G.content});await vOQ(Q);let Y=lv({entityType:"post",content:D.incomingTopic.content,metadata:{title:D.incomingTopic.title}},"-source"),J=await VC([Y],Q,B,{minRelevanceScore:0,autoMerge:!0,mergeSimilarityThreshold:D.threshold??w.mergeSimilarityThreshold}),X=await Q.entityService.listEntities({entityType:Iw});return{...J,topicCount:X.length,topics:X.map(RhA)}}),Q.eval.registerHandler("rebuildTopics",async(I)=>{await EC(Q);let D=POQ.parse(I),U=new KX(Q.entityService,B);for(let G of D.existingTopics??[])await U.createTopic(G);let Y=D.entities.map((G,Z)=>lv(G,`-rebuild-${Z}`)),J=await _hA(Y,Q,B,w),X=await Q.entityService.listEntities({entityType:Iw});return{...J,topicCount:X.length,topics:X.map(RhA)}}),Q.eval.registerHandler("extractSequentially",async(I)=>{await EC(Q);let D=bOQ.parse(I),U=D.minRelevanceScore??w.minRelevanceScore,Y=new KX(Q.entityService,B),J=[];for(let[G,Z]of D.entities.entries()){let N=lv(Z,`-sequential-${G}`),V=await $.extractFromEntity(N,U);for(let L of V)await Y.createTopic({title:L.title,content:L.content});J.push({extractedTitles:V.map((L)=>L.title)})}let X=await Q.entityService.listEntities({entityType:Iw});return{totalTopics:X.length,perEntity:J,topics:X.map(cv)}}),Q.eval.registerHandler("batchExtract",async(I)=>{await EC(Q);let U=kOQ.parse(I).entities.map((X,G)=>lv(X,`-batch-${G}`)),Y=await VC(U,Q,B,{minRelevanceScore:w.minRelevanceScore}),J=await Q.entityService.listEntities({entityType:Iw});return{...Y,topics:J.map(cv)}})}var yOQ=new GX;async function Yz1({entity:A,config:Q}){let B=uv.parse(A),w=yOQ.parseTopicBody(B.content);return{$type:"ai.rizom.brain.topic",title:w.title,body:w.content,format:"text/markdown",...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"topic",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function vhA(){return{entityType:"topic",collection:"ai.rizom.brain.topic",lexicon:Kw["ai.rizom.brain.topic"],validate:!1,buildRecord:Yz1}}var Jz1={name:"@brains/topics",private:!0,version:"0.2.0-alpha.125",description:"Extract and manage topics from conversations",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var xOQ=new GX;class Xz1 extends _Q{entityType=Iw;schema=uv;adapter=xOQ;unregisterAtprotoProjection;sourceBatch=new jhA;constructor(A={}){super(LC,Jz1,A,v31)}getEntityTypeConfig(){return{weight:0.5,projectionSource:!1}}getTemplates(){return{extraction:h31,"merge-synthesis":m31,"topic-list":u31,"topic-detail":c31}}getDataSources(){return[new bhA(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:MhA,targetType:Iw,job:{type:T31,handler:Bz1({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 yL(A,Iw,{visibility:this.config.extractionVisibility}),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:wz1()},sourceChange:{sourceTypes:this.config.includeEntityTypes,requireInitialSync:!0,jobData:(Q)=>{let B=Q.entity;if(!B)return null;if(!this.shouldProcessEntityType(B.entityType,A.entityService))return null;if(!this.isEntityPublished(B))return null;if(!VN(B.visibility,this.config.extractionVisibility))return null;return this.sourceBatch.add({entityId:B.id,entityType:B.entityType,contentHash:B.contentHash}),{mode:"source-batch"}},jobOptions:()=>({priority:5,source:O$A,delayMs:this.config.sourceChangeBatchDelayMs,deduplication:"skip",deduplicationKey:S31,metadata:{operationType:"data_processing",operationTarget:"topic-source-batch",pluginId:LC}})}}]}async onRegister(A){A.insights.register("topic-distribution",i31()),r31({context:A,pluginId:this.id}),Uz1({context:A,logger:this.logger,config:this.config}),this.unregisterAtprotoProjection=o6.getInstance().register(vhA())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(MhA)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A,Q){if(A===Iw)return!1;if(!this.config.includeEntityTypes.includes(A))return!1;return Q.getEntityTypeConfig(A).projectionSource!==!1}isEntityPublished(A){let B=A.metadata.status;if(B===void 0||B===null)return!0;if(typeof B!=="string")return!1;return this.config.extractableStatuses.includes(B)}async extractAllTopics(A){await $z1({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await fz1({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function v$A(A){return new Xz1(A)}aA();WA();aA();var yhA=H.enum(["linkedin"]),ThA=H.enum(["generating","draft","queued","published","failed"]),Wz1=H.enum(["post","deck"]),Hz1=H.object({id:H.string().min(1).describe("Document entity ID")}),BY=H.object({title:H.string().describe("Short descriptive title (3-6 words) for file naming"),platform:yhA.describe("Target platform"),status:ThA,coverImageId:H.string().optional().describe("Image entity ID for post image"),documents:H.array(Hz1).optional().describe("Document attachments for publishing"),publishedAt:H.string().datetime().optional(),platformPostId:H.string().optional().describe("ID from platform after publishing"),sourceEntityId:H.string().optional().describe("Source entity ID if auto-generated"),sourceEntityType:Wz1.optional().describe("Source entity type (post, deck)")}),Gz1=BY.extend({platform:yhA.optional(),status:ThA.optional()}),Kz1=BY.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:H.string().describe("URL-friendly identifier: {platform}-{title}"),error:H.string().optional()}),Bq=A2.extend({entityType:H.literal("social-post"),metadata:Kz1}),y$A=Bq.extend({frontmatter:BY,body:H.string()}),T$A=y$A.extend({url:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),typeLabel:H.string().optional(),coverImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()});aA();WA();class xhA extends q2{constructor(){super({entityType:"social-post",schema:Bq,frontmatterSchema:BY,supportsCoverImage:!0})}toMarkdown(A){let Q="",B={};try{B=this.parseFrontMatter(A.content,BY),Q=this.extractBody(A.content)}catch{Q=A.content}let w={...B,title:A.metadata.title,platform:A.metadata.platform,status:A.metadata.status,...A.metadata.publishedAt!==void 0&&{publishedAt:A.metadata.publishedAt},...A.metadata.platformPostId!==void 0&&{platformPostId:A.metadata.platformPostId}};return this.buildMarkdown(Q,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,Gz1),B=Q.platform??"linkedin",w=Q.status??"draft",$=`${B}-${X1(Q.title)}`;return{content:A,entityType:"social-post",metadata:{title:Q.title,slug:$,platform:B,status:w,publishedAt:Q.publishedAt,platformPostId:Q.platformPostId}}}parsePostFrontmatter(A){return this.parseFrontMatter(A.content,BY)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}buildStub(A){let B={title:A.title,platform:"linkedin",status:"generating"};return{content:this.buildMarkdown("",B),metadata:{title:A.title,slug:`linkedin-${X1(A.title)}`,platform:"linkedin",status:"generating"}}}}var t9=new xhA;aA();aA();WA();var SOQ=UW.extend({platform:H.enum(["linkedin"]).optional(),status:H.enum(["generating","draft","queued","published","failed"]).optional(),sortByQueue:H.boolean().optional(),nextInQueue:H.boolean().optional()}),gOQ=YW.extend({query:SOQ.optional()});function Fz1(A){let Q=b2(A.content,BY);return y$A.parse({...A,frontmatter:Q.metadata,body:Q.content})}class x$A extends u5{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=gOQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return Fz1(A)}buildDetailResult(A,Q){return{post:A}}buildListResult(A,Q,B){return{posts:A,totalCount:Q?.totalItems??A.length,pagination:Q,baseUrl:B.baseUrl}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A),$=B.entityService;if(w.nextInQueue)return this.fetchNextInQueue(Q,$);if(w.id){let{item:J}=await this.fetchDetail(w.id,$);return Q.parse(this.buildDetailResult(J,null))}let f={};if(w.platform)f.platform=w.platform;if(w.status)f.status=w.status;let I=Object.keys(f).length>0,D=w.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:U,pagination:Y}=await this.fetchList(w,$,{...I&&{filter:{metadata:f}},sortFields:D});return Q.parse(this.buildListResult(U,Y,w))}async fetchNextInQueue(A,Q){let w=(await Q.listEntities({entityType:this.config.entityType,options:{filter:{metadata:{status:"queued"}},sortFields:[{field:"queueOrder",direction:"asc"}],limit:1}}))[0],$=w?Fz1(w):null;return A.parse({post:$})}}WA();var Zz1=H.object({accessToken:H.string().optional(),refreshToken:H.string().optional(),organizationId:H.string().optional(),apiVersion:H.string().regex(/^\d{6}$/).optional()}),ShA=H.object({linkedin:Zz1.optional(),publishInterval:H.number().default(3600000),enabled:H.boolean().default(!0),defaultPrompt:H.string().default("Create an engaging social media post that drives engagement"),maxRetries:H.number().default(3),autoGenerateOnBlogPublish:H.boolean().default(!1)});aA();WA();o8();hhA();import{jsxDEV as z5,Fragment as uOQ}from"preact/jsx-dev-runtime";function hOQ(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function mOQ(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var g$A=({posts:A,pageTitle:Q,pagination:B,baseUrl:w="/social-posts"})=>{let $=Q??"Social Posts",f=B?.totalItems??A.length,I=`Browse all ${f} social ${f===1?"post":"posts"}`;return z5(uOQ,{children:[z5(ZQ,{title:$,description:I},void 0,!1,void 0,this),z5("div",{className:"social-post-list bg-theme",children:z5("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[z5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:$},void 0,!1,void 0,this),A.length===0?z5("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):z5("ul",{className:"space-y-6",children:A.map((D)=>z5("li",{children:z5(PB,{href:D.url,variant:"horizontal",children:z5("div",{className:"flex flex-col sm:flex-row gap-4",children:[D.coverImageUrl&&z5("img",{src:D.coverImageUrl,alt:D.frontmatter.title,className:"w-full sm:w-24 h-48 sm:h-24 object-cover rounded-lg shrink-0"},void 0,!1,void 0,this),z5("div",{className:"flex-1 min-w-0",children:[z5("div",{className:"flex items-start justify-between gap-4 mb-2",children:[z5("h2",{className:"text-lg font-semibold text-heading",children:D.frontmatter.title},void 0,!1,void 0,this),z5("time",{className:"text-sm text-theme-muted shrink-0",children:mOQ(D.frontmatter.publishedAt??D.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z5("div",{className:"flex items-center gap-2 mb-3",children:[z5(mf,{status:D.frontmatter.status},void 0,!1,void 0,this),z5("span",{className:"text-xs text-theme-muted uppercase",children:D.frontmatter.platform},void 0,!1,void 0,this),z5("span",{className:"text-xs text-theme-muted font-mono",children:D.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z5("p",{className:"text-theme leading-relaxed",children:hOQ(D.body,200)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},D.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&z5(bF,{currentPage:B.currentPage,totalPages:B.totalPages,baseUrl:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as q5,Fragment as cOQ}from"preact/jsx-dev-runtime";function Nz1(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var h$A=({post:A})=>{let Q=`Social Post - ${A.frontmatter.platform}`,B=A.body.slice(0,160),w=[{label:"Home",href:"/"},{label:A.listLabel??"Social Posts",href:A.listUrl??"/social-posts"},{label:A.frontmatter.platform}];return q5(cOQ,{children:[q5(ZQ,{title:Q,description:B},void 0,!1,void 0,this),q5("section",{className:"social-post-detail",children:q5("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:q5("div",{className:"max-w-3xl mx-auto",children:[q5(FH,{items:w},void 0,!1,void 0,this),q5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),q5("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[q5(mf,{status:A.frontmatter.status},void 0,!1,void 0,this),q5("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),q5("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&&q5(OF,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),q5(PB,{className:"p-8 mb-8",children:q5("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),q5("div",{className:"space-y-4 text-sm text-theme-muted",children:[q5("div",{children:[q5("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",Nz1(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&q5("div",{children:[q5("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",Nz1(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&q5("div",{children:q5("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 ai(A){return`social-media:${A}`}var lOQ=H.union([H.boolean(),H.object({generate:H.boolean().optional(),prompt:H.string().optional()})]),mhA=H.object({prompt:H.string().optional(),platform:H.enum(["linkedin"]).optional(),sourceEntityType:H.enum(["post","deck"]).optional(),sourceEntityId:H.string().optional(),title:H.string().optional().describe("Required when content is provided directly"),content:H.string().optional(),addToQueue:H.boolean().optional(),generateImage:H.boolean().optional().describe("Auto-generate cover image for post"),coverImage:lOQ.optional().describe("Generic cover image generation request")}),pOQ=VI.extend({slug:H.string().optional()});class MC extends L7{constructor(A,Q){super(A,Q,{schema:mhA,jobTypeName:"social-post-generation",entityType:"social-post"})}async generate(A,Q){let B=A.platform??"linkedin",w=A.addToQueue??!1,{prompt:$,sourceEntityType:f,sourceEntityId:I}=A,{content:D,title:U}=A;if(D&&U)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(D&&!U){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let L=await this.context.ai.generate({prompt:D,templateName:ai(B)});U=L.title,D=L.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(I&&f){await this.reportProgress(Q,{progress:10,message:`Fetching source ${f}`});let L=await this.context.entityService.getEntity({entityType:f,id:I});if(!L)this.failEarly(`Source entity not found: ${f}/${I}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let O=H.object({slug:H.string()}).safeParse(L.metadata),E=O.success?O.data.slug:I,S=await this.context.ai.generate({prompt:`Create an engaging ${B} post to promote this ${f}:
|
|
6524
|
+
`)}async function VC(A,Q,B,w={}){if(A.length===0)return{created:0,merged:0,skipped:0,batches:0};let $=w.minRelevanceScore??0,f=w.autoMerge??!1,I=w.mergeSimilarityThreshold??0.85,D=w.targetVisibility??"public",U=s31(A),Y=new KX(Q.entityService,B),J=w.topicMergeSynthesizer??new khA(Q,B),X=await j$A(Q.entityService,void 0,D),G=new Map,Z=0,N=0,V=0;for(let M of U){B.info(`Processing batch of ${M.length} entities`);let O=qOQ(M),E=_$A({entityTitle:`Batch of ${M.length} entities`,entityType:"batch",content:O,existingTopicTitles:X});try{let T=(await Q.ai.generate({prompt:E,templateName:"topics:extraction"})).topics.filter((y)=>y.relevanceScore>=$);for(let y of T)try{if(f){let g=await Y.findMergeCandidate({incoming:y,threshold:I,additionalCandidates:Array.from(G.values()),targetVisibility:D});if(g){let n=await J.synthesize({existingTopic:g.topic,incomingTopic:y}),m=await Y.applySynthesizedMerge({existingId:g.topic.id,synthesized:{...n,title:g.title},visibility:D});if(!m)throw Error(`Failed to merge topic: ${y.title}`);G.set(m.id,m),N++;continue}}let _=Y.getTopicIdForTitle(y.title,D);if(G.has(_)){V++;continue}let x=await Y.createTopicOptimistic({title:y.title,content:y.content,visibility:D});if(x.topic)G.set(x.topic.id,x.topic);if(x.created)Z++;else V++}catch(_){B.error("Topic batch item failed",{title:y.title,error:y0(_)})}}catch(S){B.error("Batch topic extraction failed",{batchSize:M.length,promptChars:E.length,error:y0(S)})}}let L={created:Z,merged:N,skipped:V,batches:U.length};if(Z>0||N>0)await Q.messaging.send({type:x31,payload:L,broadcast:!0});return L}aA();WA();var LOQ=H.discriminatedUnion("mode",[H.object({mode:H.literal("derive"),reason:H.string().optional()}),H.object({mode:H.literal("rebuild"),reason:H.string().optional()}),H.object({mode:H.literal("source-batch"),minRelevanceScore:H.number().min(0).max(1).optional()})]);class jhA{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 Bz1(A){let{context:Q,logger:B,config:w}=A;return{process:async($)=>{if($.mode==="derive")return await A.extractAllTopics(),{success:!0};if($.mode==="rebuild")return await A.rebuildAllTopics(),{success:!0};return VOQ({context:Q,logger:B,config:w,sourceBatch:A.sourceBatch,isEntityPublished:A.isEntityPublished,minRelevanceScore:$.minRelevanceScore??w.minRelevanceScore})},validateAndParse:($)=>{let f=LOQ.safeParse($??{});return f.success?f.data:null}}}async function VOQ(A){let Q=A.sourceBatch.drain(),B=await Promise.all(Q.map(async(Y)=>({ref:Y,entity:await A.context.entityService.getEntity({entityType:Y.entityType,id:Y.entityId})}))),w=0,$=0,f=0,I=0,D=[];for(let{ref:Y,entity:J}of B){if(!J){$++;continue}if(J.contentHash!==Y.contentHash){w++;continue}if(!A.isEntityPublished(J)){f++;continue}if(!VN(J.visibility,A.config.extractionVisibility)){I++;continue}D.push(J)}if(D.length===0)return{success:!0,sources:Q.length,created:0,merged:0,skipped:0,batches:0,stale:w,missing:$,unpublished:f,hidden:I};let U=await VC(D,A.context,A.logger,{minRelevanceScore:A.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold,targetVisibility:A.config.extractionVisibility});return{success:!0,sources:Q.length,...U,stale:w,missing:$,unpublished:f,hidden:I}}function wz1(){return{priority:5,source:O$A,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:LC}}}async function $z1(A){let Q=await Iz1(A);if(Q.length===0){A.logger.info("No entities to extract topics from");return}A.logger.info(`Batch topic extraction: ${Q.length} entities`);let B=await VC(Q,A.context,A.logger,{minRelevanceScore:A.config.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold,targetVisibility:A.config.extractionVisibility});A.logger.info("Batch topic extraction complete",B)}async function fz1(A){let Q=await Iz1(A),B=await _hA(Q,A.context,A.logger,A.config);A.logger.info("Topic rebuild complete",B)}async function _hA(A,Q,B,w){let $=new KX(Q.entityService,B),f=await $.listTopics({visibility:w.extractionVisibility});for(let D of f)await $.deleteTopic(D.id);if(A.length===0)return{deleted:f.length,created:0,merged:0,skipped:0,batches:0};let I=await VC(A,Q,B,{minRelevanceScore:w.minRelevanceScore,autoMerge:w.autoMerge,mergeSimilarityThreshold:w.mergeSimilarityThreshold,targetVisibility:w.extractionVisibility});return{deleted:f.length,...I}}async function Iz1(A){let Q=EOQ(A),B=[];for(let w of Q){let $=await A.context.entityService.listEntities({entityType:w,options:{filter:{visibilityScope:A.config.extractionVisibility}}});for(let f of $){if(!A.isEntityPublished(f))continue;B.push(f)}}return B}function EOQ(A){return A.context.entityService.getEntityTypes().filter((B)=>A.shouldProcessEntityType(B))}var pv=H.object({entityType:H.string(),content:H.string(),metadata:H.record(H.unknown()).optional()}),MOQ=pv.extend({minRelevanceScore:H.number().optional()}),COQ=H.object({contentA:pv,contentB:pv,minRelevanceScore:H.number().optional(),threshold:H.number().min(0).max(1).optional()}),si=H.object({title:H.string(),content:H.string()}),OOQ=H.object({existingTopics:H.array(si),incomingTopic:si,threshold:H.number().optional()}),ROQ=H.object({existingTopics:H.array(si).default([]),incomingTopic:si.extend({relevanceScore:H.number().min(0).max(1).optional()}),threshold:H.number().optional()}),bOQ=H.object({entities:H.array(pv).min(1),minRelevanceScore:H.number().optional()}),POQ=H.object({existingTopics:H.array(si).optional(),entities:H.array(pv)}),kOQ=H.object({entities:H.array(pv)});function lv(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:gB(A.content),visibility:"public",metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function Dz1(A){return{title:A.title,relevanceScore:A.relevanceScore}}function jOQ(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function _OQ(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:jOQ(Q)}]}}async function EC(A){let Q=await A.entityService.listEntities({entityType:Iw});await Promise.all(Q.map((B)=>A.entityService.deleteEntity({entityType:Iw,id:B.id})))}async function vOQ(A){for(;;){if((await A.jobs.getActiveJobs(["shell:embedding"])).length===0)return;await new Promise((B)=>setTimeout(B,100))}}function Uz1(A){let{context:Q,logger:B,config:w}=A,$=new PhA(Q,B),f=async(I,D,U="")=>{let Y=lv(I,U);return $.extractFromEntity(Y,D)};Q.eval.registerHandler("extractFromEntity",async(I)=>{await EC(Q);let D=MOQ.parse(I),U=D.minRelevanceScore??w.minRelevanceScore,Y=lv(D);return(await $.extractFromEntity(Y,U)).map((X)=>_OQ(X,Y))}),Q.eval.registerHandler("checkMergeSimilarity",async(I)=>{await EC(Q);let D=COQ.parse(I),U=D.minRelevanceScore??w.minRelevanceScore,Y=D.threshold??w.mergeSimilarityThreshold,[J,X]=await Promise.all([f(D.contentA,U,"-a"),f(D.contentB,U,"-b")]),G=new KX(Q.entityService,B),Z=[];for(let L of J){let M=await G.createTopic(L);if(M)Z.push(M)}let N=(await Promise.all(X.map(async(L)=>{let M=await G.findMergeCandidate({incoming:L,threshold:Y,additionalCandidates:Z});if(!M)return null;return{incomingTitle:L.title,candidateTitle:M.title,candidateScore:M.score}}))).filter((L)=>L!==null),V=N.map((L)=>L.candidateTitle);return{topicsA:J.map(Dz1),topicsB:X.map(Dz1),matchingTitles:V,mergeCandidates:N,wouldMerge:N.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(I)=>{await EC(Q);let D=OOQ.parse(I),U=D.threshold??w.mergeSimilarityThreshold,Y=new KX(Q.entityService,B),J=[];for(let G of D.existingTopics){let Z=await Y.createTopic(G);if(Z)J.push(Z)}let X=await Y.findMergeCandidate({incoming:{title:D.incomingTopic.title},threshold:U,additionalCandidates:J});return{found:X!==null,candidateTitle:X?.title,candidateScore:X?.score}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(I)=>{await EC(Q);let D=ROQ.parse(I),U=new KX(Q.entityService,B);for(let G of D.existingTopics)await U.createTopic({title:G.title,content:G.content});await vOQ(Q);let Y=lv({entityType:"post",content:D.incomingTopic.content,metadata:{title:D.incomingTopic.title}},"-source"),J=await VC([Y],Q,B,{minRelevanceScore:0,autoMerge:!0,mergeSimilarityThreshold:D.threshold??w.mergeSimilarityThreshold}),X=await Q.entityService.listEntities({entityType:Iw});return{...J,topicCount:X.length,topics:X.map(RhA)}}),Q.eval.registerHandler("rebuildTopics",async(I)=>{await EC(Q);let D=POQ.parse(I),U=new KX(Q.entityService,B);for(let G of D.existingTopics??[])await U.createTopic(G);let Y=D.entities.map((G,Z)=>lv(G,`-rebuild-${Z}`)),J=await _hA(Y,Q,B,w),X=await Q.entityService.listEntities({entityType:Iw});return{...J,topicCount:X.length,topics:X.map(RhA)}}),Q.eval.registerHandler("extractSequentially",async(I)=>{await EC(Q);let D=bOQ.parse(I),U=D.minRelevanceScore??w.minRelevanceScore,Y=new KX(Q.entityService,B),J=[];for(let[G,Z]of D.entities.entries()){let N=lv(Z,`-sequential-${G}`),V=await $.extractFromEntity(N,U);for(let L of V)await Y.createTopic({title:L.title,content:L.content});J.push({extractedTitles:V.map((L)=>L.title)})}let X=await Q.entityService.listEntities({entityType:Iw});return{totalTopics:X.length,perEntity:J,topics:X.map(cv)}}),Q.eval.registerHandler("batchExtract",async(I)=>{await EC(Q);let U=kOQ.parse(I).entities.map((X,G)=>lv(X,`-batch-${G}`)),Y=await VC(U,Q,B,{minRelevanceScore:w.minRelevanceScore}),J=await Q.entityService.listEntities({entityType:Iw});return{...Y,topics:J.map(cv)}})}var yOQ=new GX;async function Yz1({entity:A,config:Q}){let B=uv.parse(A),w=yOQ.parseTopicBody(B.content);return{$type:"ai.rizom.brain.topic",title:w.title,body:w.content,format:"text/markdown",...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"topic",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function vhA(){return{entityType:"topic",collection:"ai.rizom.brain.topic",lexicon:Kw["ai.rizom.brain.topic"],validate:!1,buildRecord:Yz1}}var Jz1={name:"@brains/topics",private:!0,version:"0.2.0-alpha.127",description:"Extract and manage topics from conversations",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var xOQ=new GX;class Xz1 extends _Q{entityType=Iw;schema=uv;adapter=xOQ;unregisterAtprotoProjection;sourceBatch=new jhA;constructor(A={}){super(LC,Jz1,A,v31)}getEntityTypeConfig(){return{weight:0.5,projectionSource:!1}}getTemplates(){return{extraction:h31,"merge-synthesis":m31,"topic-list":u31,"topic-detail":c31}}getDataSources(){return[new bhA(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:MhA,targetType:Iw,job:{type:T31,handler:Bz1({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 yL(A,Iw,{visibility:this.config.extractionVisibility}),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:wz1()},sourceChange:{sourceTypes:this.config.includeEntityTypes,requireInitialSync:!0,jobData:(Q)=>{let B=Q.entity;if(!B)return null;if(!this.shouldProcessEntityType(B.entityType,A.entityService))return null;if(!this.isEntityPublished(B))return null;if(!VN(B.visibility,this.config.extractionVisibility))return null;return this.sourceBatch.add({entityId:B.id,entityType:B.entityType,contentHash:B.contentHash}),{mode:"source-batch"}},jobOptions:()=>({priority:5,source:O$A,delayMs:this.config.sourceChangeBatchDelayMs,deduplication:"skip",deduplicationKey:S31,metadata:{operationType:"data_processing",operationTarget:"topic-source-batch",pluginId:LC}})}}]}async onRegister(A){A.insights.register("topic-distribution",i31()),r31({context:A,pluginId:this.id}),Uz1({context:A,logger:this.logger,config:this.config}),this.unregisterAtprotoProjection=o6.getInstance().register(vhA())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(MhA)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A,Q){if(A===Iw)return!1;if(!this.config.includeEntityTypes.includes(A))return!1;return Q.getEntityTypeConfig(A).projectionSource!==!1}isEntityPublished(A){let B=A.metadata.status;if(B===void 0||B===null)return!0;if(typeof B!=="string")return!1;return this.config.extractableStatuses.includes(B)}async extractAllTopics(A){await $z1({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await fz1({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function v$A(A){return new Xz1(A)}aA();WA();aA();var yhA=H.enum(["linkedin"]),ThA=H.enum(["generating","draft","queued","published","failed"]),Wz1=H.enum(["post","deck"]),Hz1=H.object({id:H.string().min(1).describe("Document entity ID")}),BY=H.object({title:H.string().describe("Short descriptive title (3-6 words) for file naming"),platform:yhA.describe("Target platform"),status:ThA,coverImageId:H.string().optional().describe("Image entity ID for post image"),documents:H.array(Hz1).optional().describe("Document attachments for publishing"),publishedAt:H.string().datetime().optional(),platformPostId:H.string().optional().describe("ID from platform after publishing"),sourceEntityId:H.string().optional().describe("Source entity ID if auto-generated"),sourceEntityType:Wz1.optional().describe("Source entity type (post, deck)")}),Gz1=BY.extend({platform:yhA.optional(),status:ThA.optional()}),Kz1=BY.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:H.string().describe("URL-friendly identifier: {platform}-{title}"),error:H.string().optional()}),Bq=A2.extend({entityType:H.literal("social-post"),metadata:Kz1}),y$A=Bq.extend({frontmatter:BY,body:H.string()}),T$A=y$A.extend({url:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),typeLabel:H.string().optional(),coverImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()});aA();WA();class xhA extends q2{constructor(){super({entityType:"social-post",schema:Bq,frontmatterSchema:BY,supportsCoverImage:!0})}toMarkdown(A){let Q="",B={};try{B=this.parseFrontMatter(A.content,BY),Q=this.extractBody(A.content)}catch{Q=A.content}let w={...B,title:A.metadata.title,platform:A.metadata.platform,status:A.metadata.status,...A.metadata.publishedAt!==void 0&&{publishedAt:A.metadata.publishedAt},...A.metadata.platformPostId!==void 0&&{platformPostId:A.metadata.platformPostId}};return this.buildMarkdown(Q,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,Gz1),B=Q.platform??"linkedin",w=Q.status??"draft",$=`${B}-${X1(Q.title)}`;return{content:A,entityType:"social-post",metadata:{title:Q.title,slug:$,platform:B,status:w,publishedAt:Q.publishedAt,platformPostId:Q.platformPostId}}}parsePostFrontmatter(A){return this.parseFrontMatter(A.content,BY)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}buildStub(A){let B={title:A.title,platform:"linkedin",status:"generating"};return{content:this.buildMarkdown("",B),metadata:{title:A.title,slug:`linkedin-${X1(A.title)}`,platform:"linkedin",status:"generating"}}}}var t9=new xhA;aA();aA();WA();var SOQ=UW.extend({platform:H.enum(["linkedin"]).optional(),status:H.enum(["generating","draft","queued","published","failed"]).optional(),sortByQueue:H.boolean().optional(),nextInQueue:H.boolean().optional()}),gOQ=YW.extend({query:SOQ.optional()});function Fz1(A){let Q=b2(A.content,BY);return y$A.parse({...A,frontmatter:Q.metadata,body:Q.content})}class x$A extends u5{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=gOQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return Fz1(A)}buildDetailResult(A,Q){return{post:A}}buildListResult(A,Q,B){return{posts:A,totalCount:Q?.totalItems??A.length,pagination:Q,baseUrl:B.baseUrl}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A),$=B.entityService;if(w.nextInQueue)return this.fetchNextInQueue(Q,$);if(w.id){let{item:J}=await this.fetchDetail(w.id,$);return Q.parse(this.buildDetailResult(J,null))}let f={};if(w.platform)f.platform=w.platform;if(w.status)f.status=w.status;let I=Object.keys(f).length>0,D=w.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:U,pagination:Y}=await this.fetchList(w,$,{...I&&{filter:{metadata:f}},sortFields:D});return Q.parse(this.buildListResult(U,Y,w))}async fetchNextInQueue(A,Q){let w=(await Q.listEntities({entityType:this.config.entityType,options:{filter:{metadata:{status:"queued"}},sortFields:[{field:"queueOrder",direction:"asc"}],limit:1}}))[0],$=w?Fz1(w):null;return A.parse({post:$})}}WA();var Zz1=H.object({accessToken:H.string().optional(),refreshToken:H.string().optional(),organizationId:H.string().optional(),apiVersion:H.string().regex(/^\d{6}$/).optional()}),ShA=H.object({linkedin:Zz1.optional(),publishInterval:H.number().default(3600000),enabled:H.boolean().default(!0),defaultPrompt:H.string().default("Create an engaging social media post that drives engagement"),maxRetries:H.number().default(3),autoGenerateOnBlogPublish:H.boolean().default(!1)});aA();WA();o8();hhA();import{jsxDEV as z5,Fragment as uOQ}from"preact/jsx-dev-runtime";function hOQ(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function mOQ(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var g$A=({posts:A,pageTitle:Q,pagination:B,baseUrl:w="/social-posts"})=>{let $=Q??"Social Posts",f=B?.totalItems??A.length,I=`Browse all ${f} social ${f===1?"post":"posts"}`;return z5(uOQ,{children:[z5(ZQ,{title:$,description:I},void 0,!1,void 0,this),z5("div",{className:"social-post-list bg-theme",children:z5("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[z5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:$},void 0,!1,void 0,this),A.length===0?z5("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):z5("ul",{className:"space-y-6",children:A.map((D)=>z5("li",{children:z5(PB,{href:D.url,variant:"horizontal",children:z5("div",{className:"flex flex-col sm:flex-row gap-4",children:[D.coverImageUrl&&z5("img",{src:D.coverImageUrl,alt:D.frontmatter.title,className:"w-full sm:w-24 h-48 sm:h-24 object-cover rounded-lg shrink-0"},void 0,!1,void 0,this),z5("div",{className:"flex-1 min-w-0",children:[z5("div",{className:"flex items-start justify-between gap-4 mb-2",children:[z5("h2",{className:"text-lg font-semibold text-heading",children:D.frontmatter.title},void 0,!1,void 0,this),z5("time",{className:"text-sm text-theme-muted shrink-0",children:mOQ(D.frontmatter.publishedAt??D.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z5("div",{className:"flex items-center gap-2 mb-3",children:[z5(mf,{status:D.frontmatter.status},void 0,!1,void 0,this),z5("span",{className:"text-xs text-theme-muted uppercase",children:D.frontmatter.platform},void 0,!1,void 0,this),z5("span",{className:"text-xs text-theme-muted font-mono",children:D.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z5("p",{className:"text-theme leading-relaxed",children:hOQ(D.body,200)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},D.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&z5(bF,{currentPage:B.currentPage,totalPages:B.totalPages,baseUrl:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as q5,Fragment as cOQ}from"preact/jsx-dev-runtime";function Nz1(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var h$A=({post:A})=>{let Q=`Social Post - ${A.frontmatter.platform}`,B=A.body.slice(0,160),w=[{label:"Home",href:"/"},{label:A.listLabel??"Social Posts",href:A.listUrl??"/social-posts"},{label:A.frontmatter.platform}];return q5(cOQ,{children:[q5(ZQ,{title:Q,description:B},void 0,!1,void 0,this),q5("section",{className:"social-post-detail",children:q5("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:q5("div",{className:"max-w-3xl mx-auto",children:[q5(FH,{items:w},void 0,!1,void 0,this),q5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),q5("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[q5(mf,{status:A.frontmatter.status},void 0,!1,void 0,this),q5("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),q5("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&&q5(OF,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),q5(PB,{className:"p-8 mb-8",children:q5("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),q5("div",{className:"space-y-4 text-sm text-theme-muted",children:[q5("div",{children:[q5("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",Nz1(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&q5("div",{children:[q5("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",Nz1(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&q5("div",{children:q5("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 ai(A){return`social-media:${A}`}var lOQ=H.union([H.boolean(),H.object({generate:H.boolean().optional(),prompt:H.string().optional()})]),mhA=H.object({prompt:H.string().optional(),platform:H.enum(["linkedin"]).optional(),sourceEntityType:H.enum(["post","deck"]).optional(),sourceEntityId:H.string().optional(),title:H.string().optional().describe("Required when content is provided directly"),content:H.string().optional(),addToQueue:H.boolean().optional(),generateImage:H.boolean().optional().describe("Auto-generate cover image for post"),coverImage:lOQ.optional().describe("Generic cover image generation request")}),pOQ=VI.extend({slug:H.string().optional()});class MC extends L7{constructor(A,Q){super(A,Q,{schema:mhA,jobTypeName:"social-post-generation",entityType:"social-post"})}async generate(A,Q){let B=A.platform??"linkedin",w=A.addToQueue??!1,{prompt:$,sourceEntityType:f,sourceEntityId:I}=A,{content:D,title:U}=A;if(D&&U)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(D&&!U){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let L=await this.context.ai.generate({prompt:D,templateName:ai(B)});U=L.title,D=L.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(I&&f){await this.reportProgress(Q,{progress:10,message:`Fetching source ${f}`});let L=await this.context.entityService.getEntity({entityType:f,id:I});if(!L)this.failEarly(`Source entity not found: ${f}/${I}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let O=H.object({slug:H.string()}).safeParse(L.metadata),E=O.success?O.data.slug:I,S=await this.context.ai.generate({prompt:`Create an engaging ${B} post to promote this ${f}:
|
|
6525
6525
|
|
|
6526
6526
|
Source: ${f}/${E}
|
|
6527
6527
|
|
|
6528
6528
|
${L.content}`,templateName:ai(B)});U=S.title,D=S.content,await this.reportProgress(Q,{progress:50,message:"Social post generated from source"})}else if($){await this.reportProgress(Q,{progress:10,message:"Generating social post with AI"});let L=await this.context.ai.generate({prompt:$,templateName:ai(B)});U=L.title,D=L.content,await this.reportProgress(Q,{progress:50,message:"Social post generated"})}else this.failEarly("No content source provided (prompt, sourceEntityId, or content)");if(!D||!U)this.failEarly("Content or title was not generated");let J={title:U,platform:B,status:w?"queued":"draft",...I&&{sourceEntityId:I},...f&&{sourceEntityType:f}},X=t9.createPostContent(J,D),Z=t9.fromMarkdown(X).metadata;if(!Z)this.failEarly("Failed to parse social post metadata");let N=await AK({entityType:"social-post",title:U,deriveId:(L)=>`${B}-${X1(L)}`,regeneratePrompt:"Generate a different social media post title on the same topic.",context:this.context}),V=X;if(N!==U){Z.title=N,Z.slug=`${B}-${X1(N)}`;let L={...J,title:N};V=t9.createPostContent(L,D)}return{id:Z.slug,content:V,metadata:Z,title:N,resultExtras:{slug:Z.slug},createOptions:{deduplicateId:!0}}}async onGenerationFailure(A,Q){await this.context.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:Q}})}async afterCreate(A,Q,B,w){if(A.generateImage){await this.reportProgress(B,{progress:90,message:"Queueing image generation"});let $=w.title??"Social Post";await this.context.jobs.enqueue({type:"image:image-generate",data:{prompt:`Social media graphic for: ${$}`,title:`${$} Image`,aspectRatio:"16:9",targetEntityType:"social-post",targetEntityId:Q},toolContext:{interfaceType:"job",userId:"system"}})}await this.context.messaging.send({type:"generate:report:success",payload:{entityType:"social-post",entityId:Q}})}summarizeDataForLog(A){return{platform:A.platform??"linkedin",hasPrompt:!!A.prompt,sourceEntityType:A.sourceEntityType,addToQueue:A.addToQueue??!1,generateImage:A.generateImage??!1,coverImage:!!A.coverImage}}}function ti(A){if(A.length<=200)return A;return`${A.slice(0,200)}\u2026 (truncated, ${A.length} bytes)`}function iOQ(A){let Q={status:"READY",media:A.urn};if(A.title)Q.title={text:A.title};return Q}function rOQ(A){if(!uhA(A))return null;let Q=m$A(A,"value");if(!Q)return null;let B=m$A(Q,"uploadMechanism");if(!B)return null;let w=m$A(B,"com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest");if(!w)return null;let $=w.uploadUrl,f=Q.asset;if(typeof $!=="string"||typeof f!=="string")return null;return{uploadUrl:$,assetUrn:f}}function dOQ(A){if(!uhA(A))return null;let Q=m$A(A,"value");if(!Q)return null;let{uploadUrl:B,document:w}=Q;if(typeof B!=="string"||typeof w!=="string")return null;return{uploadUrl:B,documentUrn:w}}function m$A(A,Q){let B=A[Q];return uhA(B)?B:null}function uhA(A){return typeof A==="object"&&A!==null}var nOQ="202604";class chA{config;logger;name="linkedin";apiBaseUrl="https://api.linkedin.com/v2";restApiBaseUrl="https://api.linkedin.com/rest";fetch;cachedUserId=null;constructor(A,Q,B={}){this.config=A;this.logger=Q;this.fetch=B.fetch??globalThis.fetch.bind(globalThis)}async publish(A,Q,B,w){if(!this.config.accessToken)throw Error("LinkedIn access token not configured");let $=await this.getAuthor(),f=w?.[0];if(w&&w.length>1)this.logger.warn("LinkedIn document publishing supports one PDF",{count:w.length});let I=null;if(f){let X=await this.uploadDocument($,f);return this.publishDocumentPost($,A,X,f.filename)}else if(B){let X=await this.uploadImage($,B);if(X)I={category:"IMAGE",urn:X}}let D={shareCommentary:{text:A},shareMediaCategory:I?.category??"NONE",...I&&{media:[iOQ(I)]}},U=await this.fetch(`${this.apiBaseUrl}/ugcPosts`,{method:"POST",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":"application/json","X-Restli-Protocol-Version":"2.0.0"},body:JSON.stringify({author:$,lifecycleState:"PUBLISHED",specificContent:{"com.linkedin.ugc.ShareContent":D},visibility:{"com.linkedin.ugc.MemberNetworkVisibility":"PUBLIC"}})});if(!U.ok){let X=ti(await U.text());throw this.logger.error("LinkedIn API error",{status:U.status,error:X}),Error(`LinkedIn API error: ${U.status} - ${X}`)}let Y=U.headers.get("X-RestLi-Id")??"";this.logger.info("LinkedIn post created",{postId:Y,mediaCategory:I?.category??"NONE"});let J={id:Y};if(Y)J.url=`https://www.linkedin.com/feed/update/${Y}`;return J}getRestHeaders(){return{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":"application/json","Linkedin-Version":this.config.apiVersion??nOQ,"X-Restli-Protocol-Version":"2.0.0"}}async uploadImage(A,Q){try{let B=await this.fetch(`${this.apiBaseUrl}/assets?action=registerUpload`,{method:"POST",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":"application/json","X-Restli-Protocol-Version":"2.0.0"},body:JSON.stringify({registerUploadRequest:{recipes:["urn:li:digitalmediaRecipe:feedshare-image"],owner:A,serviceRelationships:[{relationshipType:"OWNER",identifier:"urn:li:userGeneratedContent"}]}})});if(!B.ok){let D=ti(await B.text());return this.logger.warn("LinkedIn image upload registration failed",{status:B.status,error:D}),null}let w=rOQ(await B.json());if(!w)return this.logger.warn("LinkedIn image upload registration was malformed"),null;let{uploadUrl:$,assetUrn:f}=w,I=await this.fetch($,{method:"PUT",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":Q.mimeType},body:new Uint8Array(Q.data)});if(!I.ok)return this.logger.warn("LinkedIn image binary upload failed",{status:I.status}),null;return this.logger.info("LinkedIn image uploaded",{assetUrn:f}),f}catch(B){return this.logger.warn("LinkedIn image upload error",{error:B}),null}}async uploadDocument(A,Q){let B=await this.fetch(`${this.restApiBaseUrl}/documents?action=initializeUpload`,{method:"POST",headers:this.getRestHeaders(),body:JSON.stringify({initializeUploadRequest:{owner:A}})});if(!B.ok){let f=ti(await B.text());throw Error(`LinkedIn document upload initialization failed: ${B.status} - ${f}`)}let w=dOQ(await B.json());if(!w)throw Error("LinkedIn document upload initialization was malformed");let $=await this.fetch(w.uploadUrl,{method:"PUT",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":Q.mimeType},body:new Uint8Array(Q.data)});if(!$.ok)throw Error(`LinkedIn document binary upload failed: ${$.status}`);return this.logger.info("LinkedIn document uploaded",{documentUrn:w.documentUrn,filename:Q.filename}),w.documentUrn}async publishDocumentPost(A,Q,B,w){let $=await this.fetch(`${this.restApiBaseUrl}/posts`,{method:"POST",headers:this.getRestHeaders(),body:JSON.stringify({author:A,commentary:Q,visibility:"PUBLIC",distribution:{feedDistribution:"MAIN_FEED",targetEntities:[],thirdPartyDistributionChannels:[]},content:{media:{id:B,title:w}},lifecycleState:"PUBLISHED",isReshareDisabledByAuthor:!1})});if(!$.ok){let D=ti(await $.text());throw this.logger.error("LinkedIn document post API error",{status:$.status,error:D}),Error(`LinkedIn document post API error: ${$.status} - ${D}`)}let f=$.headers.get("X-RestLi-Id")??"";this.logger.info("LinkedIn document post created",{postId:f,documentUrn:B});let I={id:f};if(f)I.url=`https://www.linkedin.com/feed/update/${f}`;return I}async validateCredentials(){if(!this.config.accessToken)return!1;try{if(this.config.organizationId)return(await this.fetch(`${this.apiBaseUrl}/organizations/${this.config.organizationId}`,{headers:{Authorization:`Bearer ${this.config.accessToken}`}})).ok;return await this.getUserId(),!0}catch{return!1}}async getAuthor(){if(this.config.organizationId)return`urn:li:organization:${this.config.organizationId}`;return this.getUserId()}async getUserId(){if(this.cachedUserId)return this.cachedUserId;if(!this.config.accessToken)throw Error("LinkedIn access token not configured");try{let B=await this.fetch("https://api.linkedin.com/v2/userinfo",{headers:{Authorization:`Bearer ${this.config.accessToken}`}});if(B.ok){let w=await B.json();return this.cachedUserId=`urn:li:person:${w.sub}`,this.cachedUserId}}catch{}let A=await this.fetch("https://api.linkedin.com/v2/me",{headers:{Authorization:`Bearer ${this.config.accessToken}`}});if(!A.ok){let B=ti(await A.text());throw Error(`Failed to get LinkedIn user ID: ${A.status} - ${B}`)}let Q=await A.json();return this.cachedUserId=`urn:li:person:${Q.id}`,this.cachedUserId}}function lhA(A,Q,B={}){return new chA(A,Q,B)}aA();WA();Xw();hhA();var oOQ=H.object({posts:H.array(T$A),totalCount:H.number().optional(),pagination:z7.nullable(),baseUrl:H.string().optional()}),sOQ=H.object({post:T$A});function zz1(){return{linkedin:S$A,"social-post-list":P1({name:"social-post-list",description:"Social post list page template",schema:oOQ,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:g$A}}),"social-post-detail":P1({name:"social-post-detail",description:"Individual social post template",schema:sOQ,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:h$A}})}}WA();var aOQ=H.object({prompt:H.string().optional(),content:H.string().optional(),platform:H.enum(["linkedin"]).default("linkedin")}),tOQ=H.object({prompt:H.string().optional(),content:H.string().optional(),title:H.string().optional(),platform:H.enum(["linkedin"]).optional()});function qz1(A){A.eval.registerHandler("generation",async(Q)=>{let B=aOQ.parse(Q),w=B.content?`Create an engaging LinkedIn post to share this content:
|
|
6529
6529
|
|
|
6530
|
-
${B.content}`:B.prompt??"Write an engaging LinkedIn post";return A.ai.generate({prompt:w,templateName:`social-media:${B.platform}`})}),A.eval.registerHandler("create",async(Q)=>{let B=tOQ.parse(Q),w=[],$=R9.from(async(Y)=>{let J={progress:Y.progress};if(Y.message!==void 0)J.message=Y.message;w.push(J)});if(!$)throw Error("Failed to create progress reporter");let I=await new MC(A.logger,A).process(B,`eval-${Date.now()}`,$),D=!1,U;if(I.success&&I.entityId){let Y=await A.entityService.getEntity({entityType:"social-post",id:I.entityId});D=!!Y,U=Y?.content.slice(0,300)}return{...I,entityExists:D,entityPreview:U,progressSteps:w}})}WA();aA();class ei{sendMessage;logger;entityService;providers;permissions;resolveAttachment;constructor(A){this.sendMessage=A.sendMessage,this.logger=A.logger,this.entityService=A.entityService,this.providers=A.providers,this.permissions=A.permissions,this.resolveAttachment=A.resolveAttachment}async handle(A){let{entityType:Q,entityId:B}=A;if(Q!=="social-post")return;this.permissions.assertEntityActionAllowed(Q,"publish",A.authContext??{userPermissionLevel:"anchor"}),this.logger.debug("Handling publish:execute",{entityId:B});try{let w=await this.entityService.getEntity({entityType:"social-post",id:B});if(!w){await this.reportFailure(Q,B,`Post not found: ${B}`);return}let $=w;if($.metadata.status==="published"){this.logger.debug("Post already published, skipping",{entityId:B});return}let f=$.metadata.platform,I=this.providers.get(f);if(!I){await this.reportFailure(Q,B,`No provider configured for platform: ${f}`);return}let D=b2($.content,BY),U;if(D.metadata.coverImageId)U=await this.fetchImageData(D.metadata.coverImageId);let Y=D.metadata.documents??[],J=await this.fetchDocumentData(Y);try{if(Y.length>0&&J.length===0)throw Error(`Refusing to publish: ${Y.length} document(s) referenced but none could be fetched`);let X=Y.length===0?await this.resolveSourceAttachment(D.metadata):[],G=J.length>0?J:X,Z=G.length?await I.publish(D.content,$.metadata,U,G):await I.publish(D.content,$.metadata,U),N=new Date().toISOString(),V=Z.id||void 0,L={...D.metadata,status:"published",publishedAt:N,...V&&{platformPostId:V}},M=t9.createPostContent(L,D.content);await this.entityService.updateEntity({entity:{...$,content:M,metadata:{...$.metadata,status:"published",publishedAt:N,platformPostId:V}}}),await this.reportSuccess(Q,B,Z.id),this.logger.info(`Post published successfully: ${B}`,{platform:f,platformPostId:V})}catch(X){let G=X instanceof Error?X.message:String(X),Z={...D.metadata,status:"failed"},N=t9.createPostContent(Z,D.content);await this.entityService.updateEntity({entity:{...$,content:N,metadata:{...$.metadata,status:"failed"}}}),await this.reportFailure(Q,B,G),this.logger.error(`Post publish failed: ${B}`,{platform:f,error:G})}}catch(w){let $=y0(w);this.logger.error("Unexpected error in publish handler",{entityId:B,error:$}),await this.reportFailure(Q,B,$)}}async reportSuccess(A,Q,B){await this.sendMessage({type:"publish:report:success",payload:{entityType:A,entityId:Q,result:{id:B}}})}async reportFailure(A,Q,B){await this.sendMessage({type:"publish:report:failure",payload:{entityType:A,entityId:Q,error:B}})}async resolveSourceAttachment(A){if(!this.resolveAttachment||!A.sourceEntityType||!A.sourceEntityId)return[];let Q=await this.resolveAttachment({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:"carousel"});return Q?[Q]:[]}async fetchDocumentData(A){if(!A?.length)return[];let Q=[];for(let B of A){let w=await this.fetchSingleDocumentData(B.id);if(w)Q.push(w)}return Q}async fetchSingleDocumentData(A){try{let Q=await this.entityService.getEntity({entityType:"document",id:A});if(!Q){this.logger.warn("Document not found",{documentId:A});return}let B=Q.content.match(/^data:application\/pdf;base64,(.+)$/);if(!B?.[1]){this.logger.warn("Invalid document data URL format",{documentId:A});return}let w=typeof Q.metadata.filename==="string"?Q.metadata.filename:`${A}.pdf`;return{type:"document",data:Buffer.from(B[1],"base64"),mimeType:"application/pdf",filename:w}}catch(Q){this.logger.warn("Failed to fetch document",{documentId:A,error:Q});return}}async fetchImageData(A){try{let Q=await this.entityService.getEntity({entityType:"image",id:A});if(!Q){this.logger.warn("Cover image not found",{imageId:A});return}let w=Q.content.match(/^data:([^;]+);base64,(.+)$/);if(!w?.[1]||!w[2]){this.logger.warn("Invalid image data URL format",{imageId:A});return}let $=w[1],f=w[2];return{data:Buffer.from(f,"base64"),mimeType:$}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function Lz1(A,Q,B){if(Q.size===0){B.debug("No providers configured, skipping publish-pipeline registration");return}A.messaging.subscribe("system:plugins:ready",async()=>{let w=Q.values().next().value;return await A.messaging.send({type:"publish:register",payload:{entityType:"social-post",provider:w,config:{publishResultIdField:"platformPostId"}}}),B.info("Registered social-post with publish-pipeline"),{success:!0}})}function Vz1(A,Q,B){let w=new ei({sendMessage:A.messaging.send,logger:B.child("PublishExecuteHandler"),entityService:A.entityService,providers:Q,permissions:A.permissions,resolveAttachment:A.attachments.resolve});A.messaging.subscribe("publish:execute",async($)=>{return await w.handle($.payload),{success:!0}}),B.debug("Subscribed to publish:execute messages")}WA();function Ez1(A,Q){A.messaging.subscribe("entity:updated",async(B)=>{let{entityType:w,entityId:$,entity:f}=B.payload;if(w!=="post")return{success:!0};if(f.metadata?.status!=="queued")return{success:!0};try{if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:$}},limit:1}})).length>0)return Q.debug(`Social post already exists for ${$}, skipping auto-generate`),{success:!0};return await A.messaging.send({type:"social:auto-generate",payload:{sourceEntityType:w,sourceEntityId:$,platform:"linkedin"}}),Q.info(`Auto-generate social post triggered for queued post ${$}`),{success:!0}}catch(D){let U=y0(D);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:U}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function Mz1(A,Q){A.messaging.subscribe("social:auto-generate",async(B)=>{let{sourceEntityType:w,sourceEntityId:$,platform:f}=B.payload;try{let I=await A.jobs.enqueue({type:`${t9.entityType}:generation`,data:{sourceEntityType:w,sourceEntityId:$,platform:f,addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info(`Social post generation job enqueued for ${w}/${$}`,{jobId:I}),{success:!0,jobId:I}}catch(I){let D=y0(I);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:D}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function Cz1(A,Q){A.messaging.subscribe("generate:execute",async(B)=>{let{entityType:w}=B.payload;if(w!=="social-post")return{success:!0};Q.info("Received generate:execute for social-post");try{let $=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:5}});if($.length===0)return Q.info("No published posts found for social post generation"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"No published posts available for social post generation"}}),{success:!0};let f=null;for(let D of $)if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:D.id}},limit:1}})).length===0){f=D;break}if(!f)return Q.info("All recent posts already have social posts"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"All recent posts already have social posts generated"}}),{success:!0};let I=await A.jobs.enqueue({type:`${t9.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:f.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:I,sourcePostId:f.id}),{success:!0}}catch($){let f=y0($);return Q.error("Failed to handle generate:execute:",{error:f}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:f}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}async function Oz1({entity:A,config:Q}){let B=Bq.parse(A),w=t9.parsePostFrontmatter(B),$=t9.getPostContent(B);return{$type:"ai.rizom.brain.socialPost",title:w.title,platform:w.platform,body:$,format:"text/markdown",status:w.status,...w.publishedAt&&{publishedAt:w.publishedAt},...w.platformPostId&&{platformPostId:w.platformPostId},...w.sourceEntityType&&{sourceLocalEntityType:w.sourceEntityType},...w.sourceEntityId&&{sourceLocalEntityId:w.sourceEntityId},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"social-post",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function phA(){return{entityType:"social-post",collection:"ai.rizom.brain.socialPost",lexicon:Kw["ai.rizom.brain.socialPost"],validate:!1,buildRecord:Oz1}}var Rz1={name:"@brains/social-media",private:!0,version:"0.2.0-alpha.125",description:"Multi-provider social media posting with queue-based publishing",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class ihA extends _Q{entityType=t9.entityType;schema=Bq;adapter=t9;providers=new Map;unregisterAtprotoProjection;constructor(A){super("social-media",Rz1,A,ShA)}createGenerationHandler(A){return new MC(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return zz1()}getDataSources(){return[new x$A(this.logger.child("SocialPostDataSource"))]}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}async onRegister(A){if(this.initializeProviders(),Lz1(A,this.providers,this.logger),Vz1(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)Ez1(A,this.logger),Mz1(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");Cz1(A,this.logger),qz1(A),this.unregisterAtprotoProjection=o6.getInstance().register(phA()),this.logger.info("Social media plugin registered successfully")}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}initializeProviders(){if(this.config.linkedin?.accessToken){let A=lhA(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function Ar(A){return new ihA(A)}WA();var ARQ=H.enum(["draft","queued","published","failed"]),bz1=H.object({status:ARQ.default("draft"),queueOrder:H.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:H.string().datetime().optional()});class rhA{name="internal";async publish(A,Q){return{id:"internal"}}}var Qr={interfaceType:"system",userId:"system",userPermissionLevel:"anchor",authorization:"system"},l4={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"},wq={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"},Pz1={REGISTER:"publish-assets:register"};WA();var QRQ=H.enum(["provider"]),kz1=H.object({executionMode:QRQ.optional(),publishResultIdField:H.string().min(1).optional(),publishTimestampField:H.string().min(1).optional(),enabled:H.boolean().optional()}).strict();var BRQ=H.object({skipIfDraftExists:H.boolean().optional(),minSourceEntities:H.number().optional(),maxUnpublishedDrafts:H.number().optional(),sourceEntityType:H.string().optional()}),jz1=H.object({entitySchedules:H.record(H.string(),H.string()).optional(),generationSchedules:H.record(H.string(),H.string()).optional(),generationConditions:H.record(H.string(),BRQ).optional()});class mH{static instance=null;queues=new Map;static getInstance(){return mH.instance??=new mH,mH.instance}static resetInstance(){mH.instance=null}static createFresh(){return new mH}constructor(){}async add(A,Q,B=Qr){let w=this.getOrCreateQueue(A),$=w.find((D)=>D.entityId===Q);if($)return{position:$.position};let f=w.length+1,I={entityId:Q,entityType:A,position:f,queuedAt:new Date().toISOString(),authContext:{...B}};return w.push(I),{position:f}}async remove(A,Q){let B=this.queues.get(A);if(!B)return;let w=B.findIndex(($)=>$.entityId===Q);if(w===-1)return;B.splice(w,1),this.recalculatePositions(B)}async reorder(A,Q,B){let w=this.queues.get(A);if(!w)return;let $=w.findIndex((D)=>D.entityId===Q);if($===-1)return;let[f]=w.splice($,1);if(!f)return;let I=Math.max(0,Math.min(B-1,w.length));w.splice(I,0,f),this.recalculatePositions(w)}async list(A){let Q=this.queues.get(A);if(!Q)return[];return[...Q]}async getNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;return Q[0]??null}async getNextAcrossTypes(){let A=null;for(let Q of this.queues.values()){let B=Q[0];if(!B)continue;if(!A||B.queuedAt<A.queuedAt)A=B}return A}async popNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;let B=Q.shift()??null;if(B)this.recalculatePositions(Q);return B}getRegisteredTypes(){return Array.from(this.queues.keys())}async getQueuedEntityTypes(){let A=[];for(let[Q,B]of this.queues.entries())if(B.length>0)A.push(Q);return A}getOrCreateQueue(A){let Q=this.queues.get(A);if(!Q)Q=[],this.queues.set(A,Q);return Q}recalculatePositions(A){A.forEach((Q,B)=>{Q.position=B+1})}}class uH{static instance=null;providers=new Map;executionModes=new Map;publishResultIdFields=new Map;publishTimestampFields=new Map;defaultProvider=new rhA;static getInstance(){return uH.instance??=new uH,uH.instance}static resetInstance(){uH.instance=null}static createFresh(){return new uH}constructor(){}register(A,Q,B){let w=this.providers.get(A);if(w&&w.name!=="internal"&&Q.name==="internal")return;if(this.providers.set(A,Q),this.executionModes.set(A,B?.executionMode??"provider"),B?.publishResultIdField)this.publishResultIdFields.set(A,B.publishResultIdField);else this.publishResultIdFields.delete(A);if(B?.publishTimestampField)this.publishTimestampFields.set(A,B.publishTimestampField);else this.publishTimestampFields.delete(A)}get(A){return this.providers.get(A)??this.defaultProvider}getExecutionMode(A){return this.executionModes.get(A)??"provider"}getPublishResultIdField(A){return this.publishResultIdFields.get(A)}getPublishTimestampField(A){return this.publishTimestampFields.get(A)}has(A){return this.providers.has(A)}unregister(A){this.providers.delete(A),this.executionModes.delete(A),this.publishResultIdFields.delete(A),this.publishTimestampFields.delete(A)}getRegisteredTypes(){return Array.from(this.providers.keys())}}WA();WA();async function _z1(A,Q){if(!Q.publishExecutor){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:"Publish executor not configured",retryCount:0,willRetry:!1});return}await wRQ(A,Q)}async function wRQ(A,Q){if(!Q.publishExecutor)return;try{let B=await Q.publishExecutor.publish({entityType:A.entityType,id:A.entityId});if("error"in B){let w={entityType:A.entityType,entityId:A.entityId,error:B.error,retryCount:0,willRetry:!1};if(Q.messageBus)await Q.messageBus.send({type:l4.FAILED,payload:w,sender:"publish-service"});Q.onFailed?.(w);return}dhA(A.entityType,A.entityId,B.result,Q)}catch(B){let w=y0(B);Q.retryTracker.recordFailure(A.entityId,w);let $=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:w,retryCount:$?.retryCount??1,willRetry:!1})}}function dhA(A,Q,B,w){if(w.retryTracker.clearRetries(Q),w.messageBus)w.messageBus.send({type:l4.COMPLETED,payload:{entityType:A,entityId:Q,result:B},sender:"publish-service"});w.onPublish?.({entityType:A,entityId:Q,result:B})}function vz1(A,Q,B,w){w.retryTracker.recordFailure(Q,B);let $=w.retryTracker.getRetryInfo(Q),f={entityType:A,entityId:Q,error:B,retryCount:$?.retryCount??1,willRetry:!1};if(w.messageBus)w.messageBus.send({type:l4.FAILED,payload:f,sender:"publish-service"});w.onFailed?.(f)}async function yz1(A,Q){let B=Q.generationConditions[A];if(B&&Q.onCheckGenerationConditions){let $=await Q.onCheckGenerationConditions(A,B);if(!$.shouldGenerate){if(Q.messageBus)Q.messageBus.send({type:wq.SKIPPED,payload:{entityType:A,reason:$.reason??"Conditions not met"},sender:"content-pipeline"});return}}let w={entityType:A};if(Q.messageBus)await Q.messageBus.send({type:wq.EXECUTE,payload:w,sender:"content-pipeline"});Q.onGenerate?.(w)}function Tz1(A,Q,B){if(B)B.send({type:wq.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function xz1(A,Q,B){if(B)B.send({type:wq.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var $RQ=1000;class nhA{deps;publishJobs=new Map;immediateIntervalJob=null;constructor(A){this.deps=A}start(){for(let[A,Q]of Object.entries(this.entitySchedules)){let B=this.deps.config.backend.scheduleCron(Q,()=>this.processEntityType(A));this.publishJobs.set(A,B)}this.immediateIntervalJob=this.deps.config.backend.scheduleInterval($RQ,()=>this.processUnscheduledTypes())}stop(){if(fRQ(this.publishJobs),this.immediateIntervalJob)this.immediateIntervalJob.stop(),this.immediateIntervalJob=null}async processEntityType(A){if(!this.deps.isRunning())return;try{let Q=await this.deps.config.queueManager.getNext(A);if(Q)await this.processEntry(Q)}catch(Q){this.deps.config.logger.error(`Scheduler error for ${A}:`,Q)}}async processUnscheduledTypes(){if(!this.deps.isRunning())return;try{let A=await this.deps.config.queueManager.getQueuedEntityTypes();for(let Q of A)if(!this.entitySchedules[Q]){let B=await this.deps.config.queueManager.getNext(Q);if(B){await this.processEntry(B);break}}}catch(A){this.deps.config.logger.error("Scheduler error for unscheduled types:",A)}}async processEntry(A){await this.deps.config.queueManager.remove(A.entityType,A.entityId);let Q=this.deps.getPublishDeps();await _z1(A,Q)}get entitySchedules(){return this.deps.config.entitySchedules}}function fRQ(A){for(let Q of A.values())Q.stop();A.clear()}class ohA{deps;generationJobs=new Map;constructor(A){this.deps=A}start(){for(let[A,Q]of Object.entries(this.generationSchedules)){let B=this.deps.config.backend.scheduleCron(Q,()=>this.handleTriggerGeneration(A));this.generationJobs.set(A,B)}}stop(){IRQ(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await yz1(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 IRQ(A){for(let Q of A.values())Q.stop();A.clear()}class FX{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return FX.instance??=new FX(A),FX.instance}static resetInstance(){if(FX.instance)FX.instance.stop();FX.instance=null}static createFresh(A){return new FX(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new nhA({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new ohA({config:this.config,getGenerationDeps:()=>this.generationDeps,isRunning:()=>this.running})}async start(){if(this.running)return;this.running=!0,this.publishRunner.start(),this.generationRunner.start()}async stop(){this.running=!1,this.publishRunner.stop(),this.generationRunner.stop()}isRunning(){return this.running}completePublish(A,Q,B){dhA(A,Q,B,this.publishDeps)}failPublish(A,Q,B){vz1(A,Q,B,this.publishDeps)}async publishDirect(A,Q,B,w){return this.config.providerRegistry.get(A).publish(B,w)}completeGeneration(A,Q){Tz1(A,Q,this.config.messageBus)}failGeneration(A,Q){xz1(A,Q,this.config.messageBus)}get entitySchedules(){return this.config.entitySchedules}get generationSchedules(){return this.config.generationSchedules}get publishDeps(){return{retryTracker:this.config.retryTracker,messageBus:this.config.messageBus,publishExecutor:this.config.publishExecutor,onPublish:this.config.onPublish,onFailed:this.config.onFailed}}get generationDeps(){return{logger:this.config.logger,messageBus:this.config.messageBus,generationConditions:this.config.generationConditions,onCheckGenerationConditions:this.config.onCheckGenerationConditions,onGenerate:this.config.onGenerate}}validateCronExpressions(){for(let[A,Q]of Object.entries(this.entitySchedules))this.validateCronExpression(A,Q,"publish");for(let[A,Q]of Object.entries(this.generationSchedules))this.validateCronExpression(A,Q,"generation")}validateCronExpression(A,Q,B){try{this.config.backend.validateCron(Q)}catch(w){throw Error(`Invalid ${B} cron expression for ${A}: "${Q}" - ${y0(w)}`)}}}class cH{static instance=null;retries=new Map;static getInstance(){return cH.instance??=new cH,cH.instance}static resetInstance(){cH.instance=null}static createFresh(){return new cH}constructor(){}recordFailure(A,Q){let w=(this.retries.get(A)?.retryCount??0)+1;this.retries.set(A,{entityId:A,retryCount:w,lastError:Q})}clearRetries(A){this.retries.delete(A)}getRetryInfo(A){let Q=this.retries.get(A);if(!Q)return null;return{entityId:Q.entityId,retryCount:Q.retryCount,lastError:Q.lastError}}}function l7(A,Q,B,w,$,f,I,D){return l7.fromTZ(l7.tp(A,Q,B,w,$,f,I),D)}l7.fromTZISO=(A,Q,B)=>l7.fromTZ(DRQ(A,Q),B);l7.fromTZ=function(A,Q){let B=new Date(Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)),w=shA(A.tz,B),$=new Date(B.getTime()-w),f=shA(A.tz,$);if(f-w===0)return $;{let I=new Date(B.getTime()-f),D=shA(A.tz,I);if(D-f===0)return I;if(!Q&&D-f>0)return I;if(Q)throw Error("Invalid date passed to fromTZ()");return $}};l7.toTZ=function(A,Q){let B=A.toLocaleString("en-US",{timeZone:Q}).replace(/[\u202f]/," "),w=new Date(B);return{y:w.getFullYear(),m:w.getMonth()+1,d:w.getDate(),h:w.getHours(),i:w.getMinutes(),s:w.getSeconds(),tz:Q}};l7.tp=(A,Q,B,w,$,f,I)=>({y:A,m:Q,d:B,h:w,i:$,s:f,tz:I});function shA(A,Q=new Date){let B=Q.toLocaleString("en-US",{timeZone:A,timeZoneName:"shortOffset"}).split(" ").slice(-1)[0],w=Q.toLocaleString("en-US").replace(/[\u202f]/," ");return Date.parse(`${w} GMT`)-Date.parse(`${w} ${B}`)}function DRQ(A,Q){let B=new Date(Date.parse(A));if(isNaN(B))throw Error("minitz: Invalid ISO8601 passed to parser.");let w=A.substring(9);return A.includes("Z")||w.includes("-")||w.includes("+")?l7.tp(B.getUTCFullYear(),B.getUTCMonth()+1,B.getUTCDate(),B.getUTCHours(),B.getUTCMinutes(),B.getUTCSeconds(),"Etc/UTC"):l7.tp(B.getFullYear(),B.getMonth()+1,B.getDate(),B.getHours(),B.getMinutes(),B.getSeconds(),Q)}l7.minitz=l7;var ahA=32,wr=31|ahA,mz1=[1,2,4,8,16],Sz1=class{pattern;timezone;second;minute;hour;day;month;dayOfWeek;lastDayOfMonth;starDOM;starDOW;constructor(A,Q){this.pattern=A,this.timezone=Q,this.second=Array(60).fill(0),this.minute=Array(60).fill(0),this.hour=Array(24).fill(0),this.day=Array(31).fill(0),this.month=Array(12).fill(0),this.dayOfWeek=Array(7).fill(0),this.lastDayOfMonth=!1,this.starDOM=!1,this.starDOW=!1,this.parse()}parse(){if(!(typeof this.pattern=="string"||this.pattern instanceof String))throw TypeError("CronPattern: Pattern has to be of type string.");this.pattern.indexOf("@")>=0&&(this.pattern=this.handleNicknames(this.pattern).trim());let A=this.pattern.replace(/\s+/g," ").split(" ");if(A.length<5||A.length>6)throw TypeError("CronPattern: invalid configuration format ('"+this.pattern+"'), exactly five or six space separated parts are required.");if(A.length===5&&A.unshift("0"),A[3].indexOf("L")>=0&&(A[3]=A[3].replace("L",""),this.lastDayOfMonth=!0),A[3]=="*"&&(this.starDOM=!0),A[4].length>=3&&(A[4]=this.replaceAlphaMonths(A[4])),A[5].length>=3&&(A[5]=this.replaceAlphaDays(A[5])),A[5]=="*"&&(this.starDOW=!0),this.pattern.indexOf("?")>=0){let Q=new wY(new Date,this.timezone).getDate(!0);A[0]=A[0].replace("?",Q.getSeconds().toString()),A[1]=A[1].replace("?",Q.getMinutes().toString()),A[2]=A[2].replace("?",Q.getHours().toString()),this.starDOM||(A[3]=A[3].replace("?",Q.getDate().toString())),A[4]=A[4].replace("?",(Q.getMonth()+1).toString()),this.starDOW||(A[5]=A[5].replace("?",Q.getDay().toString()))}this.throwAtIllegalCharacters(A),this.partToArray("second",A[0],0,1),this.partToArray("minute",A[1],0,1),this.partToArray("hour",A[2],0,1),this.partToArray("day",A[3],-1,1),this.partToArray("month",A[4],-1,1),this.partToArray("dayOfWeek",A[5],0,wr),this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(A,Q,B,w){let $=this[A],f=A==="day"&&this.lastDayOfMonth;if(Q===""&&!f)throw TypeError("CronPattern: configuration entry "+A+" ("+Q+") is empty, check for trailing spaces.");if(Q==="*")return $.fill(w);let I=Q.split(",");if(I.length>1)for(let D=0;D<I.length;D++)this.partToArray(A,I[D],B,w);else Q.indexOf("-")!==-1&&Q.indexOf("/")!==-1?this.handleRangeWithStepping(Q,A,B,w):Q.indexOf("-")!==-1?this.handleRange(Q,A,B,w):Q.indexOf("/")!==-1?this.handleStepping(Q,A,B,w):Q!==""&&this.handleNumber(Q,A,B,w)}throwAtIllegalCharacters(A){for(let Q=0;Q<A.length;Q++)if((Q===5?/[^/*0-9,\-#L]+/:/[^/*0-9,-]+/).test(A[Q]))throw TypeError("CronPattern: configuration entry "+Q+" ("+A[Q]+") contains illegal characters.")}handleNumber(A,Q,B,w){let $=this.extractNth(A,Q),f=parseInt($[0],10)+B;if(isNaN(f))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,f,$[1]||w)}setPart(A,Q,B){if(!Object.prototype.hasOwnProperty.call(this,A))throw TypeError("CronPattern: Invalid part specified: "+A);if(A==="dayOfWeek"){if(Q===7&&(Q=0),Q<0||Q>6)throw RangeError("CronPattern: Invalid value for dayOfWeek: "+Q);this.setNthWeekdayOfMonth(Q,B);return}if(A==="second"||A==="minute"){if(Q<0||Q>=60)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="hour"){if(Q<0||Q>=24)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="day"){if(Q<0||Q>=31)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="month"&&(Q<0||Q>=12))throw RangeError("CronPattern: Invalid value for "+A+": "+Q);this[A][Q]=B}handleRangeWithStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(f===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,I,D,U]=f,Y=parseInt(I,10)+B,J=parseInt(D,10)+B,X=parseInt(U,10);if(isNaN(Y))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(J))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(isNaN(X))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(X===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(X>this[Q].length)throw TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+this[Q].length+")");if(Y>J)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let G=Y;G<=J;G+=X)this.setPart(Q,G,$[1]||w)}extractNth(A,Q){let B=A,w;if(B.includes("#")){if(Q!=="dayOfWeek")throw Error("CronPattern: nth (#) only allowed in day-of-week field");w=B.split("#")[1],B=B.split("#")[0]}return[B,w]}handleRange(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].split("-");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let I=parseInt(f[0],10)+B,D=parseInt(f[1],10)+B;if(isNaN(I))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(I>D)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let U=I;U<=D;U++)this.setPart(Q,U,$[1]||w)}handleStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].split("/");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");f[0]===""&&(f[0]="*");let I=0;f[0]!=="*"&&(I=parseInt(f[0],10)+B);let D=parseInt(f[1],10);if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(D===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(D>this[Q].length)throw TypeError("CronPattern: Syntax error, max steps for part is ("+this[Q].length+")");for(let U=I;U<this[Q].length;U+=D)this.setPart(Q,U,$[1]||w)}replaceAlphaDays(A){return A.replace(/-sun/gi,"-7").replace(/sun/gi,"0").replace(/mon/gi,"1").replace(/tue/gi,"2").replace(/wed/gi,"3").replace(/thu/gi,"4").replace(/fri/gi,"5").replace(/sat/gi,"6")}replaceAlphaMonths(A){return A.replace(/jan/gi,"1").replace(/feb/gi,"2").replace(/mar/gi,"3").replace(/apr/gi,"4").replace(/may/gi,"5").replace(/jun/gi,"6").replace(/jul/gi,"7").replace(/aug/gi,"8").replace(/sep/gi,"9").replace(/oct/gi,"10").replace(/nov/gi,"11").replace(/dec/gi,"12")}handleNicknames(A){let Q=A.trim().toLowerCase();return Q==="@yearly"||Q==="@annually"?"0 0 1 1 *":Q==="@monthly"?"0 0 1 * *":Q==="@weekly"?"0 0 * * 0":Q==="@daily"?"0 0 * * *":Q==="@hourly"?"0 * * * *":A}setNthWeekdayOfMonth(A,Q){if(typeof Q!="number"&&Q==="L")this.dayOfWeek[A]=this.dayOfWeek[A]|ahA;else if(Q===wr)this.dayOfWeek[A]=wr;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|mz1[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},gz1=[31,28,31,30,31,30,31,31,30,31,30,31],tF=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],wY=class A{tz;ms;second;minute;hour;day;month;year;constructor(Q,B){if(this.tz=B,Q&&Q instanceof Date)if(!isNaN(Q))this.fromDate(Q);else throw TypeError("CronDate: Invalid date passed to CronDate constructor");else if(Q===void 0)this.fromDate(new Date);else if(Q&&typeof Q=="string")this.fromString(Q);else if(Q instanceof A)this.fromCronDate(Q);else throw TypeError("CronDate: Invalid type ("+typeof Q+") passed to CronDate constructor")}isNthWeekdayOfMonth(Q,B,w,$){let f=new Date(Date.UTC(Q,B,w)).getUTCDay(),I=0;for(let D=1;D<=w;D++)new Date(Date.UTC(Q,B,D)).getUTCDay()===f&&I++;if($&wr&&mz1[I-1]&$)return!0;if($&ahA){let D=new Date(Date.UTC(Q,B+1,0)).getUTCDate();for(let U=w+1;U<=D;U++)if(new Date(Date.UTC(Q,B,U)).getUTCDay()===f)return!1;return!0}return!1}fromDate(Q){if(this.tz!==void 0)if(typeof this.tz=="number")this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes()+this.tz,this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),this.apply();else{let B=l7.toTZ(Q,this.tz);this.ms=Q.getMilliseconds(),this.second=B.s,this.minute=B.i,this.hour=B.h,this.day=B.d,this.month=B.m-1,this.year=B.y}else this.ms=Q.getMilliseconds(),this.second=Q.getSeconds(),this.minute=Q.getMinutes(),this.hour=Q.getHours(),this.day=Q.getDate(),this.month=Q.getMonth(),this.year=Q.getFullYear()}fromCronDate(Q){this.tz=Q.tz,this.year=Q.year,this.month=Q.month,this.day=Q.day,this.hour=Q.hour,this.minute=Q.minute,this.second=Q.second,this.ms=Q.ms}apply(){if(this.month>11||this.day>gz1[this.month]||this.hour>59||this.minute>59||this.second>59||this.hour<0||this.minute<0||this.second<0){let Q=new Date(Date.UTC(this.year,this.month,this.day,this.hour,this.minute,this.second,this.ms));return this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes(),this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),!0}else return!1}fromString(Q){if(typeof this.tz=="number"){let B=l7.fromTZISO(Q);this.ms=B.getUTCMilliseconds(),this.second=B.getUTCSeconds(),this.minute=B.getUTCMinutes(),this.hour=B.getUTCHours(),this.day=B.getUTCDate(),this.month=B.getUTCMonth(),this.year=B.getUTCFullYear(),this.apply()}else return this.fromDate(l7.fromTZISO(Q,this.tz))}findNext(Q,B,w,$){let f=this[B],I;w.lastDayOfMonth&&(this.month!==1?I=gz1[this.month]:I=new Date(Date.UTC(this.year,this.month+1,0,0,0,0,0)).getUTCDate());let D=!w.starDOW&&B=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0;for(let U=this[B]+$;U<w[B].length;U++){let Y=w[B][U];if(B==="day"&&w.lastDayOfMonth&&U-$==I&&(Y=1),B==="day"&&!w.starDOW){let J=w.dayOfWeek[(D+(U-$-1))%7];if(J&&J&wr)J=this.isNthWeekdayOfMonth(this.year,this.month,U-$,J)?1:0;else if(J)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${J}`);Q.legacyMode&&!w.starDOM?Y=Y||J:Y=Y&&J}if(Y)return this[B]=U-$,f!==this[B]?2:1}return 3}recurse(Q,B,w){let $=this.findNext(B,tF[w][0],Q,tF[w][2]);if($>1){let f=w+1;for(;f<tF.length;)this[tF[f][0]]=-tF[f][2],f++;if($===3)return this[tF[w][1]]++,this[tF[w][0]]=-tF[w][2],this.apply(),this.recurse(Q,B,0);if(this.apply())return this.recurse(Q,B,w-1)}return w+=1,w>=tF.length?this:this.year>=3000?null:this.recurse(Q,B,w)}increment(Q,B,w){return this.second+=B.interval!==void 0&&B.interval>1&&w?B.interval:1,this.ms=0,this.apply(),this.recurse(Q,B,0)}getDate(Q){return Q||this.tz===void 0?new Date(this.year,this.month,this.day,this.hour,this.minute,this.second,this.ms):typeof this.tz=="number"?new Date(Date.UTC(this.year,this.month,this.day,this.hour,this.minute-this.tz,this.second,this.ms)):l7.fromTZ(l7.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function URQ(A){if(A===void 0&&(A={}),delete A.name,A.legacyMode=A.legacyMode===void 0?!0:A.legacyMode,A.paused=A.paused===void 0?!1:A.paused,A.maxRuns=A.maxRuns===void 0?1/0:A.maxRuns,A.catch=A.catch===void 0?!1:A.catch,A.interval=A.interval===void 0?0:parseInt(A.interval.toString(),10),A.utcOffset=A.utcOffset===void 0?void 0:parseInt(A.utcOffset.toString(),10),A.unref=A.unref===void 0?!1:A.unref,A.startAt&&(A.startAt=new wY(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new wY(A.stopAt,A.timezone)),A.interval!==null){if(isNaN(A.interval))throw Error("CronOptions: Supplied value for interval is not a number");if(A.interval<0)throw Error("CronOptions: Supplied value for interval can not be negative")}if(A.utcOffset!==void 0){if(isNaN(A.utcOffset))throw Error("CronOptions: Invalid value passed for utcOffset, should be number representing minutes offset from UTC.");if(A.utcOffset<-870||A.utcOffset>870)throw Error("CronOptions: utcOffset out of bounds.");if(A.utcOffset!==void 0&&A.timezone)throw Error("CronOptions: Combining 'utcOffset' with 'timezone' is not allowed.")}if(A.unref!==!0&&A.unref!==!1)throw Error("CronOptions: Unref should be either true, false or undefined(false).");return A}function Br(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function YRQ(A){return Br(A)}function JRQ(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var hz1=30000,u$A=[],thA=class{name;options;_states;fn;constructor(A,Q,B){let w,$;if(Br(Q))$=Q;else if(typeof Q=="object")w=Q;else if(Q!==void 0)throw Error("Cron: Invalid argument passed for optionsIn. Should be one of function, or object (options).");if(Br(B))$=B;else if(typeof B=="object")w=B;else if(B!==void 0)throw Error("Cron: Invalid argument passed for funcIn. Should be one of function, or object (options).");if(this.name=w?.name,this.options=URQ(w),this._states={kill:!1,blocking:!1,previousRun:void 0,currentRun:void 0,once:void 0,currentTimeout:void 0,maxRuns:w?w.maxRuns:void 0,paused:w?w.paused:!1,pattern:new Sz1("* * * * *")},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new wY(A,this.options.timezone||this.options.utcOffset):this._states.pattern=new Sz1(A,this.options.timezone),this.name){if(u$A.find((f)=>f.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");u$A.push(this)}return $!==void 0&&YRQ($)&&(this.fn=$,this.schedule()),this}nextRun(A){let Q=this._next(A);return Q?Q.getDate(!1):null}nextRuns(A,Q){this._states.maxRuns!==void 0&&A>this._states.maxRuns&&(A=this._states.maxRuns);let B=[],w=Q||this._states.currentRun||void 0;for(;A--&&(w=this.nextRun(w));)B.push(w);return B}getPattern(){return this._states.pattern?this._states.pattern.pattern:void 0}isRunning(){let A=this.nextRun(this._states.currentRun),Q=!this._states.paused,B=this.fn!==void 0,w=!this._states.kill;return Q&&B&&w&&A!==null}isStopped(){return this._states.kill}isBusy(){return this._states.blocking}currentRun(){return this._states.currentRun?this._states.currentRun.getDate():null}previousRun(){return this._states.previousRun?this._states.previousRun.getDate():null}msToNext(A){let Q=this._next(A);return Q?A instanceof wY||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new wY(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=u$A.indexOf(this);A>=0&&u$A.splice(A,1)}pause(){return this._states.paused=!0,!this._states.kill}resume(){return this._states.paused=!1,!this._states.kill}schedule(A){if(A&&this.fn)throw Error("Cron: It is not allowed to schedule two functions using the same Croner instance.");A&&(this.fn=A);let Q=this.msToNext(),B=this.nextRun(this._states.currentRun);return Q==null||isNaN(Q)||B===null?this:(Q>hz1&&(Q=hz1),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(B),Q),this._states.currentTimeout&&this.options.unref&&JRQ(this._states.currentTimeout),this)}async _trigger(A){if(this._states.blocking=!0,this._states.currentRun=new wY(void 0,this.options.timezone||this.options.utcOffset),this.options.catch)try{this.fn!==void 0&&await this.fn(this,this.options.context)}catch(Q){Br(this.options.catch)&&this.options.catch(Q,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new wY(A,this.options.timezone||this.options.utcOffset),this._states.blocking=!1}async trigger(){await this._trigger()}runsLeft(){return this._states.maxRuns}_checkTrigger(A){let Q=new Date,B=!this._states.paused&&Q.getTime()>=A.getTime(),w=this._states.blocking&&this.options.protect;B&&!w?(this._states.maxRuns!==void 0&&this._states.maxRuns--,this._trigger()):B&&w&&Br(this.options.protect)&&setTimeout(()=>this.options.protect(this),0),this.schedule()}_next(A){let Q=!!(A||this._states.currentRun),B=!1;!A&&this.options.startAt&&this.options.interval&&([A,Q]=this._calculatePreviousRun(A,Q),B=!A),A=new wY(A,this.options.timezone||this.options.utcOffset),this.options.startAt&&A&&A.getTime()<this.options.startAt.getTime()&&(A=this.options.startAt);let w=this._states.once||new wY(A,this.options.timezone||this.options.utcOffset);return!B&&w!==this._states.once&&(w=w.increment(this._states.pattern,this.options,Q)),this._states.once&&this._states.once.getTime()<=A.getTime()||w===null||this._states.maxRuns!==void 0&&this._states.maxRuns<=0||this._states.kill||this.options.stopAt&&w.getTime()>=this.options.stopAt.getTime()?null:w}_calculatePreviousRun(A,Q){let B=new wY(void 0,this.options.timezone||this.options.utcOffset),w=A;if(this.options.startAt.getTime()<=B.getTime()){w=this.options.startAt;let $=w.getTime()+this.options.interval*1000;for(;$<=B.getTime();)w=new wY(w,this.options.timezone||this.options.utcOffset).increment(this._states.pattern,this.options,!0),$=w.getTime()+this.options.interval*1000;Q=!0}return w===null&&(w=void 0),[w,Q]}};class c$A{scheduleCron(A,Q){let B=new thA(A,()=>{Q()});return{stop:()=>B.stop()}}scheduleInterval(A,Q){let B=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(B)}}validateCron(A){new thA(A).stop()}}WA();var uz1=H.union([H.string().min(1),H.object({location:H.enum(["metadata","frontmatter"]),field:H.string().min(1)})]),l$A=H.object({entityType:H.string().min(1),attachmentType:H.string().min(1),mediaEntityType:H.enum(["image","document"]),targetEntityField:uz1.optional(),requiredWhen:H.object({status:H.string().min(1).optional(),visibility:H.string().min(1).optional()}).optional(),autoGenerate:H.boolean().optional(),requiredForPublish:H.boolean().optional(),jobType:H.string().min(1).optional()});function ehA(A){return`${A.entityType}:${A.attachmentType}`}class lH{static instance=null;definitions=new Map;static getInstance(){return lH.instance??=new lH,lH.instance}static resetInstance(){lH.instance=null}static createFresh(){return new lH}constructor(){}register(A){let Q=l$A.parse(A),B=ehA(Q);return this.definitions.set(B,Q),()=>this.unregister(Q.entityType,Q.attachmentType)}get(A,Q){return this.definitions.get(ehA({entityType:A,attachmentType:Q}))}list(A){let Q=Array.from(this.definitions.values());return A?Q.filter((B)=>B.entityType===A):Q}has(A,Q){return this.get(A,Q)!==void 0}unregister(A,Q){this.definitions.delete(ehA({entityType:A,attachmentType:Q}))}clear(){this.definitions.clear()}}WA();class p$A{deps;constructor(A){this.deps=A}async ensureForEntity(A,Q={}){let B=this.deps.registry.list(A.entityType).filter(($)=>$.autoGenerate===!0).filter(($)=>!Q.attachmentType||$.attachmentType===Q.attachmentType),w={checked:B.length,enqueued:0,skipped:0};for(let $ of B)if(await this.ensureDefinition(A,$))w.enqueued+=1;else w.skipped+=1;return w}async ensureDefinition(A,Q){if(!this.matchesPolicy(A,Q))return!1;if(this.hasTargetField(A,Q.targetEntityField))return!1;if(!this.deps.context.attachments.hasProvider(A.entityType,Q.attachmentType))return!1;let B=this.resolveJobType(Q);if(!B)return!1;let w=this.getPredictedMediaId(A,Q),$=this.getDeduplicationKey(A,Q);return await this.deps.context.jobs.enqueue({type:B,data:{sourceEntityType:A.entityType,sourceEntityId:A.id,attachmentType:Q.attachmentType,imageId:w,dedupKey:$,targetEntityType:A.entityType,targetEntityId:A.id,...this.getTargetImageFieldData(Q.targetEntityField)},options:{source:"content-pipeline",metadata:{operationType:"content_operations"},deduplication:"skip",deduplicationKey:$}}),this.deps.context.logger.debug("Queued publish asset generation",{entityType:A.entityType,entityId:A.id,attachmentType:Q.attachmentType,jobType:B}),!0}matchesPolicy(A,Q){let{requiredWhen:B}=Q;if(!B)return!0;if(B.status&&A.metadata.status!==B.status)return!1;if(B.visibility&&A.visibility!==B.visibility)return!1;return!0}hasTargetField(A,Q){if(!Q)return!1;if(typeof Q==="string")return AmA(A.metadata[Q]);if(Q.location==="metadata")return AmA(A.metadata[Q.field]);let{frontmatter:B}=jB(A.content);return AmA(B[Q.field])}resolveJobType(A){if(A.jobType)return A.jobType;if(A.mediaEntityType==="image")return"image:image-render-source";return}getPredictedMediaId(A,Q){let B=Q.attachmentType==="og-image"?"og":Q.attachmentType;return X1(`${B}-${A.entityType}-${A.id}`)}getDeduplicationKey(A,Q){return`publish-asset:${Q.attachmentType}:${A.entityType}:${A.id}`}getTargetImageFieldData(A){let Q=typeof A==="string"?A:A?.field;if(Q==="coverImageId"||Q==="ogImageId")return{targetImageField:Q};return{}}}function AmA(A){return typeof A==="string"?A.length>0:A!==void 0}aA();WA();var XRQ=H.object({id:H.string().min(1)});async function lz1(A,Q){let{bodyContent:B,coverImageId:w,documents:$,sourceEntityType:f,sourceEntityId:I}=WRQ(Q.content),D=w?await KRQ(A,w):void 0,U;if($&&$.length>0){let J=await FRQ(A,$);if(J.length>0)U=J}U??=await GRQ(A,f,I);let Y={bodyContent:B};if(D)Y.imageData=D;if(U&&U.length>0)Y.documentData=U;return Y}function WRQ(A){try{let Q=b2(A,H.record(H.unknown())),B=Q.metadata.coverImageId,w=typeof B==="string"?B:void 0,$=HRQ(Q.metadata.documents),f=cz1(Q.metadata.sourceEntityType),I=cz1(Q.metadata.sourceEntityId);return{bodyContent:Q.content,...w&&{coverImageId:w},...$.length>0&&{documents:$},...f&&{sourceEntityType:f},...I&&{sourceEntityId:I}}}catch{return{bodyContent:A}}}function HRQ(A){if(!Array.isArray(A))return[];return A.flatMap((Q)=>{let B=XRQ.safeParse(Q);return B.success?[B.data]:[]})}function cz1(A){return typeof A==="string"&&A.length>0?A:void 0}async function GRQ(A,Q,B){if(!Q||!B)return;let w=await A.attachments.resolve({sourceEntityType:Q,sourceEntityId:B,attachmentType:"carousel"});return w?[w]:void 0}async function KRQ(A,Q){let B=await A.entityService.getEntity({entityType:"image",id:Q});if(!B?.content)return;let w=pz1(B.content);if(!w?.mimeType.startsWith("image/"))return;return{data:w.data,mimeType:w.mimeType}}async function FRQ(A,Q){return(await Promise.all(Q.map((w)=>ZRQ(A,w)))).filter((w)=>w!==void 0)}async function ZRQ(A,Q){let B=await A.entityService.getEntity({entityType:"document",id:Q.id});if(!B?.content)return;let w=pz1(B.content);if(w?.mimeType!=="application/pdf")return;return{type:"document",data:w.data,mimeType:"application/pdf",filename:NRQ(B,Q.id)}}function pz1(A){let Q=A.match(/^data:([^;]+);base64,(.+)$/);if(!Q?.[1]||!Q[2])return;return{mimeType:Q[1],data:Buffer.from(Q[2],"base64")}}function NRQ(A,Q){let B=A.metadata.filename;return typeof B==="string"&&B.length>0?B:`${Q}.pdf`}WA();var zRQ=/^---\r?\n[\s\S]*?\r?\n---(?:\r?\n|$)/;async function QmA(A,Q,B,w={}){let $=w.publishedAt??new Date().toISOString(),f=w.publishTimestampField??"publishedAt",I={...Q.metadata,status:"published",[f]:$,platformId:B.id,...qRQ(B.id,w.publishResultIdField)},D={...Q,content:iz1(Q.content,$,B.id,w.publishResultIdField,f),metadata:I};return await A.entityService.updateEntity({entity:D}),D}function iz1(A,Q,B,w,$="publishedAt"){if(!zRQ.test(A))return A;let f=X4(X4(A,"status","published"),$,Q);if(!B||!w)return f;return X4(f,w,B)}function qRQ(A,Q){if(!Q||Q==="platformId")return{};return{[Q]:A}}class iv{deps;constructor(A){this.deps=A}async resolveCandidate(A){let{entityType:Q,id:B,slug:w}=A;if(!B&&!w)return{error:"Either 'id' or 'slug' must be provided"};let $=await this.findPublishableEntity(Q,B,w);if(!$)return{error:`Entity not found: ${Q}:${B??w}`};if($.visibility!=="public")return{error:`Cannot publish ${Q}:${$.id} to a public provider because visibility is ${$.visibility}`};if($.metadata.status==="published")return{error:"Entity is already published"};if(!this.deps.providerRegistry.has(Q))return{error:`No publish provider registered for ${Q}. Check that the required credentials are configured.`};return{entity:$}}async publish(A){let Q=await this.resolveCandidate(A);if("error"in Q)return Q;let{entity:B}=Q,{entityType:w}=A,$=this.deps.providerRegistry.get(w),{bodyContent:f,imageData:I,documentData:D}=await lz1(this.deps.context,B),U=await $.publish(f,B.metadata,I,D),Y=this.deps.providerRegistry.getPublishResultIdField(w),J=this.deps.providerRegistry.getPublishTimestampField(w),X=await QmA(this.deps.context,B,U,{...Y?{publishResultIdField:Y}:{},...J?{publishTimestampField:J}:{}});return await this.runPublishAssetPreflight(X),{entity:X,result:U}}async runPublishAssetPreflight(A){if(!this.deps.publishAssetPreflight)return;try{await this.deps.publishAssetPreflight.ensureForEntity(A)}catch(Q){this.deps.context.logger.warn("Publish asset preflight failed",{entityType:A.entityType,entityId:A.id,error:Q instanceof Error?Q.message:String(Q)})}}async findPublishableEntity(A,Q,B){if(Q)return this.deps.context.entityService.getEntity({entityType:A,id:Q});if(!B)return null;return(await this.deps.context.entityService.listEntities({entityType:A,options:{filter:{metadata:{slug:B}},limit:1}}))[0]??null}}aA();WA();var BmA=H.object({action:H.enum(["list","add","remove","reorder"]).describe("Queue action to perform"),entityType:H.string().optional().describe("Entity type (required for add/remove/reorder, optional for list)"),entityId:H.string().optional().describe("Entity ID (required for add/remove/reorder)"),position:H.number().optional().describe("New position for reorder action (1-based)")}),wmA=H.object({position:H.number(),entityType:H.string(),entityId:H.string(),queuedAt:H.string()}),LRQ=H.object({success:H.literal(!0),message:H.string().optional(),data:H.object({queue:H.array(wmA).optional(),entityType:H.string().optional(),entityId:H.string().optional(),position:H.number().optional()}).optional()}),VRQ=H.object({success:H.literal(!1),error:H.string(),code:H.string().optional()}),$mA=H.union([LRQ,VRQ]);function i$A(A,Q,B){return{...oQ(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",BmA,async($,f)=>{let{action:I,entityType:D,entityId:U,position:Y}=$;switch(I){case"list":return ERQ(B,D);case"add":return MRQ(A,B,D,U,f);case"remove":return CRQ(A,B,D,U,f);case"reorder":return ORQ(A,B,D,U,Y,f);default:return{success:!1,error:`Unknown action: ${I}`}}}),outputSchema:$mA}}async function ERQ(A,Q){let B=[];if(Q)B=await A.list(Q);else{let $=A.getRegisteredTypes();for(let f of $){let I=await A.list(f);B.push(...I)}B.sort((f,I)=>new Date(f.queuedAt).getTime()-new Date(I.queuedAt).getTime())}if(B.length===0)return{success:!0,data:{queue:[]},message:"No items in queue"};return{success:!0,data:{queue:B.map(($,f)=>({position:f+1,entityType:$.entityType,entityId:$.entityId,queuedAt:$.queuedAt}))},message:`${B.length} items in queue`}}async function MRQ(A,Q,B,w,$){let f=fmA("add",B,w);if(!f.success)return f.error;A.permissions.assertEntityActionAllowed(f.entityType,"publish",$??{});let I=await Q.add(f.entityType,f.entityId,{...$,authorization:"user"});return{success:!0,data:{entityType:f.entityType,entityId:f.entityId,position:I.position},message:`Added to queue at position ${I.position}`}}async function CRQ(A,Q,B,w,$){let f=fmA("remove",B,w);if(!f.success)return f.error;return A.permissions.assertEntityActionAllowed(f.entityType,"update",$??{}),await Q.remove(f.entityType,f.entityId),{success:!0,data:{entityType:f.entityType,entityId:f.entityId},message:"Removed from queue"}}async function ORQ(A,Q,B,w,$,f){let I=fmA("reorder",B,w);if(!I.success)return I.error;let D=RRQ($);if(!D.success)return D.error;return A.permissions.assertEntityActionAllowed(I.entityType,"update",f??{}),await Q.reorder(I.entityType,I.entityId,D.position),{success:!0,data:{entityType:I.entityType,entityId:I.entityId,position:D.position},message:`Moved to position ${D.position}`}}function fmA(A,Q,B){if(!Q)return{success:!1,error:{success:!1,error:`entityType is required for ${A} action`}};if(!B)return{success:!1,error:{success:!1,error:`entityId is required for ${A} action`}};return{success:!0,entityType:Q,entityId:B}}function RRQ(A){if(A===void 0)return{success:!1,error:{success:!1,error:"position is required for reorder action"}};if(A<1)return{success:!1,error:{success:!1,error:"position must be a positive number"}};return{success:!0,position:A}}WA();var r$A=H.object({entityType:H.string().describe("Entity type to publish (e.g., social-post, post, deck)"),id:H.string().optional().describe("Entity ID to publish"),slug:H.string().optional().describe("Entity slug to publish"),confirmed:H.boolean().optional(),confirmationToken:H.string().optional(),contentHash:H.string().optional()}),bRQ=H.object({success:H.literal(!0),message:H.string().optional(),data:H.object({entityType:H.string().optional(),entityId:H.string().optional(),platformId:H.string().optional(),url:H.string().optional()}).optional()}),PRQ=H.object({success:H.literal(!1),error:H.string(),code:H.string().optional()}),kRQ=H.object({success:H.literal(!1).optional(),error:H.string().optional(),needsConfirmation:H.literal(!0),toolName:H.string(),summary:H.string(),preview:H.string().optional(),args:H.unknown()}),ImA=H.union([bRQ,PRQ,kRQ]),jRQ=900000,_RQ=1000;class dz1{tokens=new Map;add(A){if(this.prune(),this.tokens.size>=_RQ){let Q=this.tokens.keys().next().value;if(Q!==void 0)this.tokens.delete(Q)}this.tokens.set(A,Date.now()+jRQ)}has(A){let Q=this.tokens.get(A);if(Q===void 0)return!1;if(Q<=Date.now())return this.tokens.delete(A),!1;return!0}delete(A){this.tokens.delete(A)}prune(){let A=Date.now();for(let[Q,B]of this.tokens)if(B<=A)this.tokens.delete(Q)}}function d$A(A,Q,B,w){let $=w??new iv({context:A,providerRegistry:B}),f=new dz1,I=`${Q}_publish`;return{name:I,description:"Publish an entity directly to its platform. Call this when the user asks to publish; the tool will request confirmation itself. Works with any registered entity type (social-post, post, deck, etc.)",inputSchema:r$A.shape,outputSchema:ImA,visibility:"anchor",handler:async(D,U)=>{let Y=r$A.safeParse(D);if(!Y.success)return{success:!1,error:`Invalid input: ${Y.error.errors.map((L)=>`${L.path.join(".")}: ${L.message}`).join(", ")}`};let J=Y.data,{entityType:X,id:G,slug:Z}=J;try{A.permissions.assertEntityActionAllowed(X,"publish",U)}catch(L){return{success:!1,error:L instanceof Error?L.message:String(L)}}let N=await $.resolveCandidate({entityType:X,id:G,slug:Z});if("error"in N)return{success:!1,error:N.error};let{entity:V}=N;if(J.confirmed){let L=J.confirmationToken;if(!L||!f.has(L))return rz1(I,J,V,f);if(f.delete(L),J.contentHash&&J.contentHash!==V.contentHash)return{success:!1,error:`Cannot publish ${X}:${V.id} because it changed after confirmation. Review it and try again.`};let M;try{M=await $.publish({entityType:X,id:V.id})}catch(S){return{success:!1,error:S instanceof Error?S.message:String(S)}}if("error"in M)return{success:!1,error:M.error};let{entity:O,result:E}=M;return{success:!0,data:{entityType:X,entityId:O.id,platformId:E.id,url:E.url},message:`Published ${X}:${O.id}`}}return rz1(I,J,V,f)}}}function rz1(A,Q,B,w){let $=crypto.randomUUID();w.add($);let f=vRQ(B);return{needsConfirmation:!0,toolName:A,summary:`Publish "${f}"?`,preview:`This will publish ${B.entityType}:${B.id} to its registered public publish provider.`,args:{...Q,id:B.id,slug:void 0,confirmed:!0,confirmationToken:$,contentHash:B.contentHash}}}function vRQ(A){let Q=A.metadata.title;if(typeof Q==="string"&&Q.length>0)return Q;let B=A.metadata.subject;if(typeof B==="string"&&B.length>0)return B;let w=A.metadata.slug;if(typeof w==="string"&&w.length>0)return w;return A.id}aA();WA();var DmA=H.object({entityType:H.string().min(1).describe("Entity type to reconcile"),status:H.string().min(1).optional().describe("Optional metadata status filter, e.g. published"),assetType:H.string().min(1).optional().describe("Optional attachment type filter, e.g. og-image")}),UmA=H.object({success:H.literal(!0),data:H.object({entityType:H.string(),assetType:H.string().optional(),checkedEntities:H.number(),checkedAssets:H.number(),enqueued:H.number(),skipped:H.number()}),message:H.string().optional()});function n$A(A,Q,B,w){return{...oQ(Q,"ensure-assets","Reconcile configured publish assets for existing entities, queueing missing generated assets such as OG images.",DmA,async(f,I)=>{if(A.permissions.assertEntityActionAllowed(f.entityType,"publish",I),B.list(f.entityType).filter((G)=>G.autoGenerate===!0).filter((G)=>!f.assetType||G.attachmentType===f.assetType).length===0)return{success:!0,data:{entityType:f.entityType,...f.assetType&&{assetType:f.assetType},checkedEntities:0,checkedAssets:0,enqueued:0,skipped:0},message:`No publish assets configured for ${f.entityType}`};let U=await A.entityService.listEntities({entityType:f.entityType,options:{...f.status&&{filter:{metadata:{status:f.status}}}}}),Y=0,J=0,X=0;for(let G of U){let Z=await w.ensureForEntity(G,{...f.assetType&&{attachmentType:f.assetType}});Y+=Z.checked,J+=Z.enqueued,X+=Z.skipped}return{success:!0,data:{entityType:f.entityType,...f.assetType&&{assetType:f.assetType},checkedEntities:U.length,checkedAssets:Y,enqueued:J,skipped:X},message:`Queued ${J} publish asset job(s)`}}),outputSchema:UmA}}aA();WA();function nz1(A,Q){yRQ(A,Q),TRQ(A,Q),xRQ(A,Q),SRQ(A,Q)}function yRQ(A,Q){A.messaging.subscribe(l4.REGISTER,async(B)=>gRQ(Q,B.payload)),A.messaging.subscribe(l4.QUEUE,async(B)=>cRQ(A,Q,B.payload)),A.messaging.subscribe(l4.DIRECT,async(B)=>lRQ(A,Q,B.payload)),A.messaging.subscribe(l4.REMOVE,async(B)=>pRQ(Q,B.payload)),A.messaging.subscribe(l4.REORDER,async(B)=>iRQ(Q,B.payload)),A.messaging.subscribe(l4.LIST,async(B)=>rRQ(A,Q,B.payload)),A.messaging.subscribe(l4.REPORT_SUCCESS,async(B)=>dRQ(Q,B.payload)),A.messaging.subscribe(l4.REPORT_FAILURE,async(B)=>nRQ(Q,B.payload)),Q.logger.debug("Subscribed to publish messages")}function TRQ(A,Q){A.messaging.subscribe(wq.REPORT_SUCCESS,async(B)=>oRQ(Q,B.payload)),A.messaging.subscribe(wq.REPORT_FAILURE,async(B)=>sRQ(Q,B.payload)),Q.logger.debug("Subscribed to generation messages")}function xRQ(A,Q){A.messaging.subscribe(Pz1.REGISTER,async(B)=>hRQ(Q,B.payload)),Q.logger.debug("Subscribed to publish asset messages")}function SRQ(A,Q){let B=async(w)=>mRQ(A,Q,w.payload);A.messaging.subscribe("entity:created",B),A.messaging.subscribe("entity:updated",B),Q.logger.debug("Subscribed to entity change messages for publish assets")}async function gRQ(A,Q){let{entityType:B,provider:w,config:$}=Q;try{let f=$?kz1.safeParse($):void 0;if(f&&!f.success)return A.logger.warn("Invalid publish provider config",{entityType:B,error:f.error.message}),{success:!1};if(w)A.providerRegistry.register(B,w,f?.data),A.logger.info(`Registered provider for entity type: ${B}`,{providerName:w.name,executionMode:A.providerRegistry.getExecutionMode(B)});return{success:!0}}catch(f){let I=y0(f);return A.logger.error(`Failed to register provider: ${I}`),{success:!1}}}async function hRQ(A,Q){let B=l$A.safeParse(Q);if(!B.success)return A.logger.warn("Invalid publish asset registration",{error:B.error.message}),{success:!1};return A.publishAssetRegistry.register(B.data),A.logger.info("Registered publish asset",{entityType:B.data.entityType,attachmentType:B.data.attachmentType,mediaEntityType:B.data.mediaEntityType}),{success:!0}}async function mRQ(A,Q,B){try{if(Q.publishAssetRegistry.list(B.entityType).length===0)return{success:!0};let w=B.entity??await A.entityService.getEntity({entityType:B.entityType,id:B.entityId});if(!uRQ(w))return{success:!0};return await Q.publishAssetPreflight.ensureForEntity(w),{success:!0}}catch(w){return Q.logger.warn("Failed to run publish asset preflight for entity event",{entityType:B.entityType,entityId:B.entityId,error:y0(w)}),{success:!1}}}function uRQ(A){if(!A)return!1;let Q=bz1.safeParse(A.metadata);return Q.success&&Q.data.status==="published"}async function cRQ(A,Q,B){let{entityType:w,entityId:$}=B;try{let f=B.authContext??Qr;A.permissions.assertEntityActionAllowed(w,"publish",f);let I=await Q.queueManager.add(w,$,f);return await A.messaging.send({type:l4.QUEUED,payload:{entityType:w,entityId:$,position:I.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:w,position:I.position}),{success:!0}}catch(f){let I=y0(f);return Q.logger.error(`Failed to queue entity: ${I}`),{success:!1}}}async function lRQ(A,Q,B){let{entityType:w,entityId:$}=B,f=B.authContext??Qr;try{if(A.permissions.assertEntityActionAllowed(w,"publish",f),!Q.providerRegistry.has(w))return Q.scheduler.failPublish(w,$,`No publish provider registered for ${w}`),{success:!1};let I=await Q.publishExecutor.publish({entityType:w,id:$});if("error"in I)return Q.scheduler.failPublish(w,$,I.error),{success:!1};return Q.scheduler.completePublish(w,$,I.result),Q.logger.debug(`Direct publish completed: ${$}`,{entityType:w}),{success:!0}}catch(I){let D=y0(I);return Q.logger.error(`Failed direct publish request: ${D}`),{success:!1}}}async function pRQ(A,Q){let{entityType:B,entityId:w}=Q;try{return await A.queueManager.remove(B,w),A.logger.debug(`Entity removed from queue: ${w}`,{entityType:B}),{success:!0}}catch($){let f=y0($);return A.logger.error(`Failed to remove entity: ${f}`),{success:!1}}}async function iRQ(A,Q){let{entityType:B,entityId:w,position:$}=Q;try{return await A.queueManager.reorder(B,w,$),A.logger.debug(`Entity reordered: ${w}`,{entityType:B,newPosition:$}),{success:!0}}catch(f){let I=y0(f);return A.logger.error(`Failed to reorder entity: ${I}`),{success:!1}}}async function rRQ(A,Q,B){let{entityType:w}=B;try{let $=await Q.queueManager.list(w);return await A.messaging.send({type:l4.LIST_RESPONSE,payload:{entityType:w,queue:$.map((f)=>({entityId:f.entityId,position:f.position,queuedAt:f.queuedAt}))}}),{success:!0}}catch($){let f=y0($);return Q.logger.error(`Failed to list queue: ${f}`),{success:!1}}}async function dRQ(A,Q){let{entityType:B,entityId:w,result:$}=Q;return A.scheduler.completePublish(B,w,$),A.logger.info(`Publish reported success: ${w}`,{entityType:B}),{success:!0}}async function nRQ(A,Q){let{entityType:B,entityId:w,error:$}=Q;A.scheduler.failPublish(B,w,$);let f=A.retryTracker.getRetryInfo(w);return A.logger.info(`Publish reported failure: ${w}`,{entityType:B,error:$,retryCount:f?.retryCount}),{success:!0}}async function oRQ(A,Q){let{entityType:B,entityId:w}=Q;return A.scheduler.completeGeneration(B,w),A.logger.info("Generation completed",{entityType:B,entityId:w}),{success:!0}}async function sRQ(A,Q){let{entityType:B,error:w}=Q;return A.scheduler.failGeneration(B,w),A.logger.warn("Generation failed",{entityType:B,error:w}),{success:!0}}WA();async function oz1(A,Q,B,w){try{if(w.skipIfDraftExists!==!1){if((await A.listEntities({entityType:B,options:{filter:{metadata:{status:"draft"}},limit:1}})).length>0)return{shouldGenerate:!1,reason:"Draft already exists"}}if(w.maxUnpublishedDrafts!==void 0){let $=await A.listEntities({entityType:B,options:{filter:{metadata:{status:"draft"}},limit:w.maxUnpublishedDrafts+1}});if($.length>=w.maxUnpublishedDrafts)return{shouldGenerate:!1,reason:`Max unpublished drafts reached (${$.length}/${w.maxUnpublishedDrafts})`}}if(w.minSourceEntities!==void 0&&w.sourceEntityType){let $=await A.listEntities({entityType:w.sourceEntityType,options:{publishedOnly:!0,limit:w.minSourceEntities}});if($.length<w.minSourceEntities)return{shouldGenerate:!1,reason:`Not enough source entities (${$.length}/${w.minSourceEntities} ${w.sourceEntityType})`}}return{shouldGenerate:!0}}catch($){return Q.error("Failed to check generation conditions",{entityType:B,error:y0($)}),{shouldGenerate:!1,reason:`Condition check failed: ${y0($)}`}}}function sz1(A){let{context:Q,config:B,queueManager:w,providerRegistry:$,retryTracker:f,publishExecutor:I,logger:D}=A,U=aRQ(Q);return FX.createFresh({queueManager:w,providerRegistry:$,retryTracker:f,logger:D,backend:new c$A,...B.entitySchedules&&{entitySchedules:B.entitySchedules},...B.generationSchedules&&{generationSchedules:B.generationSchedules},...B.generationConditions&&{generationConditions:B.generationConditions},messageBus:U,publishExecutor:I,onCheckGenerationConditions:(Y,J)=>oz1(Q.entityService,D,Y,J)})}function aRQ(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 az1(A,Q,B){let w=A.getEntityTypes();for(let f of w){let I=await A.listEntities({entityType:f,options:{filter:{metadata:{status:"queued"}}}});for(let D of I)await Q.add(D.entityType,D.id)}let $=0;for(let f of w){let I=await Q.list(f);$+=I.length}if($>0)B.info(`Rebuilt queue with ${$} queued entities`)}var tRQ=["draft","queued","published","failed"];async function tz1(A,Q){await A.messaging.send({type:"dashboard:register-widget",payload:{id:"publication-pipeline",pluginId:Q,title:"Publication Pipeline",section:"secondary",priority:100,rendererName:"PipelineWidget",visibility:"anchor",dataProvider:()=>eRQ(A)}})}async function eRQ(A){let Q=A.entityService.getEntityTypes(),B=[],w={draft:0,queued:0,published:0,failed:0};for(let $ of Q){let f=await A.entityService.listEntities({entityType:$});for(let I of f){let D=AbQ(I.metadata.status);if(!D)continue;w[D]++,B.push({id:I.id,title:QbQ(I.id,I.metadata.title),type:$,status:D})}}return{summary:w,items:B}}function AbQ(A){return tRQ.find((Q)=>Q===A)}function QbQ(A,Q){return typeof Q==="string"?Q:A}var ez1={name:"@brains/content-pipeline",private:!0,version:"0.2.0-alpha.125",description:"Content pipeline plugin for managing entity publishing queues, scheduling, and generation",type:"module",main:"src/index.ts",types:"src/index.ts",scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",croner:"^9.1.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",typescript:"^5.3.3"},exports:{".":{types:"./src/index.ts",default:"./src/index.ts"}},files:["src"]};class YmA extends YB{pluginContext;queueManager;providerRegistry;retryTracker;publishExecutor;publishAssetRegistry;publishAssetPreflight;scheduler;constructor(A){super("content-pipeline",ez1,A??{},jz1)}async onRegister(A){this.pluginContext=A,this.queueManager=mH.createFresh(),this.providerRegistry=uH.createFresh(),this.retryTracker=cH.createFresh(),this.publishAssetRegistry=lH.createFresh(),this.publishAssetPreflight=new p$A({context:A,registry:this.publishAssetRegistry}),this.publishExecutor=new iv({context:A,providerRegistry:this.providerRegistry,publishAssetPreflight:this.publishAssetPreflight}),this.scheduler=sz1({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,publishExecutor:this.publishExecutor,logger:this.logger}),nz1(A,{queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,publishExecutor:this.publishExecutor,publishAssetRegistry:this.publishAssetRegistry,publishAssetPreflight:this.publishAssetPreflight,scheduler:this.scheduler,logger:this.logger})}async onReady(A){await az1(A.entityService,this.queueManager,this.logger),await tz1(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[i$A(this.pluginContext,this.id,this.queueManager),d$A(this.pluginContext,this.id,this.providerRegistry,this.publishExecutor),n$A(this.pluginContext,this.id,this.publishAssetRegistry,this.publishAssetPreflight)]}async getInstructions(){return'## Publishing\n- Use `content-pipeline_queue` to manage the publish queue \u2014 list queued items, add entities to the queue, remove them, or reorder.\n- Use `content-pipeline_publish` to publish an entity directly to its platform (e.g. LinkedIn, Buttondown). This tool has its own confirmation flow; call it without `confirmed` when the user asks to publish instead of asking for plain-text confirmation.\n- Use `content-pipeline_ensure-assets` to reconcile missing publish assets such as generated OG images for already-published content.\n- When users ask about their "publish queue", "publishing queue", or "what\'s queued", use `content-pipeline_queue`.'}getQueueManager(){return this.queueManager}getProviderRegistry(){return this.providerRegistry}getRetryTracker(){return this.retryTracker}getPublishAssetRegistry(){return this.publishAssetRegistry}getScheduler(){return this.scheduler}async onShutdown(){await this.scheduler.stop(),mH.resetInstance(),uH.resetInstance(),cH.resetInstance(),lH.resetInstance()}}function JmA(A){return new YmA(A)}aA();WA();var Aq1=H.object({accountId:H.string().describe("Cloudflare account ID"),apiToken:H.string().describe("Cloudflare API token with Analytics:Read permission"),siteTag:H.string().describe("Cloudflare Web Analytics site tag")}),XmA=H.object({cloudflare:Aq1.optional()});aA();WA();var wbQ=H.object({date:H.string().describe("Single date in YYYY-MM-DD format").optional(),days:H.number().min(1).max(365).describe("Number of days back from yesterday (e.g., 7 for last week)").optional(),startDate:H.string().describe("Start date in YYYY-MM-DD format (use with endDate)").optional(),endDate:H.string().describe("End date in YYYY-MM-DD format (use with startDate)").optional(),limit:H.number().min(1).max(100).default(20).describe("Maximum items for breakdowns (pages, referrers, countries)")});function $bQ(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 Qq1(A,Q,B){let w=[];if(!B)return w;return w.push(oQ(A,"query",`Query website analytics from Cloudflare.
|
|
6530
|
+
${B.content}`:B.prompt??"Write an engaging LinkedIn post";return A.ai.generate({prompt:w,templateName:`social-media:${B.platform}`})}),A.eval.registerHandler("create",async(Q)=>{let B=tOQ.parse(Q),w=[],$=R9.from(async(Y)=>{let J={progress:Y.progress};if(Y.message!==void 0)J.message=Y.message;w.push(J)});if(!$)throw Error("Failed to create progress reporter");let I=await new MC(A.logger,A).process(B,`eval-${Date.now()}`,$),D=!1,U;if(I.success&&I.entityId){let Y=await A.entityService.getEntity({entityType:"social-post",id:I.entityId});D=!!Y,U=Y?.content.slice(0,300)}return{...I,entityExists:D,entityPreview:U,progressSteps:w}})}WA();aA();class ei{sendMessage;logger;entityService;providers;permissions;resolveAttachment;constructor(A){this.sendMessage=A.sendMessage,this.logger=A.logger,this.entityService=A.entityService,this.providers=A.providers,this.permissions=A.permissions,this.resolveAttachment=A.resolveAttachment}async handle(A){let{entityType:Q,entityId:B}=A;if(Q!=="social-post")return;this.permissions.assertEntityActionAllowed(Q,"publish",A.authContext??{userPermissionLevel:"anchor"}),this.logger.debug("Handling publish:execute",{entityId:B});try{let w=await this.entityService.getEntity({entityType:"social-post",id:B});if(!w){await this.reportFailure(Q,B,`Post not found: ${B}`);return}let $=w;if($.metadata.status==="published"){this.logger.debug("Post already published, skipping",{entityId:B});return}let f=$.metadata.platform,I=this.providers.get(f);if(!I){await this.reportFailure(Q,B,`No provider configured for platform: ${f}`);return}let D=b2($.content,BY),U;if(D.metadata.coverImageId)U=await this.fetchImageData(D.metadata.coverImageId);let Y=D.metadata.documents??[],J=await this.fetchDocumentData(Y);try{if(Y.length>0&&J.length===0)throw Error(`Refusing to publish: ${Y.length} document(s) referenced but none could be fetched`);let X=Y.length===0?await this.resolveSourceAttachment(D.metadata):[],G=J.length>0?J:X,Z=G.length?await I.publish(D.content,$.metadata,U,G):await I.publish(D.content,$.metadata,U),N=new Date().toISOString(),V=Z.id||void 0,L={...D.metadata,status:"published",publishedAt:N,...V&&{platformPostId:V}},M=t9.createPostContent(L,D.content);await this.entityService.updateEntity({entity:{...$,content:M,metadata:{...$.metadata,status:"published",publishedAt:N,platformPostId:V}}}),await this.reportSuccess(Q,B,Z.id),this.logger.info(`Post published successfully: ${B}`,{platform:f,platformPostId:V})}catch(X){let G=X instanceof Error?X.message:String(X),Z={...D.metadata,status:"failed"},N=t9.createPostContent(Z,D.content);await this.entityService.updateEntity({entity:{...$,content:N,metadata:{...$.metadata,status:"failed"}}}),await this.reportFailure(Q,B,G),this.logger.error(`Post publish failed: ${B}`,{platform:f,error:G})}}catch(w){let $=y0(w);this.logger.error("Unexpected error in publish handler",{entityId:B,error:$}),await this.reportFailure(Q,B,$)}}async reportSuccess(A,Q,B){await this.sendMessage({type:"publish:report:success",payload:{entityType:A,entityId:Q,result:{id:B}}})}async reportFailure(A,Q,B){await this.sendMessage({type:"publish:report:failure",payload:{entityType:A,entityId:Q,error:B}})}async resolveSourceAttachment(A){if(!this.resolveAttachment||!A.sourceEntityType||!A.sourceEntityId)return[];let Q=await this.resolveAttachment({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:"carousel"});return Q?[Q]:[]}async fetchDocumentData(A){if(!A?.length)return[];let Q=[];for(let B of A){let w=await this.fetchSingleDocumentData(B.id);if(w)Q.push(w)}return Q}async fetchSingleDocumentData(A){try{let Q=await this.entityService.getEntity({entityType:"document",id:A});if(!Q){this.logger.warn("Document not found",{documentId:A});return}let B=Q.content.match(/^data:application\/pdf;base64,(.+)$/);if(!B?.[1]){this.logger.warn("Invalid document data URL format",{documentId:A});return}let w=typeof Q.metadata.filename==="string"?Q.metadata.filename:`${A}.pdf`;return{type:"document",data:Buffer.from(B[1],"base64"),mimeType:"application/pdf",filename:w}}catch(Q){this.logger.warn("Failed to fetch document",{documentId:A,error:Q});return}}async fetchImageData(A){try{let Q=await this.entityService.getEntity({entityType:"image",id:A});if(!Q){this.logger.warn("Cover image not found",{imageId:A});return}let w=Q.content.match(/^data:([^;]+);base64,(.+)$/);if(!w?.[1]||!w[2]){this.logger.warn("Invalid image data URL format",{imageId:A});return}let $=w[1],f=w[2];return{data:Buffer.from(f,"base64"),mimeType:$}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function Lz1(A,Q,B){if(Q.size===0){B.debug("No providers configured, skipping publish-pipeline registration");return}A.messaging.subscribe("system:plugins:ready",async()=>{let w=Q.values().next().value;return await A.messaging.send({type:"publish:register",payload:{entityType:"social-post",provider:w,config:{publishResultIdField:"platformPostId"}}}),B.info("Registered social-post with publish-pipeline"),{success:!0}})}function Vz1(A,Q,B){let w=new ei({sendMessage:A.messaging.send,logger:B.child("PublishExecuteHandler"),entityService:A.entityService,providers:Q,permissions:A.permissions,resolveAttachment:A.attachments.resolve});A.messaging.subscribe("publish:execute",async($)=>{return await w.handle($.payload),{success:!0}}),B.debug("Subscribed to publish:execute messages")}WA();function Ez1(A,Q){A.messaging.subscribe("entity:updated",async(B)=>{let{entityType:w,entityId:$,entity:f}=B.payload;if(w!=="post")return{success:!0};if(f.metadata?.status!=="queued")return{success:!0};try{if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:$}},limit:1}})).length>0)return Q.debug(`Social post already exists for ${$}, skipping auto-generate`),{success:!0};return await A.messaging.send({type:"social:auto-generate",payload:{sourceEntityType:w,sourceEntityId:$,platform:"linkedin"}}),Q.info(`Auto-generate social post triggered for queued post ${$}`),{success:!0}}catch(D){let U=y0(D);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:U}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function Mz1(A,Q){A.messaging.subscribe("social:auto-generate",async(B)=>{let{sourceEntityType:w,sourceEntityId:$,platform:f}=B.payload;try{let I=await A.jobs.enqueue({type:`${t9.entityType}:generation`,data:{sourceEntityType:w,sourceEntityId:$,platform:f,addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info(`Social post generation job enqueued for ${w}/${$}`,{jobId:I}),{success:!0,jobId:I}}catch(I){let D=y0(I);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:D}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function Cz1(A,Q){A.messaging.subscribe("generate:execute",async(B)=>{let{entityType:w}=B.payload;if(w!=="social-post")return{success:!0};Q.info("Received generate:execute for social-post");try{let $=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:5}});if($.length===0)return Q.info("No published posts found for social post generation"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"No published posts available for social post generation"}}),{success:!0};let f=null;for(let D of $)if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:D.id}},limit:1}})).length===0){f=D;break}if(!f)return Q.info("All recent posts already have social posts"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"All recent posts already have social posts generated"}}),{success:!0};let I=await A.jobs.enqueue({type:`${t9.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:f.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:I,sourcePostId:f.id}),{success:!0}}catch($){let f=y0($);return Q.error("Failed to handle generate:execute:",{error:f}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:f}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}async function Oz1({entity:A,config:Q}){let B=Bq.parse(A),w=t9.parsePostFrontmatter(B),$=t9.getPostContent(B);return{$type:"ai.rizom.brain.socialPost",title:w.title,platform:w.platform,body:$,format:"text/markdown",status:w.status,...w.publishedAt&&{publishedAt:w.publishedAt},...w.platformPostId&&{platformPostId:w.platformPostId},...w.sourceEntityType&&{sourceLocalEntityType:w.sourceEntityType},...w.sourceEntityId&&{sourceLocalEntityId:w.sourceEntityId},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"social-post",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function phA(){return{entityType:"social-post",collection:"ai.rizom.brain.socialPost",lexicon:Kw["ai.rizom.brain.socialPost"],validate:!1,buildRecord:Oz1}}var Rz1={name:"@brains/social-media",private:!0,version:"0.2.0-alpha.127",description:"Multi-provider social media posting with queue-based publishing",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class ihA extends _Q{entityType=t9.entityType;schema=Bq;adapter=t9;providers=new Map;unregisterAtprotoProjection;constructor(A){super("social-media",Rz1,A,ShA)}createGenerationHandler(A){return new MC(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return zz1()}getDataSources(){return[new x$A(this.logger.child("SocialPostDataSource"))]}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}async onRegister(A){if(this.initializeProviders(),Lz1(A,this.providers,this.logger),Vz1(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)Ez1(A,this.logger),Mz1(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");Cz1(A,this.logger),qz1(A),this.unregisterAtprotoProjection=o6.getInstance().register(phA()),this.logger.info("Social media plugin registered successfully")}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}initializeProviders(){if(this.config.linkedin?.accessToken){let A=lhA(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function Ar(A){return new ihA(A)}WA();var ARQ=H.enum(["draft","queued","published","failed"]),bz1=H.object({status:ARQ.default("draft"),queueOrder:H.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:H.string().datetime().optional()});class rhA{name="internal";async publish(A,Q){return{id:"internal"}}}var Qr={interfaceType:"system",userId:"system",userPermissionLevel:"anchor",authorization:"system"},l4={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"},wq={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"},Pz1={REGISTER:"publish-assets:register"};WA();var QRQ=H.enum(["provider"]),kz1=H.object({executionMode:QRQ.optional(),publishResultIdField:H.string().min(1).optional(),publishTimestampField:H.string().min(1).optional(),enabled:H.boolean().optional()}).strict();var BRQ=H.object({skipIfDraftExists:H.boolean().optional(),minSourceEntities:H.number().optional(),maxUnpublishedDrafts:H.number().optional(),sourceEntityType:H.string().optional()}),jz1=H.object({entitySchedules:H.record(H.string(),H.string()).optional(),generationSchedules:H.record(H.string(),H.string()).optional(),generationConditions:H.record(H.string(),BRQ).optional()});class mH{static instance=null;queues=new Map;static getInstance(){return mH.instance??=new mH,mH.instance}static resetInstance(){mH.instance=null}static createFresh(){return new mH}constructor(){}async add(A,Q,B=Qr){let w=this.getOrCreateQueue(A),$=w.find((D)=>D.entityId===Q);if($)return{position:$.position};let f=w.length+1,I={entityId:Q,entityType:A,position:f,queuedAt:new Date().toISOString(),authContext:{...B}};return w.push(I),{position:f}}async remove(A,Q){let B=this.queues.get(A);if(!B)return;let w=B.findIndex(($)=>$.entityId===Q);if(w===-1)return;B.splice(w,1),this.recalculatePositions(B)}async reorder(A,Q,B){let w=this.queues.get(A);if(!w)return;let $=w.findIndex((D)=>D.entityId===Q);if($===-1)return;let[f]=w.splice($,1);if(!f)return;let I=Math.max(0,Math.min(B-1,w.length));w.splice(I,0,f),this.recalculatePositions(w)}async list(A){let Q=this.queues.get(A);if(!Q)return[];return[...Q]}async getNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;return Q[0]??null}async getNextAcrossTypes(){let A=null;for(let Q of this.queues.values()){let B=Q[0];if(!B)continue;if(!A||B.queuedAt<A.queuedAt)A=B}return A}async popNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;let B=Q.shift()??null;if(B)this.recalculatePositions(Q);return B}getRegisteredTypes(){return Array.from(this.queues.keys())}async getQueuedEntityTypes(){let A=[];for(let[Q,B]of this.queues.entries())if(B.length>0)A.push(Q);return A}getOrCreateQueue(A){let Q=this.queues.get(A);if(!Q)Q=[],this.queues.set(A,Q);return Q}recalculatePositions(A){A.forEach((Q,B)=>{Q.position=B+1})}}class uH{static instance=null;providers=new Map;executionModes=new Map;publishResultIdFields=new Map;publishTimestampFields=new Map;defaultProvider=new rhA;static getInstance(){return uH.instance??=new uH,uH.instance}static resetInstance(){uH.instance=null}static createFresh(){return new uH}constructor(){}register(A,Q,B){let w=this.providers.get(A);if(w&&w.name!=="internal"&&Q.name==="internal")return;if(this.providers.set(A,Q),this.executionModes.set(A,B?.executionMode??"provider"),B?.publishResultIdField)this.publishResultIdFields.set(A,B.publishResultIdField);else this.publishResultIdFields.delete(A);if(B?.publishTimestampField)this.publishTimestampFields.set(A,B.publishTimestampField);else this.publishTimestampFields.delete(A)}get(A){return this.providers.get(A)??this.defaultProvider}getExecutionMode(A){return this.executionModes.get(A)??"provider"}getPublishResultIdField(A){return this.publishResultIdFields.get(A)}getPublishTimestampField(A){return this.publishTimestampFields.get(A)}has(A){return this.providers.has(A)}unregister(A){this.providers.delete(A),this.executionModes.delete(A),this.publishResultIdFields.delete(A),this.publishTimestampFields.delete(A)}getRegisteredTypes(){return Array.from(this.providers.keys())}}WA();WA();async function _z1(A,Q){if(!Q.publishExecutor){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:"Publish executor not configured",retryCount:0,willRetry:!1});return}await wRQ(A,Q)}async function wRQ(A,Q){if(!Q.publishExecutor)return;try{let B=await Q.publishExecutor.publish({entityType:A.entityType,id:A.entityId});if("error"in B){let w={entityType:A.entityType,entityId:A.entityId,error:B.error,retryCount:0,willRetry:!1};if(Q.messageBus)await Q.messageBus.send({type:l4.FAILED,payload:w,sender:"publish-service"});Q.onFailed?.(w);return}dhA(A.entityType,A.entityId,B.result,Q)}catch(B){let w=y0(B);Q.retryTracker.recordFailure(A.entityId,w);let $=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:w,retryCount:$?.retryCount??1,willRetry:!1})}}function dhA(A,Q,B,w){if(w.retryTracker.clearRetries(Q),w.messageBus)w.messageBus.send({type:l4.COMPLETED,payload:{entityType:A,entityId:Q,result:B},sender:"publish-service"});w.onPublish?.({entityType:A,entityId:Q,result:B})}function vz1(A,Q,B,w){w.retryTracker.recordFailure(Q,B);let $=w.retryTracker.getRetryInfo(Q),f={entityType:A,entityId:Q,error:B,retryCount:$?.retryCount??1,willRetry:!1};if(w.messageBus)w.messageBus.send({type:l4.FAILED,payload:f,sender:"publish-service"});w.onFailed?.(f)}async function yz1(A,Q){let B=Q.generationConditions[A];if(B&&Q.onCheckGenerationConditions){let $=await Q.onCheckGenerationConditions(A,B);if(!$.shouldGenerate){if(Q.messageBus)Q.messageBus.send({type:wq.SKIPPED,payload:{entityType:A,reason:$.reason??"Conditions not met"},sender:"content-pipeline"});return}}let w={entityType:A};if(Q.messageBus)await Q.messageBus.send({type:wq.EXECUTE,payload:w,sender:"content-pipeline"});Q.onGenerate?.(w)}function Tz1(A,Q,B){if(B)B.send({type:wq.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function xz1(A,Q,B){if(B)B.send({type:wq.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var $RQ=1000;class nhA{deps;publishJobs=new Map;immediateIntervalJob=null;constructor(A){this.deps=A}start(){for(let[A,Q]of Object.entries(this.entitySchedules)){let B=this.deps.config.backend.scheduleCron(Q,()=>this.processEntityType(A));this.publishJobs.set(A,B)}this.immediateIntervalJob=this.deps.config.backend.scheduleInterval($RQ,()=>this.processUnscheduledTypes())}stop(){if(fRQ(this.publishJobs),this.immediateIntervalJob)this.immediateIntervalJob.stop(),this.immediateIntervalJob=null}async processEntityType(A){if(!this.deps.isRunning())return;try{let Q=await this.deps.config.queueManager.getNext(A);if(Q)await this.processEntry(Q)}catch(Q){this.deps.config.logger.error(`Scheduler error for ${A}:`,Q)}}async processUnscheduledTypes(){if(!this.deps.isRunning())return;try{let A=await this.deps.config.queueManager.getQueuedEntityTypes();for(let Q of A)if(!this.entitySchedules[Q]){let B=await this.deps.config.queueManager.getNext(Q);if(B){await this.processEntry(B);break}}}catch(A){this.deps.config.logger.error("Scheduler error for unscheduled types:",A)}}async processEntry(A){await this.deps.config.queueManager.remove(A.entityType,A.entityId);let Q=this.deps.getPublishDeps();await _z1(A,Q)}get entitySchedules(){return this.deps.config.entitySchedules}}function fRQ(A){for(let Q of A.values())Q.stop();A.clear()}class ohA{deps;generationJobs=new Map;constructor(A){this.deps=A}start(){for(let[A,Q]of Object.entries(this.generationSchedules)){let B=this.deps.config.backend.scheduleCron(Q,()=>this.handleTriggerGeneration(A));this.generationJobs.set(A,B)}}stop(){IRQ(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await yz1(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 IRQ(A){for(let Q of A.values())Q.stop();A.clear()}class FX{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return FX.instance??=new FX(A),FX.instance}static resetInstance(){if(FX.instance)FX.instance.stop();FX.instance=null}static createFresh(A){return new FX(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new nhA({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new ohA({config:this.config,getGenerationDeps:()=>this.generationDeps,isRunning:()=>this.running})}async start(){if(this.running)return;this.running=!0,this.publishRunner.start(),this.generationRunner.start()}async stop(){this.running=!1,this.publishRunner.stop(),this.generationRunner.stop()}isRunning(){return this.running}completePublish(A,Q,B){dhA(A,Q,B,this.publishDeps)}failPublish(A,Q,B){vz1(A,Q,B,this.publishDeps)}async publishDirect(A,Q,B,w){return this.config.providerRegistry.get(A).publish(B,w)}completeGeneration(A,Q){Tz1(A,Q,this.config.messageBus)}failGeneration(A,Q){xz1(A,Q,this.config.messageBus)}get entitySchedules(){return this.config.entitySchedules}get generationSchedules(){return this.config.generationSchedules}get publishDeps(){return{retryTracker:this.config.retryTracker,messageBus:this.config.messageBus,publishExecutor:this.config.publishExecutor,onPublish:this.config.onPublish,onFailed:this.config.onFailed}}get generationDeps(){return{logger:this.config.logger,messageBus:this.config.messageBus,generationConditions:this.config.generationConditions,onCheckGenerationConditions:this.config.onCheckGenerationConditions,onGenerate:this.config.onGenerate}}validateCronExpressions(){for(let[A,Q]of Object.entries(this.entitySchedules))this.validateCronExpression(A,Q,"publish");for(let[A,Q]of Object.entries(this.generationSchedules))this.validateCronExpression(A,Q,"generation")}validateCronExpression(A,Q,B){try{this.config.backend.validateCron(Q)}catch(w){throw Error(`Invalid ${B} cron expression for ${A}: "${Q}" - ${y0(w)}`)}}}class cH{static instance=null;retries=new Map;static getInstance(){return cH.instance??=new cH,cH.instance}static resetInstance(){cH.instance=null}static createFresh(){return new cH}constructor(){}recordFailure(A,Q){let w=(this.retries.get(A)?.retryCount??0)+1;this.retries.set(A,{entityId:A,retryCount:w,lastError:Q})}clearRetries(A){this.retries.delete(A)}getRetryInfo(A){let Q=this.retries.get(A);if(!Q)return null;return{entityId:Q.entityId,retryCount:Q.retryCount,lastError:Q.lastError}}}function l7(A,Q,B,w,$,f,I,D){return l7.fromTZ(l7.tp(A,Q,B,w,$,f,I),D)}l7.fromTZISO=(A,Q,B)=>l7.fromTZ(DRQ(A,Q),B);l7.fromTZ=function(A,Q){let B=new Date(Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)),w=shA(A.tz,B),$=new Date(B.getTime()-w),f=shA(A.tz,$);if(f-w===0)return $;{let I=new Date(B.getTime()-f),D=shA(A.tz,I);if(D-f===0)return I;if(!Q&&D-f>0)return I;if(Q)throw Error("Invalid date passed to fromTZ()");return $}};l7.toTZ=function(A,Q){let B=A.toLocaleString("en-US",{timeZone:Q}).replace(/[\u202f]/," "),w=new Date(B);return{y:w.getFullYear(),m:w.getMonth()+1,d:w.getDate(),h:w.getHours(),i:w.getMinutes(),s:w.getSeconds(),tz:Q}};l7.tp=(A,Q,B,w,$,f,I)=>({y:A,m:Q,d:B,h:w,i:$,s:f,tz:I});function shA(A,Q=new Date){let B=Q.toLocaleString("en-US",{timeZone:A,timeZoneName:"shortOffset"}).split(" ").slice(-1)[0],w=Q.toLocaleString("en-US").replace(/[\u202f]/," ");return Date.parse(`${w} GMT`)-Date.parse(`${w} ${B}`)}function DRQ(A,Q){let B=new Date(Date.parse(A));if(isNaN(B))throw Error("minitz: Invalid ISO8601 passed to parser.");let w=A.substring(9);return A.includes("Z")||w.includes("-")||w.includes("+")?l7.tp(B.getUTCFullYear(),B.getUTCMonth()+1,B.getUTCDate(),B.getUTCHours(),B.getUTCMinutes(),B.getUTCSeconds(),"Etc/UTC"):l7.tp(B.getFullYear(),B.getMonth()+1,B.getDate(),B.getHours(),B.getMinutes(),B.getSeconds(),Q)}l7.minitz=l7;var ahA=32,wr=31|ahA,mz1=[1,2,4,8,16],Sz1=class{pattern;timezone;second;minute;hour;day;month;dayOfWeek;lastDayOfMonth;starDOM;starDOW;constructor(A,Q){this.pattern=A,this.timezone=Q,this.second=Array(60).fill(0),this.minute=Array(60).fill(0),this.hour=Array(24).fill(0),this.day=Array(31).fill(0),this.month=Array(12).fill(0),this.dayOfWeek=Array(7).fill(0),this.lastDayOfMonth=!1,this.starDOM=!1,this.starDOW=!1,this.parse()}parse(){if(!(typeof this.pattern=="string"||this.pattern instanceof String))throw TypeError("CronPattern: Pattern has to be of type string.");this.pattern.indexOf("@")>=0&&(this.pattern=this.handleNicknames(this.pattern).trim());let A=this.pattern.replace(/\s+/g," ").split(" ");if(A.length<5||A.length>6)throw TypeError("CronPattern: invalid configuration format ('"+this.pattern+"'), exactly five or six space separated parts are required.");if(A.length===5&&A.unshift("0"),A[3].indexOf("L")>=0&&(A[3]=A[3].replace("L",""),this.lastDayOfMonth=!0),A[3]=="*"&&(this.starDOM=!0),A[4].length>=3&&(A[4]=this.replaceAlphaMonths(A[4])),A[5].length>=3&&(A[5]=this.replaceAlphaDays(A[5])),A[5]=="*"&&(this.starDOW=!0),this.pattern.indexOf("?")>=0){let Q=new wY(new Date,this.timezone).getDate(!0);A[0]=A[0].replace("?",Q.getSeconds().toString()),A[1]=A[1].replace("?",Q.getMinutes().toString()),A[2]=A[2].replace("?",Q.getHours().toString()),this.starDOM||(A[3]=A[3].replace("?",Q.getDate().toString())),A[4]=A[4].replace("?",(Q.getMonth()+1).toString()),this.starDOW||(A[5]=A[5].replace("?",Q.getDay().toString()))}this.throwAtIllegalCharacters(A),this.partToArray("second",A[0],0,1),this.partToArray("minute",A[1],0,1),this.partToArray("hour",A[2],0,1),this.partToArray("day",A[3],-1,1),this.partToArray("month",A[4],-1,1),this.partToArray("dayOfWeek",A[5],0,wr),this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(A,Q,B,w){let $=this[A],f=A==="day"&&this.lastDayOfMonth;if(Q===""&&!f)throw TypeError("CronPattern: configuration entry "+A+" ("+Q+") is empty, check for trailing spaces.");if(Q==="*")return $.fill(w);let I=Q.split(",");if(I.length>1)for(let D=0;D<I.length;D++)this.partToArray(A,I[D],B,w);else Q.indexOf("-")!==-1&&Q.indexOf("/")!==-1?this.handleRangeWithStepping(Q,A,B,w):Q.indexOf("-")!==-1?this.handleRange(Q,A,B,w):Q.indexOf("/")!==-1?this.handleStepping(Q,A,B,w):Q!==""&&this.handleNumber(Q,A,B,w)}throwAtIllegalCharacters(A){for(let Q=0;Q<A.length;Q++)if((Q===5?/[^/*0-9,\-#L]+/:/[^/*0-9,-]+/).test(A[Q]))throw TypeError("CronPattern: configuration entry "+Q+" ("+A[Q]+") contains illegal characters.")}handleNumber(A,Q,B,w){let $=this.extractNth(A,Q),f=parseInt($[0],10)+B;if(isNaN(f))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,f,$[1]||w)}setPart(A,Q,B){if(!Object.prototype.hasOwnProperty.call(this,A))throw TypeError("CronPattern: Invalid part specified: "+A);if(A==="dayOfWeek"){if(Q===7&&(Q=0),Q<0||Q>6)throw RangeError("CronPattern: Invalid value for dayOfWeek: "+Q);this.setNthWeekdayOfMonth(Q,B);return}if(A==="second"||A==="minute"){if(Q<0||Q>=60)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="hour"){if(Q<0||Q>=24)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="day"){if(Q<0||Q>=31)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="month"&&(Q<0||Q>=12))throw RangeError("CronPattern: Invalid value for "+A+": "+Q);this[A][Q]=B}handleRangeWithStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(f===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,I,D,U]=f,Y=parseInt(I,10)+B,J=parseInt(D,10)+B,X=parseInt(U,10);if(isNaN(Y))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(J))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(isNaN(X))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(X===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(X>this[Q].length)throw TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+this[Q].length+")");if(Y>J)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let G=Y;G<=J;G+=X)this.setPart(Q,G,$[1]||w)}extractNth(A,Q){let B=A,w;if(B.includes("#")){if(Q!=="dayOfWeek")throw Error("CronPattern: nth (#) only allowed in day-of-week field");w=B.split("#")[1],B=B.split("#")[0]}return[B,w]}handleRange(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].split("-");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let I=parseInt(f[0],10)+B,D=parseInt(f[1],10)+B;if(isNaN(I))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(I>D)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let U=I;U<=D;U++)this.setPart(Q,U,$[1]||w)}handleStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].split("/");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");f[0]===""&&(f[0]="*");let I=0;f[0]!=="*"&&(I=parseInt(f[0],10)+B);let D=parseInt(f[1],10);if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(D===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(D>this[Q].length)throw TypeError("CronPattern: Syntax error, max steps for part is ("+this[Q].length+")");for(let U=I;U<this[Q].length;U+=D)this.setPart(Q,U,$[1]||w)}replaceAlphaDays(A){return A.replace(/-sun/gi,"-7").replace(/sun/gi,"0").replace(/mon/gi,"1").replace(/tue/gi,"2").replace(/wed/gi,"3").replace(/thu/gi,"4").replace(/fri/gi,"5").replace(/sat/gi,"6")}replaceAlphaMonths(A){return A.replace(/jan/gi,"1").replace(/feb/gi,"2").replace(/mar/gi,"3").replace(/apr/gi,"4").replace(/may/gi,"5").replace(/jun/gi,"6").replace(/jul/gi,"7").replace(/aug/gi,"8").replace(/sep/gi,"9").replace(/oct/gi,"10").replace(/nov/gi,"11").replace(/dec/gi,"12")}handleNicknames(A){let Q=A.trim().toLowerCase();return Q==="@yearly"||Q==="@annually"?"0 0 1 1 *":Q==="@monthly"?"0 0 1 * *":Q==="@weekly"?"0 0 * * 0":Q==="@daily"?"0 0 * * *":Q==="@hourly"?"0 * * * *":A}setNthWeekdayOfMonth(A,Q){if(typeof Q!="number"&&Q==="L")this.dayOfWeek[A]=this.dayOfWeek[A]|ahA;else if(Q===wr)this.dayOfWeek[A]=wr;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|mz1[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},gz1=[31,28,31,30,31,30,31,31,30,31,30,31],tF=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],wY=class A{tz;ms;second;minute;hour;day;month;year;constructor(Q,B){if(this.tz=B,Q&&Q instanceof Date)if(!isNaN(Q))this.fromDate(Q);else throw TypeError("CronDate: Invalid date passed to CronDate constructor");else if(Q===void 0)this.fromDate(new Date);else if(Q&&typeof Q=="string")this.fromString(Q);else if(Q instanceof A)this.fromCronDate(Q);else throw TypeError("CronDate: Invalid type ("+typeof Q+") passed to CronDate constructor")}isNthWeekdayOfMonth(Q,B,w,$){let f=new Date(Date.UTC(Q,B,w)).getUTCDay(),I=0;for(let D=1;D<=w;D++)new Date(Date.UTC(Q,B,D)).getUTCDay()===f&&I++;if($&wr&&mz1[I-1]&$)return!0;if($&ahA){let D=new Date(Date.UTC(Q,B+1,0)).getUTCDate();for(let U=w+1;U<=D;U++)if(new Date(Date.UTC(Q,B,U)).getUTCDay()===f)return!1;return!0}return!1}fromDate(Q){if(this.tz!==void 0)if(typeof this.tz=="number")this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes()+this.tz,this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),this.apply();else{let B=l7.toTZ(Q,this.tz);this.ms=Q.getMilliseconds(),this.second=B.s,this.minute=B.i,this.hour=B.h,this.day=B.d,this.month=B.m-1,this.year=B.y}else this.ms=Q.getMilliseconds(),this.second=Q.getSeconds(),this.minute=Q.getMinutes(),this.hour=Q.getHours(),this.day=Q.getDate(),this.month=Q.getMonth(),this.year=Q.getFullYear()}fromCronDate(Q){this.tz=Q.tz,this.year=Q.year,this.month=Q.month,this.day=Q.day,this.hour=Q.hour,this.minute=Q.minute,this.second=Q.second,this.ms=Q.ms}apply(){if(this.month>11||this.day>gz1[this.month]||this.hour>59||this.minute>59||this.second>59||this.hour<0||this.minute<0||this.second<0){let Q=new Date(Date.UTC(this.year,this.month,this.day,this.hour,this.minute,this.second,this.ms));return this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes(),this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),!0}else return!1}fromString(Q){if(typeof this.tz=="number"){let B=l7.fromTZISO(Q);this.ms=B.getUTCMilliseconds(),this.second=B.getUTCSeconds(),this.minute=B.getUTCMinutes(),this.hour=B.getUTCHours(),this.day=B.getUTCDate(),this.month=B.getUTCMonth(),this.year=B.getUTCFullYear(),this.apply()}else return this.fromDate(l7.fromTZISO(Q,this.tz))}findNext(Q,B,w,$){let f=this[B],I;w.lastDayOfMonth&&(this.month!==1?I=gz1[this.month]:I=new Date(Date.UTC(this.year,this.month+1,0,0,0,0,0)).getUTCDate());let D=!w.starDOW&&B=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0;for(let U=this[B]+$;U<w[B].length;U++){let Y=w[B][U];if(B==="day"&&w.lastDayOfMonth&&U-$==I&&(Y=1),B==="day"&&!w.starDOW){let J=w.dayOfWeek[(D+(U-$-1))%7];if(J&&J&wr)J=this.isNthWeekdayOfMonth(this.year,this.month,U-$,J)?1:0;else if(J)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${J}`);Q.legacyMode&&!w.starDOM?Y=Y||J:Y=Y&&J}if(Y)return this[B]=U-$,f!==this[B]?2:1}return 3}recurse(Q,B,w){let $=this.findNext(B,tF[w][0],Q,tF[w][2]);if($>1){let f=w+1;for(;f<tF.length;)this[tF[f][0]]=-tF[f][2],f++;if($===3)return this[tF[w][1]]++,this[tF[w][0]]=-tF[w][2],this.apply(),this.recurse(Q,B,0);if(this.apply())return this.recurse(Q,B,w-1)}return w+=1,w>=tF.length?this:this.year>=3000?null:this.recurse(Q,B,w)}increment(Q,B,w){return this.second+=B.interval!==void 0&&B.interval>1&&w?B.interval:1,this.ms=0,this.apply(),this.recurse(Q,B,0)}getDate(Q){return Q||this.tz===void 0?new Date(this.year,this.month,this.day,this.hour,this.minute,this.second,this.ms):typeof this.tz=="number"?new Date(Date.UTC(this.year,this.month,this.day,this.hour,this.minute-this.tz,this.second,this.ms)):l7.fromTZ(l7.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function URQ(A){if(A===void 0&&(A={}),delete A.name,A.legacyMode=A.legacyMode===void 0?!0:A.legacyMode,A.paused=A.paused===void 0?!1:A.paused,A.maxRuns=A.maxRuns===void 0?1/0:A.maxRuns,A.catch=A.catch===void 0?!1:A.catch,A.interval=A.interval===void 0?0:parseInt(A.interval.toString(),10),A.utcOffset=A.utcOffset===void 0?void 0:parseInt(A.utcOffset.toString(),10),A.unref=A.unref===void 0?!1:A.unref,A.startAt&&(A.startAt=new wY(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new wY(A.stopAt,A.timezone)),A.interval!==null){if(isNaN(A.interval))throw Error("CronOptions: Supplied value for interval is not a number");if(A.interval<0)throw Error("CronOptions: Supplied value for interval can not be negative")}if(A.utcOffset!==void 0){if(isNaN(A.utcOffset))throw Error("CronOptions: Invalid value passed for utcOffset, should be number representing minutes offset from UTC.");if(A.utcOffset<-870||A.utcOffset>870)throw Error("CronOptions: utcOffset out of bounds.");if(A.utcOffset!==void 0&&A.timezone)throw Error("CronOptions: Combining 'utcOffset' with 'timezone' is not allowed.")}if(A.unref!==!0&&A.unref!==!1)throw Error("CronOptions: Unref should be either true, false or undefined(false).");return A}function Br(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function YRQ(A){return Br(A)}function JRQ(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var hz1=30000,u$A=[],thA=class{name;options;_states;fn;constructor(A,Q,B){let w,$;if(Br(Q))$=Q;else if(typeof Q=="object")w=Q;else if(Q!==void 0)throw Error("Cron: Invalid argument passed for optionsIn. Should be one of function, or object (options).");if(Br(B))$=B;else if(typeof B=="object")w=B;else if(B!==void 0)throw Error("Cron: Invalid argument passed for funcIn. Should be one of function, or object (options).");if(this.name=w?.name,this.options=URQ(w),this._states={kill:!1,blocking:!1,previousRun:void 0,currentRun:void 0,once:void 0,currentTimeout:void 0,maxRuns:w?w.maxRuns:void 0,paused:w?w.paused:!1,pattern:new Sz1("* * * * *")},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new wY(A,this.options.timezone||this.options.utcOffset):this._states.pattern=new Sz1(A,this.options.timezone),this.name){if(u$A.find((f)=>f.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");u$A.push(this)}return $!==void 0&&YRQ($)&&(this.fn=$,this.schedule()),this}nextRun(A){let Q=this._next(A);return Q?Q.getDate(!1):null}nextRuns(A,Q){this._states.maxRuns!==void 0&&A>this._states.maxRuns&&(A=this._states.maxRuns);let B=[],w=Q||this._states.currentRun||void 0;for(;A--&&(w=this.nextRun(w));)B.push(w);return B}getPattern(){return this._states.pattern?this._states.pattern.pattern:void 0}isRunning(){let A=this.nextRun(this._states.currentRun),Q=!this._states.paused,B=this.fn!==void 0,w=!this._states.kill;return Q&&B&&w&&A!==null}isStopped(){return this._states.kill}isBusy(){return this._states.blocking}currentRun(){return this._states.currentRun?this._states.currentRun.getDate():null}previousRun(){return this._states.previousRun?this._states.previousRun.getDate():null}msToNext(A){let Q=this._next(A);return Q?A instanceof wY||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new wY(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=u$A.indexOf(this);A>=0&&u$A.splice(A,1)}pause(){return this._states.paused=!0,!this._states.kill}resume(){return this._states.paused=!1,!this._states.kill}schedule(A){if(A&&this.fn)throw Error("Cron: It is not allowed to schedule two functions using the same Croner instance.");A&&(this.fn=A);let Q=this.msToNext(),B=this.nextRun(this._states.currentRun);return Q==null||isNaN(Q)||B===null?this:(Q>hz1&&(Q=hz1),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(B),Q),this._states.currentTimeout&&this.options.unref&&JRQ(this._states.currentTimeout),this)}async _trigger(A){if(this._states.blocking=!0,this._states.currentRun=new wY(void 0,this.options.timezone||this.options.utcOffset),this.options.catch)try{this.fn!==void 0&&await this.fn(this,this.options.context)}catch(Q){Br(this.options.catch)&&this.options.catch(Q,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new wY(A,this.options.timezone||this.options.utcOffset),this._states.blocking=!1}async trigger(){await this._trigger()}runsLeft(){return this._states.maxRuns}_checkTrigger(A){let Q=new Date,B=!this._states.paused&&Q.getTime()>=A.getTime(),w=this._states.blocking&&this.options.protect;B&&!w?(this._states.maxRuns!==void 0&&this._states.maxRuns--,this._trigger()):B&&w&&Br(this.options.protect)&&setTimeout(()=>this.options.protect(this),0),this.schedule()}_next(A){let Q=!!(A||this._states.currentRun),B=!1;!A&&this.options.startAt&&this.options.interval&&([A,Q]=this._calculatePreviousRun(A,Q),B=!A),A=new wY(A,this.options.timezone||this.options.utcOffset),this.options.startAt&&A&&A.getTime()<this.options.startAt.getTime()&&(A=this.options.startAt);let w=this._states.once||new wY(A,this.options.timezone||this.options.utcOffset);return!B&&w!==this._states.once&&(w=w.increment(this._states.pattern,this.options,Q)),this._states.once&&this._states.once.getTime()<=A.getTime()||w===null||this._states.maxRuns!==void 0&&this._states.maxRuns<=0||this._states.kill||this.options.stopAt&&w.getTime()>=this.options.stopAt.getTime()?null:w}_calculatePreviousRun(A,Q){let B=new wY(void 0,this.options.timezone||this.options.utcOffset),w=A;if(this.options.startAt.getTime()<=B.getTime()){w=this.options.startAt;let $=w.getTime()+this.options.interval*1000;for(;$<=B.getTime();)w=new wY(w,this.options.timezone||this.options.utcOffset).increment(this._states.pattern,this.options,!0),$=w.getTime()+this.options.interval*1000;Q=!0}return w===null&&(w=void 0),[w,Q]}};class c$A{scheduleCron(A,Q){let B=new thA(A,()=>{Q()});return{stop:()=>B.stop()}}scheduleInterval(A,Q){let B=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(B)}}validateCron(A){new thA(A).stop()}}WA();var uz1=H.union([H.string().min(1),H.object({location:H.enum(["metadata","frontmatter"]),field:H.string().min(1)})]),l$A=H.object({entityType:H.string().min(1),attachmentType:H.string().min(1),mediaEntityType:H.enum(["image","document"]),targetEntityField:uz1.optional(),requiredWhen:H.object({status:H.string().min(1).optional(),visibility:H.string().min(1).optional()}).optional(),autoGenerate:H.boolean().optional(),requiredForPublish:H.boolean().optional(),jobType:H.string().min(1).optional()});function ehA(A){return`${A.entityType}:${A.attachmentType}`}class lH{static instance=null;definitions=new Map;static getInstance(){return lH.instance??=new lH,lH.instance}static resetInstance(){lH.instance=null}static createFresh(){return new lH}constructor(){}register(A){let Q=l$A.parse(A),B=ehA(Q);return this.definitions.set(B,Q),()=>this.unregister(Q.entityType,Q.attachmentType)}get(A,Q){return this.definitions.get(ehA({entityType:A,attachmentType:Q}))}list(A){let Q=Array.from(this.definitions.values());return A?Q.filter((B)=>B.entityType===A):Q}has(A,Q){return this.get(A,Q)!==void 0}unregister(A,Q){this.definitions.delete(ehA({entityType:A,attachmentType:Q}))}clear(){this.definitions.clear()}}WA();class p$A{deps;constructor(A){this.deps=A}async ensureForEntity(A,Q={}){let B=this.deps.registry.list(A.entityType).filter(($)=>$.autoGenerate===!0).filter(($)=>!Q.attachmentType||$.attachmentType===Q.attachmentType),w={checked:B.length,enqueued:0,skipped:0};for(let $ of B)if(await this.ensureDefinition(A,$))w.enqueued+=1;else w.skipped+=1;return w}async ensureDefinition(A,Q){if(!this.matchesPolicy(A,Q))return!1;if(this.hasTargetField(A,Q.targetEntityField))return!1;if(!this.deps.context.attachments.hasProvider(A.entityType,Q.attachmentType))return!1;let B=this.resolveJobType(Q);if(!B)return!1;let w=this.getPredictedMediaId(A,Q),$=this.getDeduplicationKey(A,Q);return await this.deps.context.jobs.enqueue({type:B,data:{sourceEntityType:A.entityType,sourceEntityId:A.id,attachmentType:Q.attachmentType,imageId:w,dedupKey:$,targetEntityType:A.entityType,targetEntityId:A.id,...this.getTargetImageFieldData(Q.targetEntityField)},options:{source:"content-pipeline",metadata:{operationType:"content_operations"},deduplication:"skip",deduplicationKey:$}}),this.deps.context.logger.debug("Queued publish asset generation",{entityType:A.entityType,entityId:A.id,attachmentType:Q.attachmentType,jobType:B}),!0}matchesPolicy(A,Q){let{requiredWhen:B}=Q;if(!B)return!0;if(B.status&&A.metadata.status!==B.status)return!1;if(B.visibility&&A.visibility!==B.visibility)return!1;return!0}hasTargetField(A,Q){if(!Q)return!1;if(typeof Q==="string")return AmA(A.metadata[Q]);if(Q.location==="metadata")return AmA(A.metadata[Q.field]);let{frontmatter:B}=jB(A.content);return AmA(B[Q.field])}resolveJobType(A){if(A.jobType)return A.jobType;if(A.mediaEntityType==="image")return"image:image-render-source";return}getPredictedMediaId(A,Q){let B=Q.attachmentType==="og-image"?"og":Q.attachmentType;return X1(`${B}-${A.entityType}-${A.id}`)}getDeduplicationKey(A,Q){return`publish-asset:${Q.attachmentType}:${A.entityType}:${A.id}`}getTargetImageFieldData(A){let Q=typeof A==="string"?A:A?.field;if(Q==="coverImageId"||Q==="ogImageId")return{targetImageField:Q};return{}}}function AmA(A){return typeof A==="string"?A.length>0:A!==void 0}aA();WA();var XRQ=H.object({id:H.string().min(1)});async function lz1(A,Q){let{bodyContent:B,coverImageId:w,documents:$,sourceEntityType:f,sourceEntityId:I}=WRQ(Q.content),D=w?await KRQ(A,w):void 0,U;if($&&$.length>0){let J=await FRQ(A,$);if(J.length>0)U=J}U??=await GRQ(A,f,I);let Y={bodyContent:B};if(D)Y.imageData=D;if(U&&U.length>0)Y.documentData=U;return Y}function WRQ(A){try{let Q=b2(A,H.record(H.unknown())),B=Q.metadata.coverImageId,w=typeof B==="string"?B:void 0,$=HRQ(Q.metadata.documents),f=cz1(Q.metadata.sourceEntityType),I=cz1(Q.metadata.sourceEntityId);return{bodyContent:Q.content,...w&&{coverImageId:w},...$.length>0&&{documents:$},...f&&{sourceEntityType:f},...I&&{sourceEntityId:I}}}catch{return{bodyContent:A}}}function HRQ(A){if(!Array.isArray(A))return[];return A.flatMap((Q)=>{let B=XRQ.safeParse(Q);return B.success?[B.data]:[]})}function cz1(A){return typeof A==="string"&&A.length>0?A:void 0}async function GRQ(A,Q,B){if(!Q||!B)return;let w=await A.attachments.resolve({sourceEntityType:Q,sourceEntityId:B,attachmentType:"carousel"});return w?[w]:void 0}async function KRQ(A,Q){let B=await A.entityService.getEntity({entityType:"image",id:Q});if(!B?.content)return;let w=pz1(B.content);if(!w?.mimeType.startsWith("image/"))return;return{data:w.data,mimeType:w.mimeType}}async function FRQ(A,Q){return(await Promise.all(Q.map((w)=>ZRQ(A,w)))).filter((w)=>w!==void 0)}async function ZRQ(A,Q){let B=await A.entityService.getEntity({entityType:"document",id:Q.id});if(!B?.content)return;let w=pz1(B.content);if(w?.mimeType!=="application/pdf")return;return{type:"document",data:w.data,mimeType:"application/pdf",filename:NRQ(B,Q.id)}}function pz1(A){let Q=A.match(/^data:([^;]+);base64,(.+)$/);if(!Q?.[1]||!Q[2])return;return{mimeType:Q[1],data:Buffer.from(Q[2],"base64")}}function NRQ(A,Q){let B=A.metadata.filename;return typeof B==="string"&&B.length>0?B:`${Q}.pdf`}WA();var zRQ=/^---\r?\n[\s\S]*?\r?\n---(?:\r?\n|$)/;async function QmA(A,Q,B,w={}){let $=w.publishedAt??new Date().toISOString(),f=w.publishTimestampField??"publishedAt",I={...Q.metadata,status:"published",[f]:$,platformId:B.id,...qRQ(B.id,w.publishResultIdField)},D={...Q,content:iz1(Q.content,$,B.id,w.publishResultIdField,f),metadata:I};return await A.entityService.updateEntity({entity:D}),D}function iz1(A,Q,B,w,$="publishedAt"){if(!zRQ.test(A))return A;let f=X4(X4(A,"status","published"),$,Q);if(!B||!w)return f;return X4(f,w,B)}function qRQ(A,Q){if(!Q||Q==="platformId")return{};return{[Q]:A}}class iv{deps;constructor(A){this.deps=A}async resolveCandidate(A){let{entityType:Q,id:B,slug:w}=A;if(!B&&!w)return{error:"Either 'id' or 'slug' must be provided"};let $=await this.findPublishableEntity(Q,B,w);if(!$)return{error:`Entity not found: ${Q}:${B??w}`};if($.visibility!=="public")return{error:`Cannot publish ${Q}:${$.id} to a public provider because visibility is ${$.visibility}`};if($.metadata.status==="published")return{error:"Entity is already published"};if(!this.deps.providerRegistry.has(Q))return{error:`No publish provider registered for ${Q}. Check that the required credentials are configured.`};return{entity:$}}async publish(A){let Q=await this.resolveCandidate(A);if("error"in Q)return Q;let{entity:B}=Q,{entityType:w}=A,$=this.deps.providerRegistry.get(w),{bodyContent:f,imageData:I,documentData:D}=await lz1(this.deps.context,B),U=await $.publish(f,B.metadata,I,D),Y=this.deps.providerRegistry.getPublishResultIdField(w),J=this.deps.providerRegistry.getPublishTimestampField(w),X=await QmA(this.deps.context,B,U,{...Y?{publishResultIdField:Y}:{},...J?{publishTimestampField:J}:{}});return await this.runPublishAssetPreflight(X),{entity:X,result:U}}async runPublishAssetPreflight(A){if(!this.deps.publishAssetPreflight)return;try{await this.deps.publishAssetPreflight.ensureForEntity(A)}catch(Q){this.deps.context.logger.warn("Publish asset preflight failed",{entityType:A.entityType,entityId:A.id,error:Q instanceof Error?Q.message:String(Q)})}}async findPublishableEntity(A,Q,B){if(Q)return this.deps.context.entityService.getEntity({entityType:A,id:Q});if(!B)return null;return(await this.deps.context.entityService.listEntities({entityType:A,options:{filter:{metadata:{slug:B}},limit:1}}))[0]??null}}aA();WA();var BmA=H.object({action:H.enum(["list","add","remove","reorder"]).describe("Queue action to perform"),entityType:H.string().optional().describe("Entity type (required for add/remove/reorder, optional for list)"),entityId:H.string().optional().describe("Entity ID (required for add/remove/reorder)"),position:H.number().optional().describe("New position for reorder action (1-based)")}),wmA=H.object({position:H.number(),entityType:H.string(),entityId:H.string(),queuedAt:H.string()}),LRQ=H.object({success:H.literal(!0),message:H.string().optional(),data:H.object({queue:H.array(wmA).optional(),entityType:H.string().optional(),entityId:H.string().optional(),position:H.number().optional()}).optional()}),VRQ=H.object({success:H.literal(!1),error:H.string(),code:H.string().optional()}),$mA=H.union([LRQ,VRQ]);function i$A(A,Q,B){return{...oQ(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",BmA,async($,f)=>{let{action:I,entityType:D,entityId:U,position:Y}=$;switch(I){case"list":return ERQ(B,D);case"add":return MRQ(A,B,D,U,f);case"remove":return CRQ(A,B,D,U,f);case"reorder":return ORQ(A,B,D,U,Y,f);default:return{success:!1,error:`Unknown action: ${I}`}}}),outputSchema:$mA}}async function ERQ(A,Q){let B=[];if(Q)B=await A.list(Q);else{let $=A.getRegisteredTypes();for(let f of $){let I=await A.list(f);B.push(...I)}B.sort((f,I)=>new Date(f.queuedAt).getTime()-new Date(I.queuedAt).getTime())}if(B.length===0)return{success:!0,data:{queue:[]},message:"No items in queue"};return{success:!0,data:{queue:B.map(($,f)=>({position:f+1,entityType:$.entityType,entityId:$.entityId,queuedAt:$.queuedAt}))},message:`${B.length} items in queue`}}async function MRQ(A,Q,B,w,$){let f=fmA("add",B,w);if(!f.success)return f.error;A.permissions.assertEntityActionAllowed(f.entityType,"publish",$??{});let I=await Q.add(f.entityType,f.entityId,{...$,authorization:"user"});return{success:!0,data:{entityType:f.entityType,entityId:f.entityId,position:I.position},message:`Added to queue at position ${I.position}`}}async function CRQ(A,Q,B,w,$){let f=fmA("remove",B,w);if(!f.success)return f.error;return A.permissions.assertEntityActionAllowed(f.entityType,"update",$??{}),await Q.remove(f.entityType,f.entityId),{success:!0,data:{entityType:f.entityType,entityId:f.entityId},message:"Removed from queue"}}async function ORQ(A,Q,B,w,$,f){let I=fmA("reorder",B,w);if(!I.success)return I.error;let D=RRQ($);if(!D.success)return D.error;return A.permissions.assertEntityActionAllowed(I.entityType,"update",f??{}),await Q.reorder(I.entityType,I.entityId,D.position),{success:!0,data:{entityType:I.entityType,entityId:I.entityId,position:D.position},message:`Moved to position ${D.position}`}}function fmA(A,Q,B){if(!Q)return{success:!1,error:{success:!1,error:`entityType is required for ${A} action`}};if(!B)return{success:!1,error:{success:!1,error:`entityId is required for ${A} action`}};return{success:!0,entityType:Q,entityId:B}}function RRQ(A){if(A===void 0)return{success:!1,error:{success:!1,error:"position is required for reorder action"}};if(A<1)return{success:!1,error:{success:!1,error:"position must be a positive number"}};return{success:!0,position:A}}WA();var r$A=H.object({entityType:H.string().describe("Entity type to publish (e.g., social-post, post, deck)"),id:H.string().optional().describe("Entity ID to publish"),slug:H.string().optional().describe("Entity slug to publish"),confirmed:H.boolean().optional(),confirmationToken:H.string().optional(),contentHash:H.string().optional()}),bRQ=H.object({success:H.literal(!0),message:H.string().optional(),data:H.object({entityType:H.string().optional(),entityId:H.string().optional(),platformId:H.string().optional(),url:H.string().optional()}).optional()}),PRQ=H.object({success:H.literal(!1),error:H.string(),code:H.string().optional()}),kRQ=H.object({success:H.literal(!1).optional(),error:H.string().optional(),needsConfirmation:H.literal(!0),toolName:H.string(),summary:H.string(),preview:H.string().optional(),args:H.unknown()}),ImA=H.union([bRQ,PRQ,kRQ]),jRQ=900000,_RQ=1000;class dz1{tokens=new Map;add(A){if(this.prune(),this.tokens.size>=_RQ){let Q=this.tokens.keys().next().value;if(Q!==void 0)this.tokens.delete(Q)}this.tokens.set(A,Date.now()+jRQ)}has(A){let Q=this.tokens.get(A);if(Q===void 0)return!1;if(Q<=Date.now())return this.tokens.delete(A),!1;return!0}delete(A){this.tokens.delete(A)}prune(){let A=Date.now();for(let[Q,B]of this.tokens)if(B<=A)this.tokens.delete(Q)}}function d$A(A,Q,B,w){let $=w??new iv({context:A,providerRegistry:B}),f=new dz1,I=`${Q}_publish`;return{name:I,description:"Publish an entity directly to its platform. Call this when the user asks to publish; the tool will request confirmation itself. Works with any registered entity type (social-post, post, deck, etc.)",inputSchema:r$A.shape,outputSchema:ImA,visibility:"anchor",handler:async(D,U)=>{let Y=r$A.safeParse(D);if(!Y.success)return{success:!1,error:`Invalid input: ${Y.error.errors.map((L)=>`${L.path.join(".")}: ${L.message}`).join(", ")}`};let J=Y.data,{entityType:X,id:G,slug:Z}=J;try{A.permissions.assertEntityActionAllowed(X,"publish",U)}catch(L){return{success:!1,error:L instanceof Error?L.message:String(L)}}let N=await $.resolveCandidate({entityType:X,id:G,slug:Z});if("error"in N)return{success:!1,error:N.error};let{entity:V}=N;if(J.confirmed){let L=J.confirmationToken;if(!L||!f.has(L))return rz1(I,J,V,f);if(f.delete(L),J.contentHash&&J.contentHash!==V.contentHash)return{success:!1,error:`Cannot publish ${X}:${V.id} because it changed after confirmation. Review it and try again.`};let M;try{M=await $.publish({entityType:X,id:V.id})}catch(S){return{success:!1,error:S instanceof Error?S.message:String(S)}}if("error"in M)return{success:!1,error:M.error};let{entity:O,result:E}=M;return{success:!0,data:{entityType:X,entityId:O.id,platformId:E.id,url:E.url},message:`Published ${X}:${O.id}`}}return rz1(I,J,V,f)}}}function rz1(A,Q,B,w){let $=crypto.randomUUID();w.add($);let f=vRQ(B);return{needsConfirmation:!0,toolName:A,summary:`Publish "${f}"?`,preview:`This will publish ${B.entityType}:${B.id} to its registered public publish provider.`,args:{...Q,id:B.id,slug:void 0,confirmed:!0,confirmationToken:$,contentHash:B.contentHash}}}function vRQ(A){let Q=A.metadata.title;if(typeof Q==="string"&&Q.length>0)return Q;let B=A.metadata.subject;if(typeof B==="string"&&B.length>0)return B;let w=A.metadata.slug;if(typeof w==="string"&&w.length>0)return w;return A.id}aA();WA();var DmA=H.object({entityType:H.string().min(1).describe("Entity type to reconcile"),status:H.string().min(1).optional().describe("Optional metadata status filter, e.g. published"),assetType:H.string().min(1).optional().describe("Optional attachment type filter, e.g. og-image")}),UmA=H.object({success:H.literal(!0),data:H.object({entityType:H.string(),assetType:H.string().optional(),checkedEntities:H.number(),checkedAssets:H.number(),enqueued:H.number(),skipped:H.number()}),message:H.string().optional()});function n$A(A,Q,B,w){return{...oQ(Q,"ensure-assets","Reconcile configured publish assets for existing entities, queueing missing generated assets such as OG images.",DmA,async(f,I)=>{if(A.permissions.assertEntityActionAllowed(f.entityType,"publish",I),B.list(f.entityType).filter((G)=>G.autoGenerate===!0).filter((G)=>!f.assetType||G.attachmentType===f.assetType).length===0)return{success:!0,data:{entityType:f.entityType,...f.assetType&&{assetType:f.assetType},checkedEntities:0,checkedAssets:0,enqueued:0,skipped:0},message:`No publish assets configured for ${f.entityType}`};let U=await A.entityService.listEntities({entityType:f.entityType,options:{...f.status&&{filter:{metadata:{status:f.status}}}}}),Y=0,J=0,X=0;for(let G of U){let Z=await w.ensureForEntity(G,{...f.assetType&&{attachmentType:f.assetType}});Y+=Z.checked,J+=Z.enqueued,X+=Z.skipped}return{success:!0,data:{entityType:f.entityType,...f.assetType&&{assetType:f.assetType},checkedEntities:U.length,checkedAssets:Y,enqueued:J,skipped:X},message:`Queued ${J} publish asset job(s)`}}),outputSchema:UmA}}aA();WA();function nz1(A,Q){yRQ(A,Q),TRQ(A,Q),xRQ(A,Q),SRQ(A,Q)}function yRQ(A,Q){A.messaging.subscribe(l4.REGISTER,async(B)=>gRQ(Q,B.payload)),A.messaging.subscribe(l4.QUEUE,async(B)=>cRQ(A,Q,B.payload)),A.messaging.subscribe(l4.DIRECT,async(B)=>lRQ(A,Q,B.payload)),A.messaging.subscribe(l4.REMOVE,async(B)=>pRQ(Q,B.payload)),A.messaging.subscribe(l4.REORDER,async(B)=>iRQ(Q,B.payload)),A.messaging.subscribe(l4.LIST,async(B)=>rRQ(A,Q,B.payload)),A.messaging.subscribe(l4.REPORT_SUCCESS,async(B)=>dRQ(Q,B.payload)),A.messaging.subscribe(l4.REPORT_FAILURE,async(B)=>nRQ(Q,B.payload)),Q.logger.debug("Subscribed to publish messages")}function TRQ(A,Q){A.messaging.subscribe(wq.REPORT_SUCCESS,async(B)=>oRQ(Q,B.payload)),A.messaging.subscribe(wq.REPORT_FAILURE,async(B)=>sRQ(Q,B.payload)),Q.logger.debug("Subscribed to generation messages")}function xRQ(A,Q){A.messaging.subscribe(Pz1.REGISTER,async(B)=>hRQ(Q,B.payload)),Q.logger.debug("Subscribed to publish asset messages")}function SRQ(A,Q){let B=async(w)=>mRQ(A,Q,w.payload);A.messaging.subscribe("entity:created",B),A.messaging.subscribe("entity:updated",B),Q.logger.debug("Subscribed to entity change messages for publish assets")}async function gRQ(A,Q){let{entityType:B,provider:w,config:$}=Q;try{let f=$?kz1.safeParse($):void 0;if(f&&!f.success)return A.logger.warn("Invalid publish provider config",{entityType:B,error:f.error.message}),{success:!1};if(w)A.providerRegistry.register(B,w,f?.data),A.logger.info(`Registered provider for entity type: ${B}`,{providerName:w.name,executionMode:A.providerRegistry.getExecutionMode(B)});return{success:!0}}catch(f){let I=y0(f);return A.logger.error(`Failed to register provider: ${I}`),{success:!1}}}async function hRQ(A,Q){let B=l$A.safeParse(Q);if(!B.success)return A.logger.warn("Invalid publish asset registration",{error:B.error.message}),{success:!1};return A.publishAssetRegistry.register(B.data),A.logger.info("Registered publish asset",{entityType:B.data.entityType,attachmentType:B.data.attachmentType,mediaEntityType:B.data.mediaEntityType}),{success:!0}}async function mRQ(A,Q,B){try{if(Q.publishAssetRegistry.list(B.entityType).length===0)return{success:!0};let w=B.entity??await A.entityService.getEntity({entityType:B.entityType,id:B.entityId});if(!uRQ(w))return{success:!0};return await Q.publishAssetPreflight.ensureForEntity(w),{success:!0}}catch(w){return Q.logger.warn("Failed to run publish asset preflight for entity event",{entityType:B.entityType,entityId:B.entityId,error:y0(w)}),{success:!1}}}function uRQ(A){if(!A)return!1;let Q=bz1.safeParse(A.metadata);return Q.success&&Q.data.status==="published"}async function cRQ(A,Q,B){let{entityType:w,entityId:$}=B;try{let f=B.authContext??Qr;A.permissions.assertEntityActionAllowed(w,"publish",f);let I=await Q.queueManager.add(w,$,f);return await A.messaging.send({type:l4.QUEUED,payload:{entityType:w,entityId:$,position:I.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:w,position:I.position}),{success:!0}}catch(f){let I=y0(f);return Q.logger.error(`Failed to queue entity: ${I}`),{success:!1}}}async function lRQ(A,Q,B){let{entityType:w,entityId:$}=B,f=B.authContext??Qr;try{if(A.permissions.assertEntityActionAllowed(w,"publish",f),!Q.providerRegistry.has(w))return Q.scheduler.failPublish(w,$,`No publish provider registered for ${w}`),{success:!1};let I=await Q.publishExecutor.publish({entityType:w,id:$});if("error"in I)return Q.scheduler.failPublish(w,$,I.error),{success:!1};return Q.scheduler.completePublish(w,$,I.result),Q.logger.debug(`Direct publish completed: ${$}`,{entityType:w}),{success:!0}}catch(I){let D=y0(I);return Q.logger.error(`Failed direct publish request: ${D}`),{success:!1}}}async function pRQ(A,Q){let{entityType:B,entityId:w}=Q;try{return await A.queueManager.remove(B,w),A.logger.debug(`Entity removed from queue: ${w}`,{entityType:B}),{success:!0}}catch($){let f=y0($);return A.logger.error(`Failed to remove entity: ${f}`),{success:!1}}}async function iRQ(A,Q){let{entityType:B,entityId:w,position:$}=Q;try{return await A.queueManager.reorder(B,w,$),A.logger.debug(`Entity reordered: ${w}`,{entityType:B,newPosition:$}),{success:!0}}catch(f){let I=y0(f);return A.logger.error(`Failed to reorder entity: ${I}`),{success:!1}}}async function rRQ(A,Q,B){let{entityType:w}=B;try{let $=await Q.queueManager.list(w);return await A.messaging.send({type:l4.LIST_RESPONSE,payload:{entityType:w,queue:$.map((f)=>({entityId:f.entityId,position:f.position,queuedAt:f.queuedAt}))}}),{success:!0}}catch($){let f=y0($);return Q.logger.error(`Failed to list queue: ${f}`),{success:!1}}}async function dRQ(A,Q){let{entityType:B,entityId:w,result:$}=Q;return A.scheduler.completePublish(B,w,$),A.logger.info(`Publish reported success: ${w}`,{entityType:B}),{success:!0}}async function nRQ(A,Q){let{entityType:B,entityId:w,error:$}=Q;A.scheduler.failPublish(B,w,$);let f=A.retryTracker.getRetryInfo(w);return A.logger.info(`Publish reported failure: ${w}`,{entityType:B,error:$,retryCount:f?.retryCount}),{success:!0}}async function oRQ(A,Q){let{entityType:B,entityId:w}=Q;return A.scheduler.completeGeneration(B,w),A.logger.info("Generation completed",{entityType:B,entityId:w}),{success:!0}}async function sRQ(A,Q){let{entityType:B,error:w}=Q;return A.scheduler.failGeneration(B,w),A.logger.warn("Generation failed",{entityType:B,error:w}),{success:!0}}WA();async function oz1(A,Q,B,w){try{if(w.skipIfDraftExists!==!1){if((await A.listEntities({entityType:B,options:{filter:{metadata:{status:"draft"}},limit:1}})).length>0)return{shouldGenerate:!1,reason:"Draft already exists"}}if(w.maxUnpublishedDrafts!==void 0){let $=await A.listEntities({entityType:B,options:{filter:{metadata:{status:"draft"}},limit:w.maxUnpublishedDrafts+1}});if($.length>=w.maxUnpublishedDrafts)return{shouldGenerate:!1,reason:`Max unpublished drafts reached (${$.length}/${w.maxUnpublishedDrafts})`}}if(w.minSourceEntities!==void 0&&w.sourceEntityType){let $=await A.listEntities({entityType:w.sourceEntityType,options:{publishedOnly:!0,limit:w.minSourceEntities}});if($.length<w.minSourceEntities)return{shouldGenerate:!1,reason:`Not enough source entities (${$.length}/${w.minSourceEntities} ${w.sourceEntityType})`}}return{shouldGenerate:!0}}catch($){return Q.error("Failed to check generation conditions",{entityType:B,error:y0($)}),{shouldGenerate:!1,reason:`Condition check failed: ${y0($)}`}}}function sz1(A){let{context:Q,config:B,queueManager:w,providerRegistry:$,retryTracker:f,publishExecutor:I,logger:D}=A,U=aRQ(Q);return FX.createFresh({queueManager:w,providerRegistry:$,retryTracker:f,logger:D,backend:new c$A,...B.entitySchedules&&{entitySchedules:B.entitySchedules},...B.generationSchedules&&{generationSchedules:B.generationSchedules},...B.generationConditions&&{generationConditions:B.generationConditions},messageBus:U,publishExecutor:I,onCheckGenerationConditions:(Y,J)=>oz1(Q.entityService,D,Y,J)})}function aRQ(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 az1(A,Q,B){let w=A.getEntityTypes();for(let f of w){let I=await A.listEntities({entityType:f,options:{filter:{metadata:{status:"queued"}}}});for(let D of I)await Q.add(D.entityType,D.id)}let $=0;for(let f of w){let I=await Q.list(f);$+=I.length}if($>0)B.info(`Rebuilt queue with ${$} queued entities`)}var tRQ=["draft","queued","published","failed"];async function tz1(A,Q){await A.messaging.send({type:"dashboard:register-widget",payload:{id:"publication-pipeline",pluginId:Q,title:"Publication Pipeline",section:"secondary",priority:100,rendererName:"PipelineWidget",visibility:"anchor",dataProvider:()=>eRQ(A)}})}async function eRQ(A){let Q=A.entityService.getEntityTypes(),B=[],w={draft:0,queued:0,published:0,failed:0};for(let $ of Q){let f=await A.entityService.listEntities({entityType:$});for(let I of f){let D=AbQ(I.metadata.status);if(!D)continue;w[D]++,B.push({id:I.id,title:QbQ(I.id,I.metadata.title),type:$,status:D})}}return{summary:w,items:B}}function AbQ(A){return tRQ.find((Q)=>Q===A)}function QbQ(A,Q){return typeof Q==="string"?Q:A}var ez1={name:"@brains/content-pipeline",private:!0,version:"0.2.0-alpha.127",description:"Content pipeline plugin for managing entity publishing queues, scheduling, and generation",type:"module",main:"src/index.ts",types:"src/index.ts",scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",croner:"^9.1.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",typescript:"^5.3.3"},exports:{".":{types:"./src/index.ts",default:"./src/index.ts"}},files:["src"]};class YmA extends YB{pluginContext;queueManager;providerRegistry;retryTracker;publishExecutor;publishAssetRegistry;publishAssetPreflight;scheduler;constructor(A){super("content-pipeline",ez1,A??{},jz1)}async onRegister(A){this.pluginContext=A,this.queueManager=mH.createFresh(),this.providerRegistry=uH.createFresh(),this.retryTracker=cH.createFresh(),this.publishAssetRegistry=lH.createFresh(),this.publishAssetPreflight=new p$A({context:A,registry:this.publishAssetRegistry}),this.publishExecutor=new iv({context:A,providerRegistry:this.providerRegistry,publishAssetPreflight:this.publishAssetPreflight}),this.scheduler=sz1({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,publishExecutor:this.publishExecutor,logger:this.logger}),nz1(A,{queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,publishExecutor:this.publishExecutor,publishAssetRegistry:this.publishAssetRegistry,publishAssetPreflight:this.publishAssetPreflight,scheduler:this.scheduler,logger:this.logger})}async onReady(A){await az1(A.entityService,this.queueManager,this.logger),await tz1(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[i$A(this.pluginContext,this.id,this.queueManager),d$A(this.pluginContext,this.id,this.providerRegistry,this.publishExecutor),n$A(this.pluginContext,this.id,this.publishAssetRegistry,this.publishAssetPreflight)]}async getInstructions(){return'## Publishing\n- Use `content-pipeline_queue` to manage the publish queue \u2014 list queued items, add entities to the queue, remove them, or reorder.\n- Use `content-pipeline_publish` to publish an entity directly to its platform (e.g. LinkedIn, Buttondown). This tool has its own confirmation flow; call it without `confirmed` when the user asks to publish instead of asking for plain-text confirmation.\n- Use `content-pipeline_ensure-assets` to reconcile missing publish assets such as generated OG images for already-published content.\n- When users ask about their "publish queue", "publishing queue", or "what\'s queued", use `content-pipeline_queue`.'}getQueueManager(){return this.queueManager}getProviderRegistry(){return this.providerRegistry}getRetryTracker(){return this.retryTracker}getPublishAssetRegistry(){return this.publishAssetRegistry}getScheduler(){return this.scheduler}async onShutdown(){await this.scheduler.stop(),mH.resetInstance(),uH.resetInstance(),cH.resetInstance(),lH.resetInstance()}}function JmA(A){return new YmA(A)}aA();WA();var Aq1=H.object({accountId:H.string().describe("Cloudflare account ID"),apiToken:H.string().describe("Cloudflare API token with Analytics:Read permission"),siteTag:H.string().describe("Cloudflare Web Analytics site tag")}),XmA=H.object({cloudflare:Aq1.optional()});aA();WA();var wbQ=H.object({date:H.string().describe("Single date in YYYY-MM-DD format").optional(),days:H.number().min(1).max(365).describe("Number of days back from yesterday (e.g., 7 for last week)").optional(),startDate:H.string().describe("Start date in YYYY-MM-DD format (use with endDate)").optional(),endDate:H.string().describe("End date in YYYY-MM-DD format (use with startDate)").optional(),limit:H.number().min(1).max(100).default(20).describe("Maximum items for breakdowns (pages, referrers, countries)")});function $bQ(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 Qq1(A,Q,B){let w=[];if(!B)return w;return w.push(oQ(A,"query",`Query website analytics from Cloudflare.
|
|
6531
6531
|
|
|
6532
6532
|
Date range options (use only one):
|
|
6533
6533
|
- No params: yesterday only
|
|
@@ -6665,7 +6665,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,wbQ,
|
|
|
6665
6665
|
}
|
|
6666
6666
|
}
|
|
6667
6667
|
}
|
|
6668
|
-
`,variables:B})});if(!w.ok){let I=await w.text();throw Error(`Cloudflare API error: ${w.status} - ${I}`)}let $=await w.json();if($.errors&&$.errors.length>0)throw Error(`Cloudflare GraphQL error: ${$.errors.map((I)=>I.message).join(", ")}`);return($.data.viewer.accounts[0]?.rumPageloadEventsAdaptiveGroups??[]).map((I)=>({country:I.dimensions.countryName,visits:I.sum.visits}))}}WA();var HmA=7,fbQ=10;function wq1(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=wR(),B=Do(HmA),w=DN(B),$=DN(Q);try{let[f,I]=await Promise.all([A.getWebsiteStats({startDate:w,endDate:$}),A.getTopPages({startDate:w,endDate:$,limit:fbQ})]);return{days:HmA,startDate:w,endDate:$,pageviews:f.pageviews,visitors:f.visitors,topPages:I}}catch(f){return{error:f instanceof Error?f.message:"Failed to fetch analytics",days:HmA}}}}var $q1={name:"@brains/analytics",private:!0,version:"0.2.0-alpha.
|
|
6668
|
+
`,variables:B})});if(!w.ok){let I=await w.text();throw Error(`Cloudflare API error: ${w.status} - ${I}`)}let $=await w.json();if($.errors&&$.errors.length>0)throw Error(`Cloudflare GraphQL error: ${$.errors.map((I)=>I.message).join(", ")}`);return($.data.viewer.accounts[0]?.rumPageloadEventsAdaptiveGroups??[]).map((I)=>({country:I.dimensions.countryName,visits:I.sum.visits}))}}WA();var HmA=7,fbQ=10;function wq1(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=wR(),B=Do(HmA),w=DN(B),$=DN(Q);try{let[f,I]=await Promise.all([A.getWebsiteStats({startDate:w,endDate:$}),A.getTopPages({startDate:w,endDate:$,limit:fbQ})]);return{days:HmA,startDate:w,endDate:$,pageviews:f.pageviews,visitors:f.visitors,topPages:I}}catch(f){return{error:f instanceof Error?f.message:"Failed to fetch analytics",days:HmA}}}}var $q1={name:"@brains/analytics",private:!0,version:"0.2.0-alpha.127",description:"Analytics plugin for collecting website and social media metrics",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class fq1 extends YB{cloudflareClient;constructor(A={}){super("analytics",$q1,A,XmA)}async onRegister(A){this.cloudflareClient=this.config.cloudflare?new WmA(this.config.cloudflare):void 0,A.insights.register("traffic-overview",wq1(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:Bq1(Q)}})}async getTools(){return Qq1(this.id,this.getContext(),this.cloudflareClient)}}function DbQ(A={}){return new fq1(A)}var o$A=DbQ;import{randomBytes as HbQ}from"crypto";aA();WA();J8();var UbQ=new Set(["description","excerpt","summary","tagline","story"]);function YbQ(A){if(A.endsWith("s"))return A;return LI(A)}function GmA(A,Q=!1,B){let w=A._def.typeName;if(w==="ZodOptional"||w==="ZodNullable")return GmA(A._def.innerType,!0,B);if(w==="ZodDefault")return GmA(A._def.innerType,Q,A._def.defaultValue());return{inner:A,isOptional:Q,defaultValue:B}}function KmA(A,Q){let{inner:B,isOptional:w,defaultValue:$}=GmA(Q),f=B._def.typeName,I={name:A,label:aX(A),widget:"string",...w&&{required:!1},...$!==void 0&&{default:$}};switch(f){case"ZodString":{if((B._def.checks??[]).some((U)=>U.kind==="datetime"))return{...I,widget:"datetime"};if(UbQ.has(A))return{...I,widget:"text"};return{...I,widget:"string"}}case"ZodNumber":return{...I,widget:"number"};case"ZodBoolean":return{...I,widget:"boolean"};case"ZodEnum":{let D=B._def.values;return{...I,widget:"select",options:D}}case"ZodArray":{let D=B._def.type,U=KmA("item",D);if(U.widget==="object"&&U.fields)return{...I,widget:"list",fields:U.fields};return{...I,widget:"list",field:{name:A,label:aX(A),widget:U.widget}}}case"ZodObject":{let D=B.shape,U=Object.entries(D).map(([Y,J])=>KmA(Y,J));return{...I,widget:"object",fields:U}}default:return{...I,widget:"string"}}}function Iq1(A,Q){let B=Object.entries(A.shape).map(([w,$])=>KmA(w,$));if(Q)B.push({name:"body",label:"Body",widget:"markdown"});return B}function Dq1(A){let Q=[],B=[];for(let w of A.entityTypes){let $=A.getFrontmatterSchema(w);if(!$)continue;let f=A.getAdapter(w),I=f?.hasBody!==!1,D=A.entityDisplay?.[w],U=w===Ds?"Note":aX(w),Y=D?.label??U,J=D?.pluralName??YbQ(Y);if(f?.isSingleton){B.push({name:w,label:Y,file:`${w}/${w}.md`,fields:Iq1($,I)});continue}if(w===Ds){Q.push({name:w,label:J,folder:".",create:!0,extension:"md",format:"raw",fields:[{name:"body",label:"Body",widget:"markdown"}]});continue}Q.push({name:w,label:J,folder:w,create:!0,extension:"md",format:"frontmatter",fields:Iq1($,I)})}if(B.length>0)Q.push({name:"settings",label:"Settings",files:B});return{backend:{name:"github",repo:A.repo,branch:A.branch,...A.baseUrl&&{base_url:A.baseUrl},...A.authEndpoint&&{auth_endpoint:A.authEndpoint}},media_folder:"image",public_folder:"/images",collections:Q}}var JbQ=new RegExp("[<>&\\u2028\\u2029]","g");function rv(A){return JSON.stringify(A).replace(JbQ,(Q)=>`\\u${Q.charCodeAt(0).toString(16).padStart(4,"0")}`)}var Uq1="https://unpkg.com/@sveltia/cms@0.165.1/dist/sveltia-cms.js";function s$A(A){let Q=`<script src="${Uq1}"></script>`;return`<!doctype html>
|
|
6669
6669
|
<html>
|
|
6670
6670
|
<head>
|
|
6671
6671
|
<meta charset="utf-8" />
|
|
@@ -6704,7 +6704,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,wbQ,
|
|
|
6704
6704
|
showError(error instanceof Error ? error.message : String(error));
|
|
6705
6705
|
}
|
|
6706
6706
|
})();
|
|
6707
|
-
`}WA();var Yq1={name:"@brains/cms",private:!0,version:"0.2.0-alpha.
|
|
6707
|
+
`}WA();var Yq1={name:"@brains/cms",private:!0,version:"0.2.0-alpha.127",description:"CMS plugin for config and browser authoring routes",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/auth-service":"workspace:*","@brains/cms-config":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var ZmA="brains_cms_oauth_state",GbQ=600,KbQ="auth",FbQ=H.object({label:H.string().optional(),pluralName:H.string().optional()}).passthrough(),ZbQ=H.object({clientId:H.string().optional(),clientSecret:H.string().optional(),scope:H.string().optional()}),NbQ=H.object({contentRepoToken:H.string().optional()}),zbQ=H.object({entityDisplay:H.record(FbQ).optional(),routePath:H.string().default("/cms"),githubOAuth:ZbQ.optional(),passkeyLogin:NbQ.optional()}).refine((A)=>{let Q=Boolean(CC(A.githubOAuth?.clientId)&&CC(A.githubOAuth?.clientSecret)),B=Boolean(CC(A.passkeyLogin?.contentRepoToken));return!(Q&&B)},{message:"CMS login supports a single method per brain: configure githubOAuth or passkeyLogin, not both."});function qbQ(A){return`${A.endsWith("/")?A:`${A}/`}config.yml`}function CC(A){if(!A)return;let Q=A.trim();return Q.length>0?Q:void 0}function LbQ(A){let Q=CC(A.githubOAuth?.clientId),B=CC(A.githubOAuth?.clientSecret),w=CC(A.passkeyLogin?.contentRepoToken);return{...Q&&B?{githubOAuth:{clientId:Q,clientSecret:B,scope:CC(A.githubOAuth?.scope)??"repo"}}:{},...w?{passkeyLogin:{contentRepoToken:w}}:{}}}function VbQ(A){return Boolean(A.githubOAuth??A.passkeyLogin)}function EbQ(A,Q,B){let w=A.entityDisplay??B?.entityDisplay;return{...w?{entityDisplay:w}:{},...VbQ(Q)?{authEndpoint:KbQ}:{}}}async function MbQ(A){let Q=await A.messaging.send({type:"git-sync:get-repo-info",payload:{}});if("noop"in Q||!Q.success||!Q.data)throw Error("CMS config unavailable: git-sync repo info unavailable");let{repo:B,branch:w}=Q.data;if(!B||!w)throw Error("CMS config unavailable: git-sync repo info incomplete");return{repo:B,branch:w}}async function CbQ(A,Q={}){let{repo:B,branch:w}=await MbQ(A);return Dq1({repo:B,branch:w,...Q.baseUrl&&{baseUrl:Q.baseUrl},...Q.authEndpoint&&{authEndpoint:Q.authEndpoint},entityTypes:A.entityService.getEntityTypes(),getFrontmatterSchema:($)=>A.entities.getEffectiveFrontmatterSchema($),getAdapter:($)=>A.entities.getAdapter($),...Q.entityDisplay&&{entityDisplay:Q.entityDisplay}})}async function Wq1(A,Q={}){return sX(await CbQ(A,Q))}class NmA extends YB{constructor(A={}){super("cms",Yq1,A,zbQ)}async onRegister(A){await super.onRegister(A),A.endpoints.register({label:"CMS",url:this.config.routePath,priority:40,visibility:"anchor"}),A.interactions.register({id:"cms",label:"CMS",description:"Edit and manage content through the browser CMS.",href:this.config.routePath,kind:"admin",priority:40,visibility:"anchor"})}getWebRoutes(){let A=qbQ(this.config.routePath),Q=LbQ(this.config),B=[];if(Q.githubOAuth||Q.passkeyLogin)B.push({path:"/auth",method:"GET",public:!0,handler:async(w)=>this.handleAuth(w,Q)});if(Q.githubOAuth){let w=Q.githubOAuth;B.push({path:"/auth/callback",method:"GET",public:!0,handler:async($)=>this.handleGitHubCallback($,w)})}if(Q.passkeyLogin){let w=Q.passkeyLogin;B.push({path:"/auth/cms-token",method:"POST",public:!0,handler:async($)=>this.handleCmsToken($,w)})}return[{path:this.config.routePath,method:"GET",public:!0,handler:async(w)=>{if(Q.passkeyLogin){if(!await Xq1(w))return new Response(null,{status:302,headers:{Location:`/login?return_to=${encodeURIComponent(this.config.routePath)}`,"Cache-Control":"no-store"}});return fr(s$A({cmsConfigPath:A,authTokenEndpoint:"/auth/cms-token"}))}return fr(s$A({cmsConfigPath:A}))}},{path:A,method:"GET",public:!0,handler:async(w)=>{try{let $=EbQ(this.config,Q,this.getContext()),f=await Wq1(this.getContext(),{...$,...$.authEndpoint?{baseUrl:$r(this.getContext(),w)}:{}});return new Response(f,{headers:{"Content-Type":"application/yaml; charset=utf-8"}})}catch($){return new Response($ instanceof Error?$.message:"CMS unavailable",{status:503,headers:{"Content-Type":"text/plain; charset=utf-8"}})}}},...B]}async handleAuth(A,Q){if(Q.githubOAuth)return this.redirectToGitHub(A,Q.githubOAuth);if(Q.passkeyLogin){let B=await Xq1(A)?_bQ:jbQ;return fr(B($r(this.getContext(),A)))}return kbQ("CMS login is not enabled",404)}redirectToGitHub(A,Q){let B=HbQ(32).toString("base64url"),w=`${$r(this.getContext(),A)}/auth/callback`,$=new URL("https://github.com/login/oauth/authorize");return $.searchParams.set("client_id",Q.clientId),$.searchParams.set("redirect_uri",w),$.searchParams.set("scope",Q.scope),$.searchParams.set("state",B),new Response(null,{status:302,headers:{Location:$.toString(),"Set-Cookie":bbQ(B,A),"Cache-Control":"no-store"}})}async handleGitHubCallback(A,Q){let B=new URL(A.url),w=B.searchParams.get("error");if(w){let Y=B.searchParams.get("error_description")??w;return a$A(`GitHub OAuth failed: ${Y}`)}let $=B.searchParams.get("state"),f=PbQ(A.headers.get("cookie"),ZmA);if(!$||!f||$!==f)return a$A("GitHub OAuth state did not match");let I=B.searchParams.get("code");if(!I)return a$A("GitHub OAuth callback did not include a code");let D=`${$r(this.getContext(),A)}/auth/callback`,U=await ObQ(Q,I,D);if(!U.success)return a$A(U.error);return fr(vbQ(U.token,$r(this.getContext(),A)),200,{"Set-Cookie":Gq1()})}async handleCmsToken(A,Q){if(!await yU()?.getOperatorSession(A))return Jq1({error:"Operator session required"},401);return Jq1({token:Q.contentRepoToken,provider:"github"},200,{"Cache-Control":"no-store"})}}function OC(A){return new NmA(A)}async function ObQ(A,Q,B){let w=new URLSearchParams({client_id:A.clientId,client_secret:A.clientSecret,code:Q,redirect_uri:B}),$=await fetch("https://github.com/login/oauth/access_token",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/x-www-form-urlencoded"},body:w}),f;try{f=await $.json()}catch{return{success:!1,error:"GitHub token response was not JSON"}}if(!$.ok)return{success:!1,error:RbQ(f)??"GitHub token exchange failed"};if(FmA(f)&&typeof f.error==="string")return{success:!1,error:typeof f.error_description==="string"?f.error_description:f.error};let I=FmA(f)?f.access_token:void 0;if(typeof I!=="string"||I.length===0)return{success:!1,error:"GitHub token response omitted token"};return{success:!0,token:I}}function RbQ(A){if(!FmA(A))return;if(typeof A.error_description==="string")return A.error_description;return typeof A.error==="string"?A.error:void 0}function FmA(A){return Boolean(A&&typeof A==="object"&&!Array.isArray(A))}function $r(A,Q){let B=new URL(Q.url).origin;if(Hq1(B))return B;return A.siteUrl??B}function Hq1(A){let{hostname:Q}=new URL(A);return Q==="localhost"||Q==="127.0.0.1"||Q==="::1"||Q==="[::1]"}function bbQ(A,Q){let B=Hq1(new URL(Q.url).origin)?"":"; Secure";return`${ZmA}=${A}; Path=/auth; HttpOnly; SameSite=Lax; Max-Age=${GbQ}${B}`}function Gq1(){return`${ZmA}=; Path=/auth; HttpOnly; SameSite=Lax; Max-Age=0`}function PbQ(A,Q){if(!A)return;for(let B of A.split(";")){let[w,...$]=B.trim().split("=");if(w===Q)return $.join("=")}return}function fr(A,Q=200,B={}){return new Response(A,{status:Q,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store",...B}})}function kbQ(A,Q=200){return new Response(A,{status:Q,headers:{"Content-Type":"text/plain; charset=utf-8","Cache-Control":"no-store"}})}function Jq1(A,Q=200,B={}){return new Response(JSON.stringify(A),{status:Q,headers:{"Content-Type":"application/json; charset=utf-8","Cache-Control":"no-store",...B}})}function a$A(A){return fr(`<!doctype html><html><body><h1>CMS login failed</h1><p>${xbQ(A)}</p></body></html>`,400,{"Set-Cookie":Gq1()})}async function Xq1(A){return Boolean(await yU()?.getOperatorSession(A))}function jbQ(A){return`<!doctype html>
|
|
6708
6708
|
<html lang="en">
|
|
6709
6709
|
<head>
|
|
6710
6710
|
<meta charset="utf-8" />
|
|
@@ -8109,7 +8109,7 @@ ${Fq1}`;import{jsxDEV as ZX,Fragment as zq1}from"preact/jsx-dev-runtime";functio
|
|
|
8109
8109
|
}
|
|
8110
8110
|
});
|
|
8111
8111
|
})();`;function ZPQ({input:A}){let Q=A.appInfo.entities,B=A.appInfo.entityCounts,w=GPQ(A.widgets),$=Boolean(A.character.role)||Boolean(A.character.purpose)||A.character.values.length>0,f=A.appInfo.interactions,I=`layout${$?" has-identity":""}`,D=A.operatorAccess&&!A.operatorAccess.isOperator&&A.operatorAccess.hiddenWidgetCount>0,U=new Date;return HB("html",{lang:"en","data-theme":"dark",children:[HB("head",{children:[HB("meta",{charSet:"utf-8"},void 0,!1,void 0,this),HB("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"},void 0,!1,void 0,this),HB("title",{children:A.title},void 0,!1,void 0,this),HB("link",{rel:"preconnect",href:"https://fonts.googleapis.com"},void 0,!1,void 0,this),HB("link",{rel:"preconnect",href:"https://fonts.gstatic.com",crossOrigin:"anonymous"},void 0,!1,void 0,this),HB("link",{href:HPQ,rel:"stylesheet"},void 0,!1,void 0,this),A.themeCSS!==void 0&&HB("style",{"data-dashboard-theme":!0,dangerouslySetInnerHTML:{__html:A.themeCSS}},void 0,!1,void 0,this),HB("style",{"data-dashboard-styles":!0,dangerouslySetInnerHTML:{__html:Nq1}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),HB("body",{children:[HB("main",{class:"console","data-component":"dashboard:dashboard",children:[HB(qq1,{title:A.title,tagline:A.profile.description,operatorAccess:A.operatorAccess},void 0,!1,void 0,this),HB("section",{class:I,children:[$&&HB("div",{class:"identity-column",children:[HB(Vq1,{character:A.character},void 0,!1,void 0,this),HB(VmA,{interactions:f,baseUrl:A.baseUrl},void 0,!1,void 0,this),D&&A.operatorAccess&&HB(Pq1,{hiddenWidgetCount:A.operatorAccess.hiddenWidgetCount,loginUrl:A.operatorAccess.loginUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),HB("div",{class:"main-column",children:[HB(Lq1,{total:Q,entityCounts:B},void 0,!1,void 0,this),!$&&D&&A.operatorAccess&&HB(Pq1,{hiddenWidgetCount:A.operatorAccess.hiddenWidgetCount,loginUrl:A.operatorAccess.loginUrl},void 0,!1,void 0,this),w.primary.map((Y)=>HB(Q9A,{widget:Y},`${Y.widget.pluginId}:${Y.widget.id}`,!1,void 0,this)),w.secondary.map((Y)=>HB(Q9A,{widget:Y},`${Y.widget.pluginId}:${Y.widget.id}`,!1,void 0,this))]},void 0,!0,void 0,this),HB("div",{class:"sidebar-column",children:[!$&&HB(VmA,{interactions:f,baseUrl:A.baseUrl},void 0,!1,void 0,this),w.sidebar.map((Y)=>HB(Q9A,{widget:Y},`${Y.widget.pluginId}:${Y.widget.id}`,!1,void 0,this)),HB(Eq1,{endpoints:A.appInfo.endpoints,baseUrl:A.baseUrl},void 0,!1,void 0,this),HB(Rq1,{appInfo:A.appInfo,now:U},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),HB(bq1,{title:A.title,appInfo:A.appInfo,baseUrl:A.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),HB("script",{dangerouslySetInnerHTML:{__html:KPQ}},void 0,!1,void 0,this),HB("script",{dangerouslySetInnerHTML:{__html:FPQ}},void 0,!1,void 0,this),A.widgetScripts.map((Y,J)=>HB("script",{dangerouslySetInnerHTML:{__html:Y}},`widget-script:${J}`,!1,void 0,this))]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function kq1(A){return`<!doctype html>
|
|
8112
|
-
${WPQ(HB(ZPQ,{input:A},void 0,!1,void 0,this))}`}function jq1(A,Q){let B={},w=new Set;for(let[$,f]of Object.entries(A)){let I=Q?.get(f.widget.pluginId,f.widget.id);if(B[$]={...f,...I?.component?{component:I.component}:{}},I?.clientScript)w.add(I.clientScript)}return{widgets:B,widgetScripts:Array.from(w)}}var _q1={name:"@brains/dashboard",private:!0,version:"0.2.0-alpha.
|
|
8112
|
+
${WPQ(HB(ZPQ,{input:A},void 0,!1,void 0,this))}`}function jq1(A,Q){let B={},w=new Set;for(let[$,f]of Object.entries(A)){let I=Q?.get(f.widget.pluginId,f.widget.id);if(B[$]={...f,...I?.component?{component:I.component}:{}},I?.clientScript)w.add(I.clientScript)}return{widgets:B,widgetScripts:Array.from(w)}}var _q1={name:"@brains/dashboard",private:!0,version:"0.2.0-alpha.127",description:"Dashboard plugin with extensible widget system",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/auth-service":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2","preact-render-to-string":"^6.3.1"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var zPQ=H.object({version:H.string().default("1.0.0"),routePath:H.string().default("/dashboard"),themeCSS:H.string().optional()}),qPQ=H.object({id:H.string(),pluginId:H.string(),title:H.string(),description:H.string().optional(),priority:H.number().default(50),section:H.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:H.string(),visibility:W4.default("public"),component:H.custom().optional(),clientScript:H.string().optional(),dataProvider:H.function().returns(H.promise(H.unknown()))}).superRefine((A,Q)=>{if(!LmA(A.rendererName)&&!A.component)Q.addIssue({code:H.ZodIssueCode.custom,message:"Custom dashboard widgets must register a Preact component.",path:["component"]})}),LPQ=H.object({pluginId:H.string(),widgetId:H.string().optional()});function VPQ(A){return{id:A.id,pluginId:A.pluginId,title:A.title,...A.description?{description:A.description}:{},priority:A.priority,section:A.section,rendererName:A.rendererName,visibility:A.visibility,...A.component?{component:A.component}:{},...A.clientScript?{clientScript:A.clientScript}:{},dataProvider:A.dataProvider}}class MmA extends YB{widgetRegistry=null;datasource=null;siteUrl;ctx;constructor(A){super("dashboard",_q1,A??{},zPQ)}async onRegister(A){this.siteUrl=A.siteUrl,this.ctx=A,this.widgetRegistry=new e$A(this.logger),this.datasource=new A9A(this.widgetRegistry,this.logger),A.entities.registerDataSource(this.datasource),A.endpoints.register({label:"Dashboard",url:this.config.routePath,priority:30,visibility:"public"}),A.interactions.register({id:"dashboard",label:"Dashboard",description:"Inspect runtime status, endpoints, and dashboard widgets.",href:this.config.routePath,kind:"admin",priority:30,visibility:"public"}),A.messaging.subscribe("dashboard:register-widget",async(Q)=>{try{let B=qPQ.parse(Q.payload),w=VPQ(B);return this.widgetRegistry?.register(w),this.logger.debug("Widget registered via messaging",{widgetId:B.id,pluginId:B.pluginId,rendererName:B.rendererName,builtIn:t$A.includes(B.rendererName)}),{success:!0}}catch(B){return this.logger.error("Failed to register widget",{error:y0(B),payload:Q.payload}),{success:!1,error:"Widget registration failed"}}}),A.messaging.subscribe("dashboard:unregister-widget",async(Q)=>{let B=LPQ.parse(Q.payload);return this.widgetRegistry?.unregister(B.pluginId,B.widgetId),this.logger.debug("Widget unregistered via messaging",{pluginId:B.pluginId,widgetId:B.widgetId}),{success:!0}}),this.logger.info("Dashboard plugin registered")}getWebRoutes(){return[{path:this.config.routePath,method:"GET",public:!0,handler:async(A)=>{if(!this.datasource||!this.ctx)return new Response("Dashboard unavailable",{status:503,headers:{"Content-Type":"text/plain; charset=utf-8"}});let Q=this.ctx,B=await yU()?.getOperatorSession(A),w=Boolean(B),$=w?"anchor":"public",f=this.widgetRegistry?.list({permissionLevel:"anchor"})??[],I=f.filter((S)=>W$.hasPermission($,S.visibility)),D=f.length-I.length,[U,Y]=await Promise.all([this.datasource.getDashboardData({permissionLevel:$,widgets:I}),Q.appInfo()]),J=Q.identity.get(),X=Q.identity.getProfile(),G=this.siteUrl??(()=>{try{return new URL(A.url).origin}catch{return}})(),Z={...Y,endpoints:Y.endpoints.filter((S)=>W$.hasPermission($,S.visibility)),interactions:Y.interactions.filter((S)=>W$.hasPermission($,S.visibility))},N=X.name||Y.model||"Brain Dashboard",V=new URL(A.url),L=`${V.pathname}${V.search}`,M=encodeURIComponent(L),O=jq1(U.widgets,this.widgetRegistry),E={title:N,baseUrl:G,widgets:O.widgets,widgetScripts:O.widgetScripts,character:J,profile:X,appInfo:Z,...this.config.themeCSS!==void 0&&{themeCSS:this.config.themeCSS},operatorAccess:{isOperator:w,hiddenWidgetCount:D,loginUrl:`/login?return_to=${M}`,logoutUrl:`/logout?return_to=${M}`}};return new Response(kq1(E),{headers:{"Content-Type":"text/html; charset=utf-8"}})}}]}async getTools(){return[]}getWidgetRegistry(){return this.widgetRegistry}}function fq(A){return new MmA(A)}aA();WA();var EPQ=H.object({id:H.string(),pluginId:H.string(),title:H.string(),description:H.string().optional(),priority:H.number(),section:H.enum(["primary","secondary","sidebar"]),rendererName:H.string(),visibility:W4,component:H.custom().optional()}),MPQ=H.object({widget:EPQ,data:H.unknown()}),CPQ=H.object({widgets:H.record(MPQ)});WA();aA();WA();import{h as hPQ}from"preact";WA();JU();aA();var dv=H.enum(["generating","draft","queued","published","failed"]),Dr=H.object({subject:H.string(),status:dv,entityIds:H.array(H.string()).optional(),scheduledFor:H.string().datetime().optional(),sentAt:H.string().datetime().optional(),buttondownId:H.string().optional(),sourceEntityType:H.string().optional()}),vq1=Dr.pick({subject:!0,status:!0,entityIds:!0,scheduledFor:!0,sentAt:!0,buttondownId:!0,sourceEntityType:!0}).extend({error:H.string().optional()}),Ur=A2.extend({entityType:H.literal("newsletter"),metadata:vq1});aA();class yq1 extends q2{constructor(){super({entityType:"newsletter",schema:Ur,frontmatterSchema:Dr})}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 Tq1=new yq1;aA();aA();WA();var OPQ=UW.extend({status:H.enum(["generating","draft","queued","published","failed"]).optional()}),RPQ=YW.extend({query:OPQ.optional()});function xq1(A){try{let{content:Q}=b2(A.content,Dr);return Q}catch{return A.content}}class CmA extends u5{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=RPQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){let Q=xq1(A),B={id:A.id,subject:A.metadata.subject,status:A.metadata.status,excerpt:K7(Q,150),created:A.created,url:`/newsletters/${A.id}`};if(A.metadata.sentAt)B.sentAt=A.metadata.sentAt;return B}buildListResult(A,Q,B){return{newsletters:A,totalCount:Q?.totalItems??A.length,pagination:Q}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A),$=B.entityService;if(w.id)return this.fetchSingleNewsletter(w.id,Q,$);let f=w.status,I=f?{filter:{metadata:{status:f}}}:void 0,{items:D,pagination:U}=await this.fetchList(w,$,I);return Q.parse(this.buildListResult(D,U,w))}async fetchSingleNewsletter(A,Q,B){let w=await B.getEntity({entityType:this.config.entityType,id:A});if(!w)throw Error(`Newsletter not found: ${A}`);let $=await this.resolveNavigation(w,B),f=[];if(w.metadata.entityIds?.length){let U=w.metadata.sourceEntityType??"post";f=(await Promise.all(w.metadata.entityIds.map(async(J)=>{let X=await B.getEntity({entityType:U,id:J});if(X){let G=X.metadata;return{id:J,title:G.title??J,url:`/${U}s/${G.slug??J}`}}return null}))).filter((J)=>J!==null)}let I=xq1(w),D={id:w.id,subject:w.metadata.subject,status:w.metadata.status,content:I,created:w.created,updated:w.updated,sentAt:w.metadata.sentAt,scheduledFor:w.metadata.scheduledFor,newsletter:w,prevNewsletter:$.prev?{id:$.prev.id,subject:$.prev.subject,url:$.prev.url}:null,nextNewsletter:$.next?{id:$.next.id,subject:$.next.subject,url:$.next.url}:null,sourceEntities:f.length>0?f:void 0};return Q.parse(D)}}aA();WA();var bPQ=H.object({prompt:H.string().optional().describe("AI generation prompt"),sourceEntityIds:H.array(H.string()).optional().describe("Entity IDs to include in newsletter (e.g., blog posts)"),sourceEntityType:H.enum(["post"]).optional().describe("Type of source entities"),content:H.string().optional().describe("Direct content (skip AI)"),subject:H.string().optional().describe("Newsletter subject (AI-generated if not provided)"),addToQueue:H.boolean().optional().describe("Create as queued (true) or draft (false)")});class OmA extends L7{constructor(A,Q){super(A,Q,{schema:bPQ,jobTypeName:"newsletter:generation",entityType:"newsletter"})}async generate(A,Q){let B=A.addToQueue??!1,{prompt:w,sourceEntityIds:$,sourceEntityType:f}=A,{content:I,subject:D}=A;if(I){if(!D)this.failEarly("Subject is required when providing content directly");await this.reportProgress(Q,{progress:50,message:"Using provided content"})}else if($&&$.length>0){let G=f??"post";await this.reportProgress(Q,{progress:10,message:`Fetching ${$.length} source entities`});let N=(await Promise.all($.map((E)=>this.context.entityService.getEntity({entityType:G,id:E})))).filter((E)=>E!=null);if(N.length===0)this.failEarly(`No source entities found for IDs: ${$.join(", ")}`);await this.reportProgress(Q,{progress:30,message:`Generating newsletter from ${N.length} posts`});let L=`Create an engaging newsletter that highlights these blog posts:
|
|
8113
8113
|
|
|
8114
8114
|
${N.map((E)=>`## ${E.metadata.title}
|
|
8115
8115
|
|
|
@@ -8178,14 +8178,14 @@ Newsletter-specific guidelines:
|
|
|
8178
8178
|
- "Reply and let me know..."
|
|
8179
8179
|
- "Until next time..."
|
|
8180
8180
|
|
|
8181
|
-
The goal is to build a relationship with readers through valuable, authentic content.`});WA();aA();import{jsxDEV as p4,Fragment as vPQ}from"preact/jsx-dev-runtime";var kPQ=H.object({id:H.string(),subject:H.string(),status:dv,excerpt:H.string(),created:H.string(),sentAt:H.string().optional(),url:H.string()}),jPQ=H.object({newsletters:H.array(kPQ),totalCount:H.number(),pagination:z7.nullable()}),_PQ=({newsletters:A,totalCount:Q,pageTitle:B,pagination:w,baseUrl:$="/newsletters"})=>{let f=B??"Newsletters",I=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return p4(vPQ,{children:[p4(ZQ,{title:f,description:I},void 0,!1,void 0,this),p4("div",{className:"newsletter-list bg-theme",children:p4("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[p4("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:f},void 0,!1,void 0,this),A.length===0?p4("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):p4("div",{className:"space-y-4",children:A.map((D)=>p4(PB,{href:D.url,children:[p4(W9,{className:"text-lg",children:D.subject},void 0,!1,void 0,this),p4(p9,{children:p4("div",{className:"flex items-center gap-3",children:[p4(mf,{status:D.status},void 0,!1,void 0,this),p4("span",{className:"text-sm text-theme-muted",children:d6(D.sentAt??D.created,{style:"long"})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),D.excerpt&&p4("p",{className:"text-theme-muted line-clamp-2",children:D.excerpt},void 0,!1,void 0,this)]},D.id,!0,void 0,this))},void 0,!1,void 0,this),w&&w.totalPages>1&&p4(bF,{currentPage:w.currentPage,totalPages:w.totalPages,baseUrl:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},gq1=P1({name:"newsletter-list",description:"Newsletter list page template",schema:jPQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:_PQ}});WA();aA();import{jsxDEV as L8,Fragment as SPQ}from"preact/jsx-dev-runtime";var yPQ=H.object({id:H.string(),title:H.string(),url:H.string()}),hq1=H.object({id:H.string(),subject:H.string(),url:H.string()}),TPQ=H.object({id:H.string(),subject:H.string(),status:dv,content:H.string(),created:H.string(),updated:H.string(),sentAt:H.string().optional(),scheduledFor:H.string().optional(),sourceEntities:H.array(yPQ).optional(),prevNewsletter:hq1.nullable().optional(),nextNewsletter:hq1.nullable().optional()}),xPQ=({subject:A,status:Q,content:B,created:w,sentAt:$,scheduledFor:f,sourceEntities:I,prevNewsletter:D,nextNewsletter:U})=>{let Y=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],J=$??w,X=$?"Sent":"Created";return L8(SPQ,{children:[L8(ZQ,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),L8("section",{className:"newsletter-detail-section",children:L8("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:L8("div",{className:"max-w-3xl mx-auto",children:[L8(FH,{items:Y},void 0,!1,void 0,this),L8("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),L8("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[L8(mf,{status:Q},void 0,!1,void 0,this),L8("span",{children:[X,": ",d6(J,{style:"long"})]},void 0,!0,void 0,this),f&&Q==="queued"&&L8("span",{children:["Scheduled for: ",d6(f,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I&&I.length>0&&L8(PB,{variant:"compact",className:"mb-8",children:[L8("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),L8("ul",{className:"space-y-1",children:I.map((G)=>L8("li",{children:L8("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),L8(M$,{markdown:B},void 0,!1,void 0,this),(D??U)&&L8("nav",{className:"mt-12 pt-8 border-t border-theme",children:L8("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[D?L8(PB,{href:D.url,variant:"compact",children:[L8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),L8("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:D.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this):L8("div",{},void 0,!1,void 0,this),U&&L8(PB,{href:U.url,variant:"compact",className:"md:text-right",children:[L8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),L8("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:U.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},mq1=P1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:TPQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:xPQ}});var uq1={name:"@brains/newsletter-entity",private:!0,version:"0.2.0-alpha.
|
|
8181
|
+
The goal is to build a relationship with readers through valuable, authentic content.`});WA();aA();import{jsxDEV as p4,Fragment as vPQ}from"preact/jsx-dev-runtime";var kPQ=H.object({id:H.string(),subject:H.string(),status:dv,excerpt:H.string(),created:H.string(),sentAt:H.string().optional(),url:H.string()}),jPQ=H.object({newsletters:H.array(kPQ),totalCount:H.number(),pagination:z7.nullable()}),_PQ=({newsletters:A,totalCount:Q,pageTitle:B,pagination:w,baseUrl:$="/newsletters"})=>{let f=B??"Newsletters",I=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return p4(vPQ,{children:[p4(ZQ,{title:f,description:I},void 0,!1,void 0,this),p4("div",{className:"newsletter-list bg-theme",children:p4("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[p4("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:f},void 0,!1,void 0,this),A.length===0?p4("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):p4("div",{className:"space-y-4",children:A.map((D)=>p4(PB,{href:D.url,children:[p4(W9,{className:"text-lg",children:D.subject},void 0,!1,void 0,this),p4(p9,{children:p4("div",{className:"flex items-center gap-3",children:[p4(mf,{status:D.status},void 0,!1,void 0,this),p4("span",{className:"text-sm text-theme-muted",children:d6(D.sentAt??D.created,{style:"long"})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),D.excerpt&&p4("p",{className:"text-theme-muted line-clamp-2",children:D.excerpt},void 0,!1,void 0,this)]},D.id,!0,void 0,this))},void 0,!1,void 0,this),w&&w.totalPages>1&&p4(bF,{currentPage:w.currentPage,totalPages:w.totalPages,baseUrl:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},gq1=P1({name:"newsletter-list",description:"Newsletter list page template",schema:jPQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:_PQ}});WA();aA();import{jsxDEV as L8,Fragment as SPQ}from"preact/jsx-dev-runtime";var yPQ=H.object({id:H.string(),title:H.string(),url:H.string()}),hq1=H.object({id:H.string(),subject:H.string(),url:H.string()}),TPQ=H.object({id:H.string(),subject:H.string(),status:dv,content:H.string(),created:H.string(),updated:H.string(),sentAt:H.string().optional(),scheduledFor:H.string().optional(),sourceEntities:H.array(yPQ).optional(),prevNewsletter:hq1.nullable().optional(),nextNewsletter:hq1.nullable().optional()}),xPQ=({subject:A,status:Q,content:B,created:w,sentAt:$,scheduledFor:f,sourceEntities:I,prevNewsletter:D,nextNewsletter:U})=>{let Y=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],J=$??w,X=$?"Sent":"Created";return L8(SPQ,{children:[L8(ZQ,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),L8("section",{className:"newsletter-detail-section",children:L8("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:L8("div",{className:"max-w-3xl mx-auto",children:[L8(FH,{items:Y},void 0,!1,void 0,this),L8("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),L8("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[L8(mf,{status:Q},void 0,!1,void 0,this),L8("span",{children:[X,": ",d6(J,{style:"long"})]},void 0,!0,void 0,this),f&&Q==="queued"&&L8("span",{children:["Scheduled for: ",d6(f,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I&&I.length>0&&L8(PB,{variant:"compact",className:"mb-8",children:[L8("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),L8("ul",{className:"space-y-1",children:I.map((G)=>L8("li",{children:L8("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),L8(M$,{markdown:B},void 0,!1,void 0,this),(D??U)&&L8("nav",{className:"mt-12 pt-8 border-t border-theme",children:L8("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[D?L8(PB,{href:D.url,variant:"compact",children:[L8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),L8("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:D.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this):L8("div",{},void 0,!1,void 0,this),U&&L8(PB,{href:U.url,variant:"compact",className:"md:text-right",children:[L8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),L8("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:U.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},mq1=P1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:TPQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:xPQ}});var uq1={name:"@brains/newsletter-entity",private:!0,version:"0.2.0-alpha.127",description:"Newsletter entity type with AI generation and publish pipeline",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts,.tsx","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/entity-service":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var mPQ=H.object({});class RmA extends _Q{entityType="newsletter";schema=Ur;adapter=Tq1;constructor(A={}){super("newsletter",uq1,A,mPQ)}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}createGenerationHandler(A){return new OmA(this.logger,A)}getTemplates(){return{generation:Sq1,"newsletter-list":gq1,"newsletter-detail":mq1}}getDataSources(){return[new CmA(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:()=>hPQ(QTA,{variant:"inline"})}});return{success:!0}}),this.logger.debug("Newsletter plugin registered")}deferPublishRegistration(A){let Q={name:"internal",publish:async(B,w)=>{let $=typeof w.subject==="string"?w.subject:"",f=await A.messaging.send({type:"buttondown:send",payload:{entityId:"",subject:$,content:B}});return{id:!("noop"in f)&&f.data?.emailId?f.data.emailId:"internal"}}};A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"publish:register",payload:{entityType:"newsletter",provider:Q,config:{publishResultIdField:"buttondownId",publishTimestampField:"sentAt"}}}),{success:!0}})}subscribeToGenerateExecute(A){A.messaging.subscribe("generate:execute",async(Q)=>{if(Q.payload.entityType!=="newsletter")return{success:!0};try{let B=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:10}});if(B.length===0)return await A.messaging.send({type:"generate:report:failure",payload:{entityType:"newsletter",error:"No published posts available for newsletter"}}),{success:!0};return await A.jobs.enqueue({type:"newsletter:generation",data:{sourceEntityIds:B.map((w)=>w.id),sourceEntityType:"post",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}}),{success:!0}}catch(B){return await A.messaging.send({type:"generate:report:failure",payload:{entityType:"newsletter",error:y0(B)}}),{success:!0}}})}registerEvalHandlers(A){let Q=H.object({prompt:H.string().optional(),content:H.string().optional()});A.eval.registerHandler("generation",async(B)=>{let w=Q.parse(B),$=w.content?`Create an engaging newsletter based on this content:
|
|
8182
8182
|
|
|
8183
|
-
${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function bmA(A={}){return new RmA(A)}aA();WA();class nv{config;logger;constructor(A,Q){this.config=A;this.logger=Q}async request(A,Q={}){let B=`https://api.buttondown.email/v1${A}`;this.logger.debug("Buttondown API request",{endpoint:A,method:Q.method??"GET"});let w=await fetch(B,{...Q,headers:{Authorization:`Token ${this.config.apiKey}`,"Content-Type":"application/json",...Q.headers}});if(!w.ok){let $=await w.json().catch(()=>({})),f=$.detail??$.message??`HTTP ${w.status}`;throw this.logger.error("Buttondown API error",{endpoint:A,status:w.status,error:f}),Error(`Buttondown API error: ${f}`)}return w.json()}async createSubscriber(A){let Q={email_address:A.email,type:this.config.doubleOptIn?"unactivated":"regular"};if(A.name)Q.metadata={name:A.name};if(A.tags&&A.tags.length>0)Q.tags=A.tags;this.logger.info("Creating subscriber",{email:A.email});try{return await this.request("/subscribers",{method:"POST",body:JSON.stringify(Q)})}catch(B){if(B instanceof Error&&B.message.includes("already subscribed")){let w=B.message.match(/id=([a-f0-9-]+)/);return this.logger.info("Subscriber already exists",{email:A.email}),{id:w?.[1]??"existing",email:A.email,subscriber_type:"already_subscribed"}}throw B}}async unsubscribe(A){this.logger.info("Unsubscribing",{email:A}),await this.request(`/subscribers/${encodeURIComponent(A)}`,{method:"DELETE"})}async listSubscribers(A){let Q=new URLSearchParams;if(A?.type)Q.set("type",A.type);if(A?.limit)Q.set("page_size",String(A.limit));let B=Q.toString(),w=B?`/subscribers?${B}`:"/subscribers";return this.request(w)}async createEmail(A){let Q={subject:A.subject,body:A.body,status:A.status??"draft"};if(A.publish_date)Q.publish_date=A.publish_date;return this.logger.info("Creating email",{subject:A.subject,status:A.status??"draft"}),this.request("/emails",{method:"POST",body:JSON.stringify(Q)})}async getEmail(A){return this.request(`/emails/${A}`)}async validateCredentials(){try{return await this.request("/subscribers?page_size=1"),!0}catch{return!1}}}aA();WA();var uPQ=H.object({email:H.string().email().describe("Email address to subscribe"),name:H.string().optional().describe("Subscriber name (optional)"),tags:H.array(H.string()).optional().describe("Tags to apply to subscriber (optional)")}),cPQ=H.object({email:H.string().email().describe("Email address to unsubscribe")}),lPQ=H.object({type:H.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:H.number().optional().describe("Maximum number of results")});function cq1(A,Q,B){let w=new nv(Q,B);return[oQ(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",uPQ,async($)=>{try{let f=await w.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),I=f.subscriber_type==="already_subscribed";return Y8({subscriberId:f.id,email:f.email,status:f.subscriber_type,message:I?"already_subscribed":"subscribed"},I?`${$.email} is already subscribed`:`Subscribed ${$.email} successfully`)}catch(f){return H$(y0(f))}}),oQ(A,"unsubscribe","Unsubscribe an email address from the newsletter.",cPQ,async($)=>{try{return await w.unsubscribe($.email),Y8({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(f){return H$(y0(f))}}),oQ(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",lPQ,async($)=>{try{let f=await w.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return Y8({subscribers:f.results.map((I)=>({id:I.id,email:I.email,status:I.subscriber_type})),count:f.count},`Found ${f.count} subscribers`)}catch(f){return H$(y0(f))}})]}WA();async function lq1(A,Q,B,w){if(A.entityType!=="post")return{success:!0,skipped:!0,reason:"Only post entity types trigger auto-send"};let $=await B.getEntity({entityType:"post",id:A.entityId});if(!$)return{success:!1,error:`Post ${A.entityId} not found`};w.info("Auto-sending newsletter for published post",{postId:$.id,title:$.metadata.title});try{let f=await Q.createEmail({subject:$.metadata.title,body:$.content,status:"about_to_send"});return w.info("Newsletter sent for post",{postId:$.id,emailId:f.id}),{success:!0,emailId:f.id}}catch(f){let I=y0(f);return w.error("Failed to send newsletter for post",{postId:$.id,error:I}),{success:!1,error:I}}}var pq1={name:"@brains/buttondown",private:!0,version:"0.2.0-alpha.
|
|
8183
|
+
${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function bmA(A={}){return new RmA(A)}aA();WA();class nv{config;logger;constructor(A,Q){this.config=A;this.logger=Q}async request(A,Q={}){let B=`https://api.buttondown.email/v1${A}`;this.logger.debug("Buttondown API request",{endpoint:A,method:Q.method??"GET"});let w=await fetch(B,{...Q,headers:{Authorization:`Token ${this.config.apiKey}`,"Content-Type":"application/json",...Q.headers}});if(!w.ok){let $=await w.json().catch(()=>({})),f=$.detail??$.message??`HTTP ${w.status}`;throw this.logger.error("Buttondown API error",{endpoint:A,status:w.status,error:f}),Error(`Buttondown API error: ${f}`)}return w.json()}async createSubscriber(A){let Q={email_address:A.email,type:this.config.doubleOptIn?"unactivated":"regular"};if(A.name)Q.metadata={name:A.name};if(A.tags&&A.tags.length>0)Q.tags=A.tags;this.logger.info("Creating subscriber",{email:A.email});try{return await this.request("/subscribers",{method:"POST",body:JSON.stringify(Q)})}catch(B){if(B instanceof Error&&B.message.includes("already subscribed")){let w=B.message.match(/id=([a-f0-9-]+)/);return this.logger.info("Subscriber already exists",{email:A.email}),{id:w?.[1]??"existing",email:A.email,subscriber_type:"already_subscribed"}}throw B}}async unsubscribe(A){this.logger.info("Unsubscribing",{email:A}),await this.request(`/subscribers/${encodeURIComponent(A)}`,{method:"DELETE"})}async listSubscribers(A){let Q=new URLSearchParams;if(A?.type)Q.set("type",A.type);if(A?.limit)Q.set("page_size",String(A.limit));let B=Q.toString(),w=B?`/subscribers?${B}`:"/subscribers";return this.request(w)}async createEmail(A){let Q={subject:A.subject,body:A.body,status:A.status??"draft"};if(A.publish_date)Q.publish_date=A.publish_date;return this.logger.info("Creating email",{subject:A.subject,status:A.status??"draft"}),this.request("/emails",{method:"POST",body:JSON.stringify(Q)})}async getEmail(A){return this.request(`/emails/${A}`)}async validateCredentials(){try{return await this.request("/subscribers?page_size=1"),!0}catch{return!1}}}aA();WA();var uPQ=H.object({email:H.string().email().describe("Email address to subscribe"),name:H.string().optional().describe("Subscriber name (optional)"),tags:H.array(H.string()).optional().describe("Tags to apply to subscriber (optional)")}),cPQ=H.object({email:H.string().email().describe("Email address to unsubscribe")}),lPQ=H.object({type:H.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:H.number().optional().describe("Maximum number of results")});function cq1(A,Q,B){let w=new nv(Q,B);return[oQ(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",uPQ,async($)=>{try{let f=await w.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),I=f.subscriber_type==="already_subscribed";return Y8({subscriberId:f.id,email:f.email,status:f.subscriber_type,message:I?"already_subscribed":"subscribed"},I?`${$.email} is already subscribed`:`Subscribed ${$.email} successfully`)}catch(f){return H$(y0(f))}}),oQ(A,"unsubscribe","Unsubscribe an email address from the newsletter.",cPQ,async($)=>{try{return await w.unsubscribe($.email),Y8({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(f){return H$(y0(f))}}),oQ(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",lPQ,async($)=>{try{let f=await w.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return Y8({subscribers:f.results.map((I)=>({id:I.id,email:I.email,status:I.subscriber_type})),count:f.count},`Found ${f.count} subscribers`)}catch(f){return H$(y0(f))}})]}WA();async function lq1(A,Q,B,w){if(A.entityType!=="post")return{success:!0,skipped:!0,reason:"Only post entity types trigger auto-send"};let $=await B.getEntity({entityType:"post",id:A.entityId});if(!$)return{success:!1,error:`Post ${A.entityId} not found`};w.info("Auto-sending newsletter for published post",{postId:$.id,title:$.metadata.title});try{let f=await Q.createEmail({subject:$.metadata.title,body:$.content,status:"about_to_send"});return w.info("Newsletter sent for post",{postId:$.id,emailId:f.id}),{success:!0,emailId:f.id}}catch(f){let I=y0(f);return w.error("Failed to send newsletter for post",{postId:$.id,error:I}),{success:!1,error:I}}}var pq1={name:"@brains/buttondown",private:!0,version:"0.2.0-alpha.127",description:"Buttondown newsletter integration \u2014 subscriber management and API routes",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var iPQ=H.object({apiKey:H.string().optional().describe("Buttondown API key"),doubleOptIn:H.boolean().default(!0).describe("Require email confirmation for new subscribers"),autoSendOnPublish:H.boolean().default(!1).describe("Automatically send newsletter when a blog post is published")});class PmA extends YB{constructor(A={}){super("buttondown",pq1,A,iPQ)}async onRegister(A){if(A.messaging.subscribe("buttondown:is-configured",async()=>{return{success:!!this.config.apiKey}}),this.config.apiKey){let Q=new nv({apiKey:this.config.apiKey,doubleOptIn:this.config.doubleOptIn},this.logger);if(A.messaging.subscribe("buttondown:send",async(B)=>{try{return{success:!0,data:{emailId:(await Q.createEmail({subject:B.payload.subject,body:B.payload.content,status:"about_to_send"})).id}}}catch(w){return this.logger.error("Buttondown send failed",{error:y0(w)}),{success:!1}}}),this.config.autoSendOnPublish)A.messaging.subscribe("publish:completed",async(B)=>{return await lq1(B.payload,Q,A.entityService,this.logger),{success:!0}}),this.logger.info("Buttondown auto-send on publish enabled")}}async getTools(){if(!this.config.apiKey)return[];return cq1(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 kmA(A={}){return new PmA(A)}var rPQ=H.object({apiKey:H.string().optional().describe("Buttondown API key"),doubleOptIn:H.boolean().optional().describe("Require email confirmation for new subscribers"),autoSendOnPublish:H.boolean().optional().describe("Automatically send newsletter when a blog post is published")});function iq1(A={}){let Q=rPQ.parse(A);return[bmA({}),kmA({...Q.apiKey!==void 0&&{apiKey:Q.apiKey},...Q.doubleOptIn!==void 0&&{doubleOptIn:Q.doubleOptIn},...Q.autoSendOnPublish!==void 0&&{autoSendOnPublish:Q.autoSendOnPublish}})]}aA();WA();import{existsSync as $kQ,mkdirSync as fkQ,writeFileSync as IkQ}from"fs";import{join as AZ}from"path";WA();var jmA=H.object({baseFolder:H.string().default("_obsidian")});WA();function dPQ(A){let Q=A,B=!0,w=void 0,$=!1,f=!0;while(f){if(f=!1,Q instanceof H.ZodOptional)B=!1,Q=Q._def.innerType,f=!0;if(Q instanceof H.ZodDefault)B=!1,$=!0,w=Q._def.defaultValue(),Q=Q._def.innerType,f=!0;if(Q instanceof H.ZodNullable)B=!1,Q=Q._def.innerType,f=!0}let I={inner:Q,required:B};if($)I.defaultValue=w;return I}function nPQ(A){if(A instanceof H.ZodEnum)return{type:"enum",enumValues:A._def.values};if(A instanceof H.ZodLiteral)return{type:"string",defaultValue:A._def.value};if(A instanceof H.ZodString)return{type:"string"};if(A instanceof H.ZodNumber)return{type:"number"};if(A instanceof H.ZodBoolean)return{type:"boolean"};if(A instanceof H.ZodArray)return{type:"array"};if(A instanceof H.ZodDate)return{type:"date"};if(A instanceof H.ZodPipeline){if(A._def.out instanceof H.ZodDate)return{type:"date"}}return{type:"unknown"}}function rq1(A){let Q=A.shape,B=[];for(let[w,$]of Object.entries(Q)){let{inner:f,required:I,defaultValue:D}=dPQ($),U=nPQ(f),Y={name:w,type:U.type,required:I},J=D!==void 0?D:U.defaultValue;if(J!==void 0)Y.defaultValue=J;if(U.enumValues)Y.enumValues=U.enumValues;B.push(Y)}return B}function oPQ(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 dq1(A,Q,B=""){let w=["---"];for(let $ of Q){let f=oPQ($,A);if(f==="")w.push(`${$.name}:`);else w.push(`${$.name}: ${f}`)}if(w.push("---"),w.push(""),B)w.push(B);else w.push("<!-- Write your content here -->"),w.push("");return w.join(`
|
|
8184
8184
|
`)}WA();var sPQ={string:"Input",number:"Number",boolean:"Boolean",date:"Date",enum:"Select",array:"Multi",unknown:"Input"};function aPQ(A){let Q={name:A.name,id:A.name,type:sPQ[A.type]};if(A.type==="enum"&&A.enumValues){let B={};A.enumValues.forEach((w,$)=>{B[String($)]=w}),Q.options=B}return Q}function nq1(A,Q){let B={filesPaths:A,fields:Q.map(aPQ)};return`---
|
|
8185
8185
|
${sX(B)}---
|
|
8186
|
-
`}WA();var tPQ=new Set(["entityType"]),ePQ={base:"Notes"},AkQ=new Set(["note"]);function QkQ(A){let Q=["file.name"];for(let B of A)if(!tPQ.has(B.name))Q.push(B.name);return Q}function BkQ(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function oq1(A,Q){let B=ePQ[A]??fo(A),w=BkQ(Q),$=QkQ(Q),f=[{type:"table",name:`All ${B}`,order:$}];if(w)f.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:$});let D={filters:{and:[AkQ.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:f};return{filename:`${B}.base`,content:sX(D),hasStatus:w}}function sq1(A){if(A.length===0)return null;let Q=A.map((w)=>`file.inFolder("${w}")`),B={filters:{and:[Q.length===1?Q[0]:{or:Q}]},views:[{type:"table",name:"Settings",order:["file.name","file.folder"]}]};return sX(B)}function aq1(A){if(A.length===0)return null;let Q=A.map((w)=>`file.inFolder("${w.entityType}")`),B={filters:{and:[Q.length===1?Q[0]:{or:Q},'status != "published"']},views:[{type:"table",name:"Pipeline",groupBy:{property:"status",direction:"ASC"},order:["file.name","file.folder","status"]}]};return sX(B)}var tq1={name:"@brains/obsidian-vault",private:!0,version:"0.2.0-alpha.125",description:"Obsidian vault integration \u2014 generates templates from entity schemas",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var DkQ={mkdir:fkQ,writeFile:IkQ,existsFile:$kQ},UkQ=H.object({entityTypes:H.array(H.string()).optional().describe("Entity types to generate templates for (default: all)")});class _mA extends YB{deps;constructor(A={},Q={}){super("obsidian-vault",tq1,A,jmA);this.deps={...DkQ,...Q}}async onReady(A){this.logger.info("Auto-syncing Obsidian templates, fileClasses, and bases"),await this.sync(A)}async getTools(){let A=this.getContext();return[oQ(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",UkQ,async(Q)=>{return this.sync(A,Q.entityTypes)})]}async sync(A,Q){try{let B=A.entityService.getEntityTypes(),w=Q?B.filter((L)=>Q.includes(L)):B,$=AZ(A.dataDir,this.config.baseFolder),f=AZ($,"templates"),I=AZ($,"fileClasses"),D=AZ($,"bases");this.deps.mkdir(f,{recursive:!0}),this.deps.mkdir(I,{recursive:!0}),this.deps.mkdir(D,{recursive:!0});let U=[],Y=[],J=[],X=[],G=[],Z=[];for(let L of w){let M=A.entities.getEffectiveFrontmatterSchema(L);if(!M){this.logger.debug(`Skipping ${L}: no frontmatter schema`),Y.push(L);continue}let O=rq1(M),E=A.entities.getAdapter(L),S=E?.isSingleton===!0,T=nq1(L,O);if(this.deps.writeFile(AZ(I,`${L}.md`),T),J.push(L),S){G.push(L),this.logger.debug(`Generated fileClass (singleton): ${L}`);continue}let y=E?.getBodyTemplate()??"",_=dq1(L,O,y);this.deps.writeFile(AZ(f,`${L}.md`),_),U.push(L);let x=oq1(L,O),g=AZ(D,x.filename);if(!this.deps.existsFile(g))this.deps.writeFile(g,x.content),X.push(L),this.logger.debug(`Generated base: ${x.filename}`);if(x.hasStatus)Z.push({entityType:L,fields:O});this.logger.debug(`Generated template + fileClass: ${L}`)}let N=sq1(G);if(N){let L=AZ(D,"Settings.base");if(!this.deps.existsFile(L))this.deps.writeFile(L,N),X.push("Settings"),this.logger.debug("Generated Settings.base")}let V=aq1(Z);if(V){let L=AZ(D,"Pipeline.base");if(!this.deps.existsFile(L))this.deps.writeFile(L,V),X.push("Pipeline"),this.logger.debug("Generated Pipeline.base")}return this.logger.info(`Synced ${U.length} templates, ${J.length} fileClasses, ${X.length} bases (${Y.length} skipped)`),Y8({generated:U,skipped:Y,fileClasses:J,bases:X})}catch(B){return this.logger.error("Failed to sync",{error:B}),H$(B instanceof Error?B.message:"Unknown error")}}}function vmA(A,Q){return new _mA(A,Q)}aA();WA();aA();var ymA=H.enum(["new","planned","in-progress","done","declined"]),TmA=H.enum(["low","medium","high","critical"]),Yr=H.object({title:H.string(),status:ymA,priority:TmA.default("medium"),requested:H.number().int().default(1),declinedReason:H.string().optional()}),eq1=H.object({title:H.string(),status:ymA,priority:TmA,requested:H.number().int(),slug:H.string()}),Jr=A2.extend({entityType:H.literal("wish"),metadata:eq1}),xmA=H.object({});aA();WA();class Xr extends q2{constructor(){super({entityType:"wish",schema:Jr,frontmatterSchema:Yr})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,Yr);return{frontmatter:Yr.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),B=X1(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:B}}}}var SmA=new Xr;WA();WA();async function AL1(A,Q){let B=`${Q.title}: ${Q.description}`,$=(await A.search({query:B,options:{types:["wish"],limit:1}}))[0];if($&&$.score>=A.similarityThreshold)return $.entity;let f=X1(Q.title);return A.getEntity({entityType:"wish",id:f})}class B9A{logger;context;adapter=new Xr;constructor(A,Q){this.logger=A;this.context=Q}async process(A,Q,B){let w=A.title??A.prompt??"Untitled wish",$=A.content??A.prompt??"",f=await AL1({search:(Y)=>this.context.entityService.search(Y),getEntity:(Y)=>this.context.entityService.getEntity(Y),similarityThreshold:0.85},{title:w,description:$});if(f){let{frontmatter:Y,description:J}=this.adapter.parseWishContent(f.content),X=Y.requested+1,G=this.adapter.createWishContent({...Y,requested:X},J);return await this.context.entityService.updateEntity({entity:{...f,content:G,metadata:{...f.metadata,requested:X}}}),this.logger.info("Incremented wish request count",{id:f.id,requested:X}),{success:!0,entityId:f.id,existed:!0,requested:X}}let I=X1(w),D=A.options?.priority??"medium",U=this.adapter.createWishContent({title:w,status:"new",priority:D,requested:1},$);return await this.context.entityService.createEntity({entity:{id:I,entityType:"wish",content:U,metadata:{title:w,status:"new",priority:D,requested:1,slug:I}}}),this.logger.info("Created new wish",{id:I,title:w}),{success:!0,entityId:I,existed:!1,requested:1}}}var QL1={critical:0,high:1,medium:2,low:3};function BL1(A){A.sort((Q,B)=>{let w=B.metadata.requested-Q.metadata.requested;if(w!==0)return w;return QL1[Q.metadata.priority]-QL1[B.metadata.priority]})}var wL1={name:"@brains/wishlist",private:!0,version:"0.2.0-alpha.125",description:"Wishlist plugin for tracking unfulfilled user requests",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class $L1 extends _Q{entityType=SmA.entityType;schema=Jr;adapter=SmA;constructor(A={}){super("wishlist",wL1,A,xmA)}async interceptCreate(A,Q,B){let w=await new B9A(this.logger,B).process({...A.title?{title:A.title}:{},...A.prompt?{prompt:A.prompt}:{},...A.content?{content:A.content}:{}},`wish-create-${Date.now()}`,{});if(!w.success)return{kind:"handled",result:{success:!1,error:w.error??"Failed to create wish"}};return{kind:"handled",result:{success:!0,data:{...w.entityId?{entityId:w.entityId}:{},status:w.existed?"updated":"created"}}}}async onRegister(A){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:"top-wishes",pluginId:this.id,title:"Top Wishes",section:"secondary",priority:30,rendererName:"ListWidget",dataProvider:async()=>{let B=await A.entityService.listEntities({entityType:"wish",options:{limit:10}});return BL1(B),{items:B.map((w)=>({id:w.id,name:w.metadata.title,count:w.metadata.requested,priority:w.metadata.priority,status:w.metadata.status}))}}}}),{success:!0}});let Q=new B9A(this.logger,A);A.jobs.registerHandler("wish:create",{process:Q.process.bind(Q),validateAndParse:(B)=>B})}async getInstructions(){return"**CRITICAL \u2014 Wishlist exclusions**: A2A agent-contact requests are never wishlist cases. "+'If a request asks you to ask, message, contact, call, or reach out to an agent, and the target is missing, ambiguous, archived, URL-only, unsaved-domain, or not-yet-saved in the local agent directory, do not call any create tool for a wish. Tell the user to add/save or clarify the agent first. This includes requests that contain a full agent URL, a bare domain like unknown-agent.io, or phrasing like "message this agent URL for me". Only create or save an agent entry if the user explicitly asks you to add or save that agent. '+"**CRITICAL \u2014 Unfulfilled requests**: For other unfulfillable requests, ALWAYS call `system_create` with entityType "+`"wish" BEFORE responding when you cannot fulfill a user's request. This applies to physical actions, non-agent missing integrations, and any non-agent capability `+"you lack. Physical-world requests like making food, driving somewhere, or doing chores are always wishlist cases. Do NOT just explain you can't do it \u2014 create the wish first, THEN respond. "+"Never claim the request was added to the wishlist unless you actually called system_create for the wish. In your response, tell the user their request has been added to the wishlist."}}function JkQ(A={}){return new $L1(A)}var w9A=JkQ;aA();WA();aA();var Wr=H.object({title:H.string(),target:H.string()}),fL1=H.object({title:H.string(),target:H.string(),slug:H.string().optional()}),Hr=A2.extend({entityType:H.literal("prompt"),metadata:fL1});aA();WA();class gmA extends q2{constructor(){super({entityType:"prompt",schema:Hr,frontmatterSchema:Wr})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,Wr);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,Wr),B=X1(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:B}}}}var $9A=new gmA;var IL1={name:"@brains/prompt",private:!0,version:"0.2.0-alpha.125",description:"Prompt entity type \u2014 AI prompts as editable markdown entities",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","bun-types":"latest",typescript:"^5.3.3"}};class hmA extends _Q{entityType=$9A.entityType;schema=Hr;adapter=$9A;constructor(){super("prompt",IL1,{},void 0)}getEntityTypeConfig(){return{embeddable:!1}}}function RC(){return new hmA}aA();WA();class f9A{apiKey;fetchFn;baseUrl="https://api.unsplash.com";constructor(A,Q){this.apiKey=A,this.fetchFn=Q}async searchPhotos(A,Q){let B=new URL(`${this.baseUrl}/search/photos`);B.searchParams.set("query",A),B.searchParams.set("page",String(Q.page)),B.searchParams.set("per_page",String(Q.perPage));let w=await this.fetchFn(B.toString(),{headers:{Authorization:`Client-ID ${this.apiKey}`}});if(!w.ok)throw Error(`Unsplash API error: ${w.status} ${w.statusText}`);let $=await w.json();return{photos:$.results.map(WkQ),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}function WkQ(A){return{id:A.id,description:A.description,altDescription:A.alt_description,thumbnailUrl:A.urls.thumb,imageUrl:A.urls.regular,photographerName:A.user.name,photographerUrl:A.user.links.html,sourceUrl:A.links.html,downloadLocation:A.links.download_location,width:A.width,height:A.height}}WA();var DL1={query:H.string().describe("Search terms for stock photos"),perPage:H.number().min(1).max(30).default(10).describe("Results per page (1-30)"),page:H.number().min(1).default(1).describe("Page number")},UL1={photoId:H.string().describe("Photo ID from search results"),downloadLocation:H.string().url().describe("Download tracking URL (required by provider ToS)"),photographerName:H.string().describe("Photographer name for attribution"),photographerUrl:H.string().url().describe("Photographer profile URL for attribution"),sourceUrl:H.string().url().describe("Photo page URL on provider"),imageUrl:H.string().url().describe("Image URL to download"),title:H.string().optional().describe("Image entity title"),alt:H.string().optional().describe("Alt text for the image"),targetEntityType:H.string().optional().describe("Entity type to set cover image on"),targetEntityId:H.string().optional().describe("Entity ID to set cover image on")};function YL1(A,Q){return[HkQ(A,Q),GkQ(A,Q)]}function HkQ(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:DL1,handler:async(B)=>{let w=H.object(DL1).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};try{return{success:!0,data:await Q.provider.searchPhotos(w.data.query,{page:w.data.page,perPage:w.data.perPage})}}catch($){return{success:!1,error:$ instanceof Error?$.message:"Search failed"}}}}}function GkQ(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:UL1,handler:async(B)=>{let w=H.object(UL1).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{photoId:$,downloadLocation:f,photographerName:I,photographerUrl:D,sourceUrl:U,imageUrl:Y,title:J,alt:X,targetEntityType:G,targetEntityId:Z}=w.data,N={photographerName:I,photographerUrl:D,sourceUrl:U},V=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:Y}}}});if(V[0]){let O={imageEntityId:V[0].id,alreadyExisted:!0,attribution:N};if(G&&Z)await KkQ(Q.entityService,G,Z,V[0].id),O.coverSet=!0;return{success:!0,data:O}}let L=await Q.jobs.enqueue({type:"select-photo",data:{photoId:$,downloadLocation:f,photographerName:I,photographerUrl:D,sourceUrl:U,imageUrl:Y,...J!==void 0?{title:J}:{},...X!==void 0?{alt:X}:{},...G!==void 0?{targetEntityType:G}:{},...Z!==void 0?{targetEntityId:Z}:{}}}),M={imageEntityId:$,alreadyExisted:!1,attribution:N,jobId:L,status:"generating"};if(G&&Z)M.coverSet=!0;return{success:!0,data:M}}}}async function KkQ(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}aA();WA();C7();var FkQ=H.object({photoId:H.string(),downloadLocation:H.string().url(),photographerName:H.string(),photographerUrl:H.string().url(),sourceUrl:H.string().url(),imageUrl:H.string().url(),title:H.string().optional(),alt:H.string().optional(),targetEntityType:H.string().optional(),targetEntityId:H.string().optional()});class mmA extends ZB{deps;constructor(A,Q){super(A,{schema:FkQ,jobTypeName:"select-photo"});this.deps=Q}async process(A,Q,B){await this.reportProgress(B,{progress:10,message:"Tracking stock photo download"}),await this.deps.provider.triggerDownload(A.downloadLocation),await this.reportProgress(B,{progress:35,message:"Downloading stock photo"});let w=await this.deps.fetchImage(A.imageUrl),$=A.title??`Stock photo ${A.photoId}`,f=mI.createImageEntity({dataUrl:w,title:$,alt:A.alt??$});await this.reportProgress(B,{progress:75,message:"Saving stock photo"});let{entityId:I}=await this.deps.entityService.createEntity({entity:{id:A.photoId,...f,metadata:{...f.metadata,sourceUrl:A.imageUrl}}}),D={imageEntityId:I,alreadyExisted:!1};if(A.targetEntityType&&A.targetEntityId)await ZkQ(this.deps.entityService,A.targetEntityType,A.targetEntityId,I),D.coverSet=!0;return await this.reportProgress(B,{progress:100,message:"Stock photo selected"}),D}summarizeDataForLog(A){return{photoId:A.photoId,hasTarget:A.targetEntityType!==void 0}}}async function ZkQ(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}C7();var JL1={name:"@brains/stock-photo",private:!0,version:"0.2.0-alpha.125",description:"Stock photo search and selection \u2014 Unsplash provider",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var zkQ=H.object({provider:H.enum(["unsplash"]).default("unsplash"),apiKey:H.string().optional().describe("Stock photo provider API key")});class umA extends YB{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",JL1,A,zkQ);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=YL1(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??qU,jobs:A.jobs}),this.cachedTools}async registerJobHandlers(){if(!this.config.apiKey)return;let A=this.getContext();A.jobs.registerHandler("select-photo",new mmA(this.logger.child("SelectPhotoJobHandler"),{provider:this.createProvider(),entityService:A.entityService,fetchImage:this.deps.fetchImage??qU}))}createProvider(){return new f9A(this.config.apiKey??"",this.deps.fetch??globalThis.fetch)}}function cmA(A={},Q={}){return new umA(A,Q)}aA();WA();aA();aA();WA();var XL1=H.enum(["ai","foundation","work"]),WL1=H.object({suffix:XL1,title:H.string(),body:H.string(),linkLabel:H.string(),linkHref:H.string()}),Gr=H.object({eyebrow:H.string(),headline:H.string(),cards:H.array(WL1).min(1)}),I9A=H.object({title:H.string(),slug:H.string(),status:H.enum(["draft","published"])}),Kr=A2.extend({entityType:H.literal("ecosystem-section"),metadata:I9A});class HL1 extends q2{constructor(){super({entityType:"ecosystem-section",schema:Kr,frontmatterSchema:I9A})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var lmA=new HL1;WA();function qkQ(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function pmA(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function Fr(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function D9A(A){let Q=qkQ(A),w=pmA(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return Gr.parse({eyebrow:pmA(Q,"Eyebrow"),headline:pmA(Q,"Headline"),cards:w.map(($)=>({suffix:Fr($,"Suffix"),title:Fr($,"Title"),body:Fr($,"Body"),linkLabel:Fr($,"Link Label"),linkHref:Fr($,"Link Href")}))})}function GL1(A){return["# Ecosystem Section","","## Eyebrow",A.eyebrow,"","## Headline",A.headline,"","## Cards","",...A.cards.flatMap((Q,B)=>[`### Card ${B+1}`,"","#### Suffix",Q.suffix,"","#### Title",Q.title,"","#### Body",Q.body,"","#### Link Label",Q.linkLabel,"","#### Link Href",Q.linkHref,""])].join(`
|
|
8186
|
+
`}WA();var tPQ=new Set(["entityType"]),ePQ={base:"Notes"},AkQ=new Set(["note"]);function QkQ(A){let Q=["file.name"];for(let B of A)if(!tPQ.has(B.name))Q.push(B.name);return Q}function BkQ(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function oq1(A,Q){let B=ePQ[A]??fo(A),w=BkQ(Q),$=QkQ(Q),f=[{type:"table",name:`All ${B}`,order:$}];if(w)f.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:$});let D={filters:{and:[AkQ.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:f};return{filename:`${B}.base`,content:sX(D),hasStatus:w}}function sq1(A){if(A.length===0)return null;let Q=A.map((w)=>`file.inFolder("${w}")`),B={filters:{and:[Q.length===1?Q[0]:{or:Q}]},views:[{type:"table",name:"Settings",order:["file.name","file.folder"]}]};return sX(B)}function aq1(A){if(A.length===0)return null;let Q=A.map((w)=>`file.inFolder("${w.entityType}")`),B={filters:{and:[Q.length===1?Q[0]:{or:Q},'status != "published"']},views:[{type:"table",name:"Pipeline",groupBy:{property:"status",direction:"ASC"},order:["file.name","file.folder","status"]}]};return sX(B)}var tq1={name:"@brains/obsidian-vault",private:!0,version:"0.2.0-alpha.127",description:"Obsidian vault integration \u2014 generates templates from entity schemas",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var DkQ={mkdir:fkQ,writeFile:IkQ,existsFile:$kQ},UkQ=H.object({entityTypes:H.array(H.string()).optional().describe("Entity types to generate templates for (default: all)")});class _mA extends YB{deps;constructor(A={},Q={}){super("obsidian-vault",tq1,A,jmA);this.deps={...DkQ,...Q}}async onReady(A){this.logger.info("Auto-syncing Obsidian templates, fileClasses, and bases"),await this.sync(A)}async getTools(){let A=this.getContext();return[oQ(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",UkQ,async(Q)=>{return this.sync(A,Q.entityTypes)})]}async sync(A,Q){try{let B=A.entityService.getEntityTypes(),w=Q?B.filter((L)=>Q.includes(L)):B,$=AZ(A.dataDir,this.config.baseFolder),f=AZ($,"templates"),I=AZ($,"fileClasses"),D=AZ($,"bases");this.deps.mkdir(f,{recursive:!0}),this.deps.mkdir(I,{recursive:!0}),this.deps.mkdir(D,{recursive:!0});let U=[],Y=[],J=[],X=[],G=[],Z=[];for(let L of w){let M=A.entities.getEffectiveFrontmatterSchema(L);if(!M){this.logger.debug(`Skipping ${L}: no frontmatter schema`),Y.push(L);continue}let O=rq1(M),E=A.entities.getAdapter(L),S=E?.isSingleton===!0,T=nq1(L,O);if(this.deps.writeFile(AZ(I,`${L}.md`),T),J.push(L),S){G.push(L),this.logger.debug(`Generated fileClass (singleton): ${L}`);continue}let y=E?.getBodyTemplate()??"",_=dq1(L,O,y);this.deps.writeFile(AZ(f,`${L}.md`),_),U.push(L);let x=oq1(L,O),g=AZ(D,x.filename);if(!this.deps.existsFile(g))this.deps.writeFile(g,x.content),X.push(L),this.logger.debug(`Generated base: ${x.filename}`);if(x.hasStatus)Z.push({entityType:L,fields:O});this.logger.debug(`Generated template + fileClass: ${L}`)}let N=sq1(G);if(N){let L=AZ(D,"Settings.base");if(!this.deps.existsFile(L))this.deps.writeFile(L,N),X.push("Settings"),this.logger.debug("Generated Settings.base")}let V=aq1(Z);if(V){let L=AZ(D,"Pipeline.base");if(!this.deps.existsFile(L))this.deps.writeFile(L,V),X.push("Pipeline"),this.logger.debug("Generated Pipeline.base")}return this.logger.info(`Synced ${U.length} templates, ${J.length} fileClasses, ${X.length} bases (${Y.length} skipped)`),Y8({generated:U,skipped:Y,fileClasses:J,bases:X})}catch(B){return this.logger.error("Failed to sync",{error:B}),H$(B instanceof Error?B.message:"Unknown error")}}}function vmA(A,Q){return new _mA(A,Q)}aA();WA();aA();var ymA=H.enum(["new","planned","in-progress","done","declined"]),TmA=H.enum(["low","medium","high","critical"]),Yr=H.object({title:H.string(),status:ymA,priority:TmA.default("medium"),requested:H.number().int().default(1),declinedReason:H.string().optional()}),eq1=H.object({title:H.string(),status:ymA,priority:TmA,requested:H.number().int(),slug:H.string()}),Jr=A2.extend({entityType:H.literal("wish"),metadata:eq1}),xmA=H.object({});aA();WA();class Xr extends q2{constructor(){super({entityType:"wish",schema:Jr,frontmatterSchema:Yr})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,Yr);return{frontmatter:Yr.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),B=X1(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:B}}}}var SmA=new Xr;WA();WA();async function AL1(A,Q){let B=`${Q.title}: ${Q.description}`,$=(await A.search({query:B,options:{types:["wish"],limit:1}}))[0];if($&&$.score>=A.similarityThreshold)return $.entity;let f=X1(Q.title);return A.getEntity({entityType:"wish",id:f})}class B9A{logger;context;adapter=new Xr;constructor(A,Q){this.logger=A;this.context=Q}async process(A,Q,B){let w=A.title??A.prompt??"Untitled wish",$=A.content??A.prompt??"",f=await AL1({search:(Y)=>this.context.entityService.search(Y),getEntity:(Y)=>this.context.entityService.getEntity(Y),similarityThreshold:0.85},{title:w,description:$});if(f){let{frontmatter:Y,description:J}=this.adapter.parseWishContent(f.content),X=Y.requested+1,G=this.adapter.createWishContent({...Y,requested:X},J);return await this.context.entityService.updateEntity({entity:{...f,content:G,metadata:{...f.metadata,requested:X}}}),this.logger.info("Incremented wish request count",{id:f.id,requested:X}),{success:!0,entityId:f.id,existed:!0,requested:X}}let I=X1(w),D=A.options?.priority??"medium",U=this.adapter.createWishContent({title:w,status:"new",priority:D,requested:1},$);return await this.context.entityService.createEntity({entity:{id:I,entityType:"wish",content:U,metadata:{title:w,status:"new",priority:D,requested:1,slug:I}}}),this.logger.info("Created new wish",{id:I,title:w}),{success:!0,entityId:I,existed:!1,requested:1}}}var QL1={critical:0,high:1,medium:2,low:3};function BL1(A){A.sort((Q,B)=>{let w=B.metadata.requested-Q.metadata.requested;if(w!==0)return w;return QL1[Q.metadata.priority]-QL1[B.metadata.priority]})}var wL1={name:"@brains/wishlist",private:!0,version:"0.2.0-alpha.127",description:"Wishlist plugin for tracking unfulfilled user requests",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class $L1 extends _Q{entityType=SmA.entityType;schema=Jr;adapter=SmA;constructor(A={}){super("wishlist",wL1,A,xmA)}async interceptCreate(A,Q,B){let w=await new B9A(this.logger,B).process({...A.title?{title:A.title}:{},...A.prompt?{prompt:A.prompt}:{},...A.content?{content:A.content}:{}},`wish-create-${Date.now()}`,{});if(!w.success)return{kind:"handled",result:{success:!1,error:w.error??"Failed to create wish"}};return{kind:"handled",result:{success:!0,data:{...w.entityId?{entityId:w.entityId}:{},status:w.existed?"updated":"created"}}}}async onRegister(A){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:"top-wishes",pluginId:this.id,title:"Top Wishes",section:"secondary",priority:30,rendererName:"ListWidget",dataProvider:async()=>{let B=await A.entityService.listEntities({entityType:"wish",options:{limit:10}});return BL1(B),{items:B.map((w)=>({id:w.id,name:w.metadata.title,count:w.metadata.requested,priority:w.metadata.priority,status:w.metadata.status}))}}}}),{success:!0}});let Q=new B9A(this.logger,A);A.jobs.registerHandler("wish:create",{process:Q.process.bind(Q),validateAndParse:(B)=>B})}async getInstructions(){return"**CRITICAL \u2014 Wishlist exclusions**: A2A agent-contact requests are never wishlist cases. "+'If a request asks you to ask, message, contact, call, or reach out to an agent, and the target is missing, ambiguous, archived, URL-only, unsaved-domain, or not-yet-saved in the local agent directory, do not call any create tool for a wish. Tell the user to add/save or clarify the agent first. This includes requests that contain a full agent URL, a bare domain like unknown-agent.io, or phrasing like "message this agent URL for me". Only create or save an agent entry if the user explicitly asks you to add or save that agent. '+"**CRITICAL \u2014 Unfulfilled requests**: For other unfulfillable requests, ALWAYS call `system_create` with entityType "+`"wish" BEFORE responding when you cannot fulfill a user's request. This applies to physical actions, non-agent missing integrations, and any non-agent capability `+"you lack. Physical-world requests like making food, driving somewhere, or doing chores are always wishlist cases. Do NOT just explain you can't do it \u2014 create the wish first, THEN respond. "+"Never claim the request was added to the wishlist unless you actually called system_create for the wish. In your response, tell the user their request has been added to the wishlist."}}function JkQ(A={}){return new $L1(A)}var w9A=JkQ;aA();WA();aA();var Wr=H.object({title:H.string(),target:H.string()}),fL1=H.object({title:H.string(),target:H.string(),slug:H.string().optional()}),Hr=A2.extend({entityType:H.literal("prompt"),metadata:fL1});aA();WA();class gmA extends q2{constructor(){super({entityType:"prompt",schema:Hr,frontmatterSchema:Wr})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,Wr);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,Wr),B=X1(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:B}}}}var $9A=new gmA;var IL1={name:"@brains/prompt",private:!0,version:"0.2.0-alpha.127",description:"Prompt entity type \u2014 AI prompts as editable markdown entities",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","bun-types":"latest",typescript:"^5.3.3"}};class hmA extends _Q{entityType=$9A.entityType;schema=Hr;adapter=$9A;constructor(){super("prompt",IL1,{},void 0)}getEntityTypeConfig(){return{embeddable:!1}}}function RC(){return new hmA}aA();WA();class f9A{apiKey;fetchFn;baseUrl="https://api.unsplash.com";constructor(A,Q){this.apiKey=A,this.fetchFn=Q}async searchPhotos(A,Q){let B=new URL(`${this.baseUrl}/search/photos`);B.searchParams.set("query",A),B.searchParams.set("page",String(Q.page)),B.searchParams.set("per_page",String(Q.perPage));let w=await this.fetchFn(B.toString(),{headers:{Authorization:`Client-ID ${this.apiKey}`}});if(!w.ok)throw Error(`Unsplash API error: ${w.status} ${w.statusText}`);let $=await w.json();return{photos:$.results.map(WkQ),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}function WkQ(A){return{id:A.id,description:A.description,altDescription:A.alt_description,thumbnailUrl:A.urls.thumb,imageUrl:A.urls.regular,photographerName:A.user.name,photographerUrl:A.user.links.html,sourceUrl:A.links.html,downloadLocation:A.links.download_location,width:A.width,height:A.height}}WA();var DL1={query:H.string().describe("Search terms for stock photos"),perPage:H.number().min(1).max(30).default(10).describe("Results per page (1-30)"),page:H.number().min(1).default(1).describe("Page number")},UL1={photoId:H.string().describe("Photo ID from search results"),downloadLocation:H.string().url().describe("Download tracking URL (required by provider ToS)"),photographerName:H.string().describe("Photographer name for attribution"),photographerUrl:H.string().url().describe("Photographer profile URL for attribution"),sourceUrl:H.string().url().describe("Photo page URL on provider"),imageUrl:H.string().url().describe("Image URL to download"),title:H.string().optional().describe("Image entity title"),alt:H.string().optional().describe("Alt text for the image"),targetEntityType:H.string().optional().describe("Entity type to set cover image on"),targetEntityId:H.string().optional().describe("Entity ID to set cover image on")};function YL1(A,Q){return[HkQ(A,Q),GkQ(A,Q)]}function HkQ(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:DL1,handler:async(B)=>{let w=H.object(DL1).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};try{return{success:!0,data:await Q.provider.searchPhotos(w.data.query,{page:w.data.page,perPage:w.data.perPage})}}catch($){return{success:!1,error:$ instanceof Error?$.message:"Search failed"}}}}}function GkQ(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:UL1,handler:async(B)=>{let w=H.object(UL1).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{photoId:$,downloadLocation:f,photographerName:I,photographerUrl:D,sourceUrl:U,imageUrl:Y,title:J,alt:X,targetEntityType:G,targetEntityId:Z}=w.data,N={photographerName:I,photographerUrl:D,sourceUrl:U},V=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:Y}}}});if(V[0]){let O={imageEntityId:V[0].id,alreadyExisted:!0,attribution:N};if(G&&Z)await KkQ(Q.entityService,G,Z,V[0].id),O.coverSet=!0;return{success:!0,data:O}}let L=await Q.jobs.enqueue({type:"select-photo",data:{photoId:$,downloadLocation:f,photographerName:I,photographerUrl:D,sourceUrl:U,imageUrl:Y,...J!==void 0?{title:J}:{},...X!==void 0?{alt:X}:{},...G!==void 0?{targetEntityType:G}:{},...Z!==void 0?{targetEntityId:Z}:{}}}),M={imageEntityId:$,alreadyExisted:!1,attribution:N,jobId:L,status:"generating"};if(G&&Z)M.coverSet=!0;return{success:!0,data:M}}}}async function KkQ(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}aA();WA();C7();var FkQ=H.object({photoId:H.string(),downloadLocation:H.string().url(),photographerName:H.string(),photographerUrl:H.string().url(),sourceUrl:H.string().url(),imageUrl:H.string().url(),title:H.string().optional(),alt:H.string().optional(),targetEntityType:H.string().optional(),targetEntityId:H.string().optional()});class mmA extends ZB{deps;constructor(A,Q){super(A,{schema:FkQ,jobTypeName:"select-photo"});this.deps=Q}async process(A,Q,B){await this.reportProgress(B,{progress:10,message:"Tracking stock photo download"}),await this.deps.provider.triggerDownload(A.downloadLocation),await this.reportProgress(B,{progress:35,message:"Downloading stock photo"});let w=await this.deps.fetchImage(A.imageUrl),$=A.title??`Stock photo ${A.photoId}`,f=mI.createImageEntity({dataUrl:w,title:$,alt:A.alt??$});await this.reportProgress(B,{progress:75,message:"Saving stock photo"});let{entityId:I}=await this.deps.entityService.createEntity({entity:{id:A.photoId,...f,metadata:{...f.metadata,sourceUrl:A.imageUrl}}}),D={imageEntityId:I,alreadyExisted:!1};if(A.targetEntityType&&A.targetEntityId)await ZkQ(this.deps.entityService,A.targetEntityType,A.targetEntityId,I),D.coverSet=!0;return await this.reportProgress(B,{progress:100,message:"Stock photo selected"}),D}summarizeDataForLog(A){return{photoId:A.photoId,hasTarget:A.targetEntityType!==void 0}}}async function ZkQ(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}C7();var JL1={name:"@brains/stock-photo",private:!0,version:"0.2.0-alpha.127",description:"Stock photo search and selection \u2014 Unsplash provider",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var zkQ=H.object({provider:H.enum(["unsplash"]).default("unsplash"),apiKey:H.string().optional().describe("Stock photo provider API key")});class umA extends YB{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",JL1,A,zkQ);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=YL1(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??qU,jobs:A.jobs}),this.cachedTools}async registerJobHandlers(){if(!this.config.apiKey)return;let A=this.getContext();A.jobs.registerHandler("select-photo",new mmA(this.logger.child("SelectPhotoJobHandler"),{provider:this.createProvider(),entityService:A.entityService,fetchImage:this.deps.fetchImage??qU}))}createProvider(){return new f9A(this.config.apiKey??"",this.deps.fetch??globalThis.fetch)}}function cmA(A={},Q={}){return new umA(A,Q)}aA();WA();aA();aA();WA();var XL1=H.enum(["ai","foundation","work"]),WL1=H.object({suffix:XL1,title:H.string(),body:H.string(),linkLabel:H.string(),linkHref:H.string()}),Gr=H.object({eyebrow:H.string(),headline:H.string(),cards:H.array(WL1).min(1)}),I9A=H.object({title:H.string(),slug:H.string(),status:H.enum(["draft","published"])}),Kr=A2.extend({entityType:H.literal("ecosystem-section"),metadata:I9A});class HL1 extends q2{constructor(){super({entityType:"ecosystem-section",schema:Kr,frontmatterSchema:I9A})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var lmA=new HL1;WA();function qkQ(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function pmA(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function Fr(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function D9A(A){let Q=qkQ(A),w=pmA(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return Gr.parse({eyebrow:pmA(Q,"Eyebrow"),headline:pmA(Q,"Headline"),cards:w.map(($)=>({suffix:Fr($,"Suffix"),title:Fr($,"Title"),body:Fr($,"Body"),linkLabel:Fr($,"Link Label"),linkHref:Fr($,"Link Href")}))})}function GL1(A){return["# Ecosystem Section","","## Eyebrow",A.eyebrow,"","## Headline",A.headline,"","## Cards","",...A.cards.flatMap((Q,B)=>[`### Card ${B+1}`,"","#### Suffix",Q.suffix,"","#### Title",Q.title,"","#### Body",Q.body,"","#### Link Label",Q.linkLabel,"","#### Link Href",Q.linkHref,""])].join(`
|
|
8187
8187
|
`)}var LkQ=H.object({query:H.object({id:H.string().optional()}).optional()}).passthrough();class U9A{id="rizom-ecosystem:entities";name="Rizom Ecosystem";description="Fetches an ecosystem-section entity for rendering";async fetch(A,Q,B){let $=LkQ.parse(A??{}).query?.id??"rizom-ecosystem",f=await B.entityService.getEntity({entityType:"ecosystem-section",id:$});if(!f)throw Error(`Ecosystem section not found: ${$}`);return Q.parse(D9A(f.content))}}aA();var VkQ=ywA({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 pH(...A){return VkQ(L_(A))}import{jsxDEV as P$8}from"preact/jsx-dev-runtime";import{jsxDEV as v$8}from"preact/jsx-dev-runtime";import{jsxDEV as S$8}from"preact/jsx-dev-runtime";import{jsxDEV as MkQ}from"preact/jsx-dev-runtime";var imA="px-6 md:px-10 xl:px-20",EkQ=`${imA} relative z-[1]`,rmA=({id:A,className:Q,children:B})=>MkQ("section",{id:A,className:pH(EkQ,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as Y9A}from"preact/jsx-dev-runtime";var CkQ=new Map([["work","text-accent"],["foundation","text-secondary"],["ai","text-accent-bright"]]),Zr=({name:A="rizom",brandSuffix:Q,className:B,dotClassName:w,suffixClassName:$})=>{let f=CkQ.get(Q);return Y9A("span",{className:pH("inline-flex items-baseline gap-0 font-display font-medium tracking-[-0.015em] [font-variation-settings:'opsz'_24]",B),children:[Y9A("span",{className:"text-theme",children:A},void 0,!1,void 0,this),Y9A("span",{className:pH(f??"text-accent",w),children:"."},void 0,!1,void 0,this),Y9A("span",{className:pH("italic font-normal text-theme-muted",$),children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as o$8}from"preact/jsx-dev-runtime";import{jsxDEV as e$8}from"preact/jsx-dev-runtime";import{jsxDEV as w98,Fragment as B98}from"preact/jsx-dev-runtime";import{jsxDEV as I98}from"preact/jsx-dev-runtime";import{Fragment as dmA}from"preact";import{jsxDEV as Nr}from"preact/jsx-dev-runtime";var OkQ=/(\*[^*]+\*)/;function nmA(A,Q){let B=A.split(`
|
|
8188
|
-
`);return Nr(dmA,{children:B.map((w,$)=>Nr(dmA,{children:[$>0&&Nr("br",{},void 0,!1,void 0,this),w.split(OkQ).map((f,I)=>{if(f.length>=3&&f.startsWith("*")&&f.endsWith("*"))return Nr("span",{className:Q,children:f.slice(1,-1)},I,!1,void 0,this);return Nr(dmA,{children:f},I,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as nf,Fragment as SkQ}from"preact/jsx-dev-runtime";var RkQ="italic text-accent font-normal",bkQ="You are here",PkQ={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},kkQ={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},jkQ={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},_kQ="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",vkQ="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",ykQ="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",TkQ="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",xkQ=({card:A})=>{let Q=A.linkLabel===bkQ,B=A.linkHref.trim().length===0,w=nf(SkQ,{children:[nf(Zr,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),nf("span",{className:`${_kQ} ${PkQ[A.suffix]}`,children:A.title},void 0,!1,void 0,this),nf("p",{className:vkQ,children:A.body},void 0,!1,void 0,this),Q?nf("span",{className:TkQ,children:A.linkLabel},void 0,!1,void 0,this):nf("span",{className:ykQ,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?kkQ[A.suffix]:"border-white/10"}`;return Q||B?nf("div",{className:$,children:w},void 0,!1,void 0,this):nf("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${jkQ[A.suffix]}`,children:w},void 0,!1,void 0,this)},omA=({eyebrow:A,headline:Q,cards:B})=>nf(rmA,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[nf("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[nf("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),nf("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:nmA(Q,RkQ)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),nf("div",{className:"mx-auto grid max-w-[1180px] grid-cols-3 gap-16 max-[768px]:grid-cols-1 max-[768px]:gap-7",children:B.map((w)=>nf(xkQ,{card:w},w.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);var gkQ=[{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 KL1(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:gkQ.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var hkQ=KL1();var smA=P1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:Gr,formatter:{parse:D9A,format:GL1},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:omA}});var FL1={name:"@brains/rizom-ecosystem",private:!0,version:"0.2.0-alpha.
|
|
8188
|
+
`);return Nr(dmA,{children:B.map((w,$)=>Nr(dmA,{children:[$>0&&Nr("br",{},void 0,!1,void 0,this),w.split(OkQ).map((f,I)=>{if(f.length>=3&&f.startsWith("*")&&f.endsWith("*"))return Nr("span",{className:Q,children:f.slice(1,-1)},I,!1,void 0,this);return Nr(dmA,{children:f},I,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as nf,Fragment as SkQ}from"preact/jsx-dev-runtime";var RkQ="italic text-accent font-normal",bkQ="You are here",PkQ={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},kkQ={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},jkQ={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},_kQ="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",vkQ="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",ykQ="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",TkQ="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",xkQ=({card:A})=>{let Q=A.linkLabel===bkQ,B=A.linkHref.trim().length===0,w=nf(SkQ,{children:[nf(Zr,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),nf("span",{className:`${_kQ} ${PkQ[A.suffix]}`,children:A.title},void 0,!1,void 0,this),nf("p",{className:vkQ,children:A.body},void 0,!1,void 0,this),Q?nf("span",{className:TkQ,children:A.linkLabel},void 0,!1,void 0,this):nf("span",{className:ykQ,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?kkQ[A.suffix]:"border-white/10"}`;return Q||B?nf("div",{className:$,children:w},void 0,!1,void 0,this):nf("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${jkQ[A.suffix]}`,children:w},void 0,!1,void 0,this)},omA=({eyebrow:A,headline:Q,cards:B})=>nf(rmA,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[nf("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[nf("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),nf("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:nmA(Q,RkQ)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),nf("div",{className:"mx-auto grid max-w-[1180px] grid-cols-3 gap-16 max-[768px]:grid-cols-1 max-[768px]:gap-7",children:B.map((w)=>nf(xkQ,{card:w},w.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);var gkQ=[{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 KL1(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:gkQ.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var hkQ=KL1();var smA=P1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:Gr,formatter:{parse:D9A,format:GL1},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:omA}});var FL1={name:"@brains/rizom-ecosystem",private:!0,version:"0.2.0-alpha.127",description:"Entity-backed Rizom ecosystem section",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@rizom/ui":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class amA extends _Q{entityType="ecosystem-section";schema=Kr;adapter=lmA;constructor(A={}){super("rizom-ecosystem",FL1,A,H.object({}).default({}))}getTemplates(){return{ecosystem:smA}}getDataSources(){return[new U9A]}}function bC(A={}){return new amA(A)}WA();aA();aA();WA();t$();WA();aA();var e9="agent",ZL1="agent-discovery",NL1="agent:generation",zL1="agent-network",qL1="AgentNetworkWidget",zr="agent-discovery:entities",tmA="agent-list",emA="agent-detail",a6="skill",LL1="skill",J9A="skill-derivation",VL1="skill:project",EL1="skill-derivation",ML1="skill:skill-derivation",CL1="skills";var ov=H.object({name:H.string(),description:H.string(),tags:H.array(H.string())}),$Y=H.enum(["discovered","approved"]).describe("Discovered for review or approved for calling"),NX=oY.pick({name:!0,kind:!0,organization:!0}).extend({brainName:H.string().describe("Name of the brain instance"),url:H.string().url().describe("Brain endpoint URL"),did:H.string().optional().describe("Decentralized identifier (public)"),repoDid:H.string().optional().describe("ATProto repo DID"),brainDid:H.string().optional().describe("ATProto brain DID"),anchorDid:H.string().optional().describe("ATProto anchor DID"),cardUri:H.string().optional().describe("ATProto brain card URI"),cardCid:H.string().optional().describe("ATProto brain card CID"),a2aEndpoint:H.string().url().optional().describe("A2A endpoint URL"),status:$Y,discoveredAt:H.string().datetime().describe("When this agent was first discovered")}),OL1=NX.pick({name:!0,url:!0,status:!0}).extend({discoveredAt:H.string().datetime().optional(),slug:H.string(),repoDid:H.string().optional(),brainDid:H.string().optional(),anchorDid:H.string().optional(),cardUri:H.string().optional(),cardCid:H.string().optional(),a2aEndpoint:H.string().url().optional()}),sv=A2.extend({entityType:H.literal(e9),metadata:OL1}),qr=sv.extend({frontmatter:NX,about:H.string(),skills:H.array(ov),notes:H.string()}),av=qr.extend({url:H.string().optional(),typeLabel:H.string().optional()}),ukQ=qr.extend({url:H.string(),typeLabel:H.string()});WA();var ckQ=H.array(ov);function RL1(A){let Q=ckQ.safeParse(A);if(!Q.success||Q.data.length===0)return"";return Q.data.map((B)=>{let w=B.tags.length>0?` [${B.tags.join(", ")}]`:"";return`- ${B.name}: ${B.description}${w}`}).join(`
|
|
8189
8189
|
`)}function bL1(A){if(!A.trim())return[];let Q=[];for(let B of A.split(`
|
|
8190
8190
|
`)){let w=B.match(/^- (.+?): (.+?)(?:\s+\[(.+?)\])?$/);if(!w)continue;let $=w[1]??"",f=w[2]??"",I=w[3],D=I?I.split(",").map((U)=>U.trim()).filter(Boolean):[];Q.push({name:$,description:f,tags:D})}return Q}var lkQ=H.object({about:H.string(),skills:H.array(ov),notes:H.string()}),PL1=new lB(lkQ,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:RL1,parser:bL1},{key:"notes",label:"Notes",type:"string"}]});class of extends q2{constructor(){super({entityType:e9,schema:sv,frontmatterSchema:NX})}fromMarkdown(A){let Q=this.parseFrontMatter(A,NX),B=fN(Q.url);return{content:A,entityType:e9,metadata:{name:Q.name,url:Q.url,status:Q.status,discoveredAt:Q.discoveredAt,slug:B,...Q.repoDid&&{repoDid:Q.repoDid},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},...Q.cardUri&&{cardUri:Q.cardUri},...Q.cardCid&&{cardCid:Q.cardCid},...Q.a2aEndpoint&&{a2aEndpoint:Q.a2aEndpoint}}}}createAgentContent(A){let Q={name:A.name,kind:A.kind,...A.organization&&{organization:A.organization},brainName:A.brainName,url:A.url,...A.did&&{did:A.did},...A.repoDid&&{repoDid:A.repoDid},...A.brainDid&&{brainDid:A.brainDid},...A.anchorDid&&{anchorDid:A.anchorDid},...A.cardUri&&{cardUri:A.cardUri},...A.cardCid&&{cardCid:A.cardCid},...A.a2aEndpoint&&{a2aEndpoint:A.a2aEndpoint},status:$Y.parse(A.status),discoveredAt:A.discoveredAt},B=PL1.format({about:A.about,skills:A.skills,notes:A.notes});return this.buildMarkdown(B,Q)}parseAgentContent(A){let Q=this.extractBody(A);if(!Q.trim())return{about:"",skills:[],notes:""};try{let B=PL1.parse(Q);return{about:B.about,skills:B.skills,notes:B.notes}}catch{return{about:"",skills:[],notes:""}}}parseEntity(A){return{frontmatter:this.parseFrontMatter(A.content,NX),body:this.parseAgentContent(A.content)}}}aA();var pkQ=new of,ikQ=UW.extend({status:$Y.optional()}),rkQ=YW.extend({query:ikQ.optional()});function dkQ(A){let Q=b2(A.content,NX),B=pkQ.parseAgentContent(A.content);return qr.parse({...A,frontmatter:Q.metadata,about:B.about,skills:B.skills,notes:B.notes})}class X9A extends u5{id=zr;name="Agent Directory DataSource";description="Fetches and transforms agent entities for rendering";config={entityType:e9,defaultSort:[{field:"discoveredAt",direction:"desc"}],defaultLimit:50,lookupField:"slug",enableNavigation:!0};constructor(A){super(A)}transformEntity(A){return dkQ(A)}buildDetailResult(A,Q){return{agent:A,prevAgent:Q?.prev??null,nextAgent:Q?.next??null}}parseQuery(A){let Q=rkQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}buildListResult(A,Q,B){let w=$Y.safeParse(B.status);return{agents:A,pagination:Q,baseUrl:B.baseUrl,selectedStatus:w.success?w.data:"all"}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A);if(w.id)return super.fetch(A,Q,B);let{items:$,pagination:f}=await this.fetchList(w,B.entityService,w.status?{filter:{metadata:{status:w.status}}}:void 0);return Q.parse(this.buildListResult($,f,w))}}aA();WA();o8();aA();async function kL1(A,Q){let w=`${(A.startsWith("http")?A:`https://${A}`).replace(/\/$/,"")}/.well-known/agent-card.json`;try{let $=await Q(w);if(!$.ok)return null;let f=await $.json();return px(f)}catch{return null}}function W9A(A){let Q=A.trim();if(Q.startsWith("http://")||Q.startsWith("https://"))try{return new URL(Q).hostname}catch{return Q}let B=Q.match(/https?:\/\/[^\s]+?(?=[.,;:!?)]*(?:\s|$))/);if(B)try{return new URL(B[0]).hostname}catch{return B[0]}if(/^[^\s]+\.[^\s]+$/.test(Q))return Q;return""}WA();var nkQ=new of;function jL1(A){return A.trim().toLowerCase().replace(/[_\s]+/g,"-")}function Iq(A){let Q=new Set,B=[];for(let w of A){let $=jL1(w);if(!$||Q.has($))continue;Q.add($),B.push($)}return B}function okQ(A,Q){if(Q.count!==A.count)return Q.count-A.count;return A.tag.localeCompare(Q.tag)}async function _L1(A,Q={}){let B=Q.minCount??1,w=Q.topN??12,$=Q.visibilityScope??"public",f=new Map,[I,D]=await Promise.all([A.entityService.listEntities({entityType:a6,options:{filter:{visibilityScope:$}}}),A.entityService.listEntities({entityType:e9,options:{filter:{visibilityScope:$}}})]),U=(Y)=>{for(let J of Iq(Y))f.set(J,(f.get(J)??0)+1)};for(let Y of I)U(Y.metadata.tags);for(let Y of D){let J=nkQ.parseAgentContent(Y.content);U(J.skills.flatMap((X)=>X.tags))}return Array.from(f.entries()).map(([Y,J])=>({tag:Y,count:J})).filter((Y)=>Y.count>=B).sort(okQ).slice(0,w)}function vL1(A){if(A.length===0)return"";return["Current agent-directory tag vocabulary (reuse existing tags where they fit; propose new only when nothing does):",...A.map(({tag:Q,count:B})=>`- ${Q} (${B})`)].join(`
|
|
8191
8191
|
`)}var skQ=new of;function yL1(A,Q={}){let B=A.anchor?.name??A.brainName,w=A.anchor?.kind??"professional",$=[];if(A.anchor?.description)$.push(A.anchor.description);if(A.description)$.push(A.description);let f=Q.status??"discovered",I=new Date().toISOString();return{content:skQ.createAgentContent({name:B,kind:w,...A.anchor?.organization&&{organization:A.anchor.organization},brainName:A.brainName,url:A.url,status:f,discoveredAt:I,about:$.join(`
|
|
@@ -8286,7 +8286,7 @@ ${sX(B)}---
|
|
|
8286
8286
|
setTagFilter("all");
|
|
8287
8287
|
});
|
|
8288
8288
|
})();`;import{jsxDEV as nQ}from"preact/jsx-dev-runtime";function fjQ({item:A}){return nQ("li",{class:"list-item",children:[nQ("div",{class:"list-main",children:[nQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this),nQ("span",{class:"list-desc",children:A.description},void 0,!1,void 0,this),A.tags.length>0&&nQ("div",{class:"list-tags",children:A.tags.map((Q)=>nQ("span",{class:"tag",children:Q},`${A.id}:${Q}`,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),nQ("div",{class:"list-meta",children:A.status==="discovered"&&nQ("span",{class:"pill pill--warn",children:"review"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function IjQ({item:A}){return nQ("li",{class:"list-item agent-network-skill-row","data-agent-network-skill-row":!0,"data-agent-network-tags":JSON.stringify(A.tags),children:[nQ("div",{class:"list-main",children:nQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this)},void 0,!1,void 0,this),nQ("div",{class:"list-meta",children:nQ("span",{class:`agent-network-source${A.sourceType==="brain"?" is-brain":""}`,children:A.sourceLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function DjQ({kind:A,items:Q,active:B}){return nQ("div",{class:`agent-network-panel${B?" is-active":""}`,"data-agent-network-panel":A,children:Q.length>0?nQ("ul",{class:"list agent-network-list",children:Q.map((w)=>nQ(fjQ,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):nQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function UjQ({skills:A,count:Q,filters:B}){return nQ("div",{class:"agent-network-panel","data-agent-network-panel":"skills",children:[nQ("div",{class:"agent-network-filter-row",role:"tablist","aria-label":"Filter skills by tag",children:[nQ("button",{class:"agent-network-filter is-active",type:"button","data-agent-network-tag-filter":"all","aria-pressed":"true",children:[nQ("span",{class:"count",children:Q},void 0,!1,void 0,this),nQ("span",{class:"label",children:"all"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B.map((w)=>nQ("button",{class:`agent-network-filter${w.variant==="gap"?" is-gap":""}`,type:"button","data-agent-network-tag-filter":w.tag,"aria-pressed":"false",children:[nQ("span",{class:"count",children:w.count},void 0,!1,void 0,this),nQ("span",{class:"label",children:w.tag},void 0,!1,void 0,this)]},w.tag,!0,void 0,this))]},void 0,!0,void 0,this),A.length>0?nQ("ul",{class:"list agent-network-list agent-network-skills-list",children:A.map((w)=>nQ(IjQ,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):nQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function BuA({data:A}){let Q=mL1.safeParse(A);if(!Q.success)return nQ("p",{class:"muted",children:"Nothing to show yet."},void 0,!1,void 0,this);let B=Q.data;return nQ("div",{"data-agent-network-widget":!0,"data-agent-network-view":"agents",children:[nQ("div",{class:"agent-network-view-tabs",role:"tablist","aria-label":"Browse the agent network",children:[nQ("button",{class:"agent-network-view-tab is-active",type:"button","data-agent-network-view-tab":"agents","aria-pressed":"true",children:["Agents",nQ("span",{class:"agent-network-view-count",children:B.counts.agents},void 0,!1,void 0,this)]},void 0,!0,void 0,this),nQ("button",{class:"agent-network-view-tab",type:"button","data-agent-network-view-tab":"skills","aria-pressed":"false",children:["Skills",nQ("span",{class:"agent-network-view-count",children:B.counts.skills},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),nQ("div",{class:"agent-network-kind-tabs",role:"tablist","aria-label":"Filter agents by kind",children:QuA.map((w)=>{let $=w==="all";return nQ("button",{class:`agent-network-kind-tab${$?" is-active":""}`,type:"button","data-agent-network-kind-tab":w,"aria-pressed":$?"true":"false",children:[nQ("span",{class:"agent-network-kind-count",children:B.agents[w].length},void 0,!1,void 0,this),nQ("span",{class:"agent-network-kind-label",children:w},void 0,!1,void 0,this)]},w,!0,void 0,this)})},void 0,!1,void 0,this),QuA.map((w)=>nQ(DjQ,{kind:w,items:B.agents[w],active:w==="all"},w,!1,void 0,this)),nQ(UjQ,{skills:B.skills,count:B.counts.skills,filters:B.skillFilters},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function cL1(A,Q){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:zL1,pluginId:Q,title:"Agent Network",section:"secondary",priority:15,rendererName:qL1,component:BuA,clientScript:G9A,dataProvider:async()=>uL1(A)}}),{success:!0}})}WA();var lL1=new of;function YjQ(A){return A.skills.map((Q)=>({name:Q.name,description:Q.description,tags:Q.tags??[]}))}function JjQ(A){return new URL(A).hostname}function XjQ(A){return[`ATProto card: ${A.uri}`,`ATProto card CID: ${A.cid}`,`ATProto repo DID: ${A.repoDid}`].join(`
|
|
8289
|
-
`)}function WjQ(A){let Q=A.record.brain.did,B=A.record.anchor.did;return{agentId:A.agent.id,name:A.agent.metadata.name,url:A.agent.metadata.url,status:A.agent.metadata.status,repoDid:A.repoDid,...Q&&{brainDid:Q},...B&&{anchorDid:B},cardUri:A.uri,cardCid:A.cid}}async function HjQ(A,Q,B){await A.messaging.send({type:Q,payload:B,broadcast:!0})}async function GjQ(A,Q,B=new Date().toISOString()){let{record:w}=Q,$=JjQ(w.siteUrl),f=await A.entityService.getEntity({entityType:"agent",id:$}),I=f?lL1.parseEntity(f):void 0,D=w.brain.did,U=w.anchor.did,Y=YjQ(w),J=f?.metadata.status??"discovered",X=f?.metadata.url??w.siteUrl,G=f?.metadata.slug??fN(X),Z=f?.metadata.name??w.anchor.name,N=I?.frontmatter.kind??w.anchor.kind,V=f?.metadata.discoveredAt??B,L=w.brain.purpose||I?.body.about||"",M=Y.length>0?Y:I?.body.skills??[],O={...f?.metadata??{},name:Z,url:X,status:J,discoveredAt:V,slug:G,repoDid:Q.repoDid,...D&&{brainDid:D},...U&&{anchorDid:U},cardUri:Q.uri,cardCid:Q.cid},E=lL1.createAgentContent({name:Z,kind:N,...I?.frontmatter.organization&&{organization:I.frontmatter.organization},brainName:w.brain.name,url:X,...D&&{did:D,brainDid:D},...U&&{anchorDid:U},repoDid:Q.repoDid,cardUri:Q.uri,cardCid:Q.cid,...I?.frontmatter.a2aEndpoint&&{a2aEndpoint:I.frontmatter.a2aEndpoint},status:J,discoveredAt:V,about:L,skills:M,notes:XjQ({repoDid:Q.repoDid,uri:Q.uri,cid:Q.cid})});if(f){let T={...f,content:E,metadata:O,updated:B};return await A.entityService.updateEntity({entity:T}),{agent:T,created:!1}}let S={id:$,entityType:"agent",content:E,metadata:O,contentHash:"",visibility:"public",created:B,updated:B};return await A.entityService.createEntity({entity:S}),{agent:S,created:!0}}function pL1(A){A.messaging.subscribe(K5A,async(Q)=>{let B=oK1.parse(Q.payload),w=await GjQ(A,B),$=WjQ({agent:w.agent,repoDid:B.repoDid,uri:B.uri,cid:B.cid,record:B.record});return await HjQ(A,w.created?dK1:nK1,$),{success:!0,data:$}})}function iL1(){return'## Agent directory\n\nThese rules govern the local `agent` directory and agent-contact requests. They override the general wishlist rule and the general "always attempt tool calls" rule.\n\n### Directory CRUD\n- Add a new agent contact with `system_create` using `entityType: "agent"` and pass the domain or URL in `url`.\n- List saved agents with `system_list` using `entityType: "agent"`.\n- Approve a discovered agent with `system_update` on the `agent` entity using `fields` (for example `fields: { status: "approved" }`). Do not replace the full content just to change status.\n- When the user explicitly says `approve`, `approve it`, `yes approve`, or `approve <agent-id>`, call `system_update` immediately with `fields: { status: "approved" }` and let the standard confirmation flow ask the user to confirm. Never pass `confirmed: true` on the initial approval request.\n- If the previous turn identified one specific discovered agent, treat a short follow-up like `approve`, `approve it`, or `yes approve` as referring to that same agent id.\n- If `system_update` succeeds for an approval request, answer plainly that the agent is now approved. Do not say the operation failed, and do not ask to retry, unless the tool actually failed.\n- If `system_update` says to use `fields`, or says full content replacement is invalid/empty, retry once immediately with `fields` instead of surfacing that error to the user.\n- If the user gives an exact saved agent id like `old-agent.io`, call that single `system_update` directly instead of listing/searching first.\n\n### Contact requests (ask / talk to / what does X say)\n- Treat phrases like `what does <agent> have to say`, `what would <agent> say/think`, and asking a saved agent for its own skills/capabilities as contact requests. For an exact saved local agent id such as `yeehaa.io` or `docs.rizom.ai`, use `a2a_call` rather than answering from local saved agent metadata, unless the user explicitly asks for directory/profile details.\n- If a previous turn contacted an exact saved agent id with `a2a_call`, a follow-up like `what skills does it have`, `what does it say about X`, or `tell me more` is another contact request to the same saved agent. Call `a2a_call` again with that id, even if the previous remote response was a refusal or error. Do not inspect or summarize local `agent` metadata for these follow-ups.\n- If the user uses a display/contact name like `Brain` rather than an exact saved id, first inspect saved agents with `system_list({ entityType: "agent" })`. If multiple saved agents could match, ask which one and do not call any tool. Never choose the first match.\n- If a saved agent is archived/removed, do not call it and do not create a wish. Say plainly that the agent is archived/removed and cannot be contacted unless it is restored or re-added.\n\n### Save-first for unsaved agents\n- Calling and saving agents are separate actions. If the user asks to `call`, `talk to`, `ask`, message, contact, or reach out to an unsaved agent domain/URL, do **not** call `system_create` or `a2a_call` on that first request. Tell the user the agent is not yet in the local agent **directory** and ask them to **add/save it first**. The reply must include both the word **directory** (to be clear about what\'s missing) and the phrase **add/save it first**.\n- This applies equally to full URLs (`https://unknown-agent.io/a2a`) and bare domains/ids (`unknown-agent.io`). A URL-based or unsaved-domain agent contact request is a save-first directory case, not a wishlist case.\n- When refusing, cite the agent domain/URL **by name** in your reply (e.g. "you\'ll need to add/save `unknown-agent.io` first") \u2014 do not say "that agent" without naming it. This anchors the domain for any affirmative follow-up.\n- The save-first refusal turn must have **no tool calls**. Do not create a wish, note, reminder, task, or backlog item to remember the blocked contact request. Specifically: never call `system_create` with `entityType: "wish"` for an agent-contact request, and never create any other fallback entity for a missing, archived/removed, or ambiguous agent unless the user explicitly asks you to add/save/unarchive it.\n- In the user-facing save-first refusal, say only that the agent must be in the local directory and ask them to add/save it first. Do not mention wishes, wishlist, backlog, or fallback entities in that response.\n\n### Affirmative follow-up after save-first refusal\n- If a recent user message named exactly one unsaved agent domain/URL and you told them to add/save it first, treat a short affirmative follow-up like `yes`, `yes please`, `please do`, `go ahead`, `do that`, or `save it` as consent to save that same agent immediately with `system_create({ entityType: "agent", url: "that-domain" })`. The trigger is the user\'s prior reference to the domain, not whether your refusal echoed it back.\n- A bare affirmative follow-up is enough. For example, after `Can you talk to save-first-followup.example for me?` and your save-first refusal, `Yes please` means call `system_create({ entityType: "agent", url: "save-first-followup.example" })` immediately.\n- Do **not** repeat the save-first instruction, ask for a description, ask for the domain again, or return an empty response after such an affirmative follow-up; just call `system_create`.\n\n### Examples\n- User: "Ask https://unknown-agent.io about X" \u2192 do **not** call `a2a_call` and do **not** call `system_create` for a wish. Tell them to add/save `unknown-agent.io` first.\n- User: "Can you message this agent URL for me: https://unknown-agent.io/a2a?" \u2192 do **not** create a wish. Tell them the agent must be saved first.\n- User: "Ask Brain about X" with both `yeehaa.io` and `brain-labs.io` saved as "Brain" \u2192 ask the user to choose between those two saved ids and do not call `a2a_call`.'}aA();Xw();WA();import{jsxDEV as rL1}from"preact/jsx-dev-runtime";function K9A(A){try{return new URL(A).hostname}catch{return A}}var F9A=({name:A,className:Q=""})=>{let B=A.charAt(0).toUpperCase(),w=0;for(let f=0;f<A.length;f++)w=A.charCodeAt(f)+((w<<5)-w);let $=Math.abs(w)%360;return rL1("div",{className:`flex items-center justify-center rounded-full text-white font-bold flex-shrink-0 ${Q}`,style:{backgroundColor:`hsl(${$}, 55%, 45%)`},children:B},void 0,!1,void 0,this)},Z9A=({kind:A,size:Q="md"})=>{let w={professional:"bg-status-success text-status-success",team:"bg-status-info text-status-info",collective:"bg-brand/10 text-brand"}[A]??"bg-status-neutral text-status-neutral";return rL1("span",{className:`inline-flex items-center rounded-full font-medium ${Q==="sm"?"px-2 py-0.5 text-xs":"px-2.5 py-0.5 text-[13px]"} ${w}`,children:A},void 0,!1,void 0,this)};import{jsxDEV as L2,Fragment as ZjQ}from"preact/jsx-dev-runtime";var KjQ=({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 FjQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function dL1(A,Q,B){let w=new URLSearchParams({status:Q});if(B>1)w.set("page",String(B));return`${A}?${w.toString()}`}var wuA=({agent:A})=>{let{frontmatter:Q,about:B,skills:w,url:$}=A,f=Q.status==="approved";return L2("a",{href:$,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${f?"":"opacity-70"}`,children:[L2(F9A,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),L2("div",{className:"flex-1 min-w-0",children:[L2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[L2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),L2(Z9A,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&L2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),B&&L2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:B},void 0,!1,void 0,this),f&&L2(KjQ,{skills:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[L2("span",{className:"text-xs text-theme-muted",children:K9A(Q.url)},void 0,!1,void 0,this),L2("span",{className:"text-[11px] text-theme-muted opacity-60",children:f?`Discovered ${FjQ(Q.discoveredAt)}`:"Discovered \xB7 approve before calling"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},nL1=({agents:A,pageTitle:Q,pagination:B,baseUrl:w="/agents",selectedStatus:$})=>{let f=Q??"Agent Directory",I=B?.totalItems??A.length,D=A.filter((G)=>G.frontmatter.status==="approved"),U=A.filter((G)=>G.frontmatter.status==="discovered"),Y=D.length,J=U.length,X=`Your network of ${I} ${I===1?"brain":"brains"} and their anchors`;return L2(ZjQ,{children:[L2(ZQ,{title:f,description:X},void 0,!1,void 0,this),L2("div",{className:"agent-list bg-theme",children:L2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[L2("div",{className:"mb-8 pb-6 border-b border-theme",children:[L2("h1",{className:"text-4xl font-bold text-heading mb-2",children:f},void 0,!1,void 0,this),L2("p",{className:"text-theme-muted mb-4",children:X},void 0,!1,void 0,this),L2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[L2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[I," total"]},void 0,!0,void 0,this),L2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[Y," approved"]},void 0,!0,void 0,this),L2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-theme-muted",children:[J," discovered"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-wrap gap-2 text-sm",children:[L2("a",{href:w,className:`px-3 py-1 rounded-full border transition-colors ${$==="all"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"All"},void 0,!1,void 0,this),L2("a",{href:`${w}?status=approved`,className:`px-3 py-1 rounded-full border transition-colors ${$==="approved"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Approved"},void 0,!1,void 0,this),L2("a",{href:`${w}?status=discovered`,className:`px-3 py-1 rounded-full border transition-colors ${$==="discovered"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Discovered"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$==="all"&&D.length>0&&L2("section",{className:"mb-10",children:[L2("div",{className:"flex items-center justify-between mb-4",children:[L2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),L2("span",{className:"text-sm text-theme-muted",children:D.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col gap-4",children:D.map((G)=>L2(wuA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&U.length>0&&L2("section",{children:[L2("div",{className:"flex items-center justify-between mb-4",children:[L2("div",{children:[L2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),L2("p",{className:"text-sm text-theme-muted",children:"Review and approve these before calling them."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("span",{className:"text-sm text-theme-muted",children:U.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col gap-4",children:U.map((G)=>L2(wuA,{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(wuA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&L2("p",{className:"text-center text-theme-muted py-16",children:"No agents in your directory yet."},void 0,!1,void 0,this),B&&B.totalPages>1&&$==="all"&&L2("div",{className:"mt-12",children:L2(bF,{currentPage:B.currentPage,totalPages:B.totalPages,baseUrl:w},void 0,!1,void 0,this)},void 0,!1,void 0,this),B&&B.totalPages>1&&$!=="all"&&L2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[B.hasPrevPage?L2("a",{href:dL1(w,$,B.currentPage-1),className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted hover:text-heading transition-colors",children:"\u2190 Prev"},void 0,!1,void 0,this):L2("span",{className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted opacity-50",children:"\u2190 Prev"},void 0,!1,void 0,this),L2("span",{className:"text-sm text-theme-muted",children:["Page ",B.currentPage," of ",B.totalPages]},void 0,!0,void 0,this),B.hasNextPage?L2("a",{href:dL1(w,$,B.currentPage+1),className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted hover:text-heading transition-colors",children:"Next \u2192"},void 0,!1,void 0,this):L2("span",{className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted opacity-50",children:"Next \u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as X2,Fragment as LjQ}from"preact/jsx-dev-runtime";function NjQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var Lr=({children:A})=>X2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),zjQ=({skill:A})=>X2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[X2("div",{className:"flex-1",children:[X2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),X2("div",{className:"text-[13px] text-theme-muted",children:A.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.tags.length>0&&X2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>X2("span",{className:"text-[11px] px-2 py-0.5 bg-theme rounded-md text-theme-muted",children:Q},Q,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),qjQ=({label:A,value:Q,valueClassName:B})=>X2("div",{className:"flex justify-between text-[13px]",children:[X2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),X2("span",{className:B??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),oL1=({agent:A,prevAgent:Q,nextAgent:B})=>{let{frontmatter:w,about:$,skills:f,notes:I}=A,D=K9A(w.url),U=w.status==="approved";return X2(LjQ,{children:[X2(ZQ,{title:w.name,description:$||`Agent profile for ${w.name}`},void 0,!1,void 0,this),X2("article",{className:"agent-detail",children:X2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[X2("a",{href:"/agents",className:"text-sm text-theme-muted hover:text-brand transition-colors mb-6 inline-block",children:"\u2190 Back to Directory"},void 0,!1,void 0,this),X2("div",{className:"flex items-start gap-6 mb-8",children:[X2(F9A,{name:w.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),X2("div",{children:[X2("div",{className:"flex items-center gap-3 mb-1",children:[X2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:w.name},void 0,!1,void 0,this),X2(Z9A,{kind:w.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X2("div",{className:"text-base text-theme-muted mb-2",children:w.brainName},void 0,!1,void 0,this),X2("div",{className:"flex items-center gap-3 text-theme-muted",children:[w.organization&&X2("span",{className:"text-[15px]",children:w.organization},void 0,!1,void 0,this),w.organization&&X2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),X2("span",{className:"text-sm",children:["Discovered ",NjQ(w.discoveredAt)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!U&&X2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[X2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),X2("p",{className:"text-sm text-theme-muted",children:"This brain is discovered but not approved yet, so it cannot be called until you approve it."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X2("div",{className:"flex flex-col md:flex-row gap-12",children:[X2("div",{className:"flex-[2] min-w-0",children:[$&&X2("section",{className:"mb-8",children:[X2(Lr,{children:"About"},void 0,!1,void 0,this),X2("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f.length>0&&X2("section",{className:"mb-8",children:[X2(Lr,{children:"Skills"},void 0,!1,void 0,this),X2("div",{className:"flex flex-col gap-2.5",children:f.map((Y)=>X2(zjQ,{skill:Y},Y.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I&&X2("section",{className:"mb-8",children:[X2(Lr,{children:"Notes"},void 0,!1,void 0,this),X2("p",{className:"text-[15px] text-theme leading-relaxed",children:I},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[X2("section",{className:"mb-8",children:[X2(Lr,{children:"Brain"},void 0,!1,void 0,this),X2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[X2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:w.brainName},void 0,!1,void 0,this),w.did&&X2("div",{className:"text-xs text-theme-muted font-mono",children:w.did},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X2("section",{className:"mb-8",children:[X2(Lr,{children:"Connection"},void 0,!1,void 0,this),X2("div",{className:"flex flex-col gap-3",children:[X2("div",{children:[X2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),X2("div",{className:"text-xs text-heading font-mono",children:w.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X2(qjQ,{label:"Status",value:w.status==="approved"?"Approved":"Discovered",valueClassName:w.status==="approved"?"text-status-success font-medium":"text-theme-muted"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X2("a",{href:w.url.replace(/\/a2a\/?$/,""),target:"_blank",rel:"noopener noreferrer",className:"flex items-center justify-center px-5 py-3 bg-theme-dark text-theme-inverse rounded-lg text-sm font-medium hover:opacity-90 transition-opacity",children:["Visit ",D," \u2197"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),(Q??B)&&X2("nav",{className:"mt-12 pt-6 border-t border-theme flex flex-col gap-3 md:flex-row md:items-center md:justify-between",children:[X2("div",{className:"min-h-[1px]",children:Q&&X2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[X2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),X2("span",{className:"text-heading font-medium",children:Q.frontmatter.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X2("div",{className:"min-h-[1px] md:text-right",children:B&&X2("a",{href:B.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[X2("span",{children:"Next \u2192"},void 0,!1,void 0,this),X2("span",{className:"text-heading font-medium",children:B.frontmatter.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};var VjQ=H.object({agents:H.array(av),pageTitle:H.string().optional(),pagination:z7.nullable(),baseUrl:H.string().optional(),selectedStatus:H.union([H.literal("all"),$Y])});function sL1(){return{[tmA]:P1({name:tmA,description:"Agent directory list page template",schema:VjQ,dataSourceId:zr,requiredPermission:"public",layout:{component:nL1}}),[emA]:P1({name:emA,description:"Individual agent profile template",schema:H.object({agent:av,prevAgent:av.nullable(),nextAgent:av.nullable()}),dataSourceId:zr,requiredPermission:"public",layout:{component:oL1}})}}var N9A={name:"@brains/agent-discovery",private:!0,version:"0.2.0-alpha.125",description:"Agent discovery \u2014 brain+anchor contacts and skills",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var MjQ=new of;class $uA extends _Q{entityType=e9;schema=sv;adapter=MjQ;constructor(){super(ZL1,N9A)}interceptCreate(A,Q,B){return TL1(A,Q,B,this.id)}createGenerationHandler(A){return new AuA(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return sL1()}getDataSources(){return[new X9A(this.logger.child("AgentDataSource"))]}async onRegister(A){pL1(A),cL1(A,this.id)}async getInstructions(){return iL1()}}function fuA(){return new $uA}aA();WA();aA();var tv=jI,aL1=jI,Vr=A2.extend({entityType:H.literal(a6),metadata:aL1});aA();class ev extends q2{constructor(){super({entityType:a6,schema:Vr,frontmatterSchema:tv})}fromMarkdown(A){let Q=this.parseFrontMatter(A,tv);return{content:A,entityType:a6,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}aA();WA();var CjQ=H.object({skills:H.array(tv).max(8)}),tL1=P1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:CjQ,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
|
|
8289
|
+
`)}function WjQ(A){let Q=A.record.brain.did,B=A.record.anchor.did;return{agentId:A.agent.id,name:A.agent.metadata.name,url:A.agent.metadata.url,status:A.agent.metadata.status,repoDid:A.repoDid,...Q&&{brainDid:Q},...B&&{anchorDid:B},cardUri:A.uri,cardCid:A.cid}}async function HjQ(A,Q,B){await A.messaging.send({type:Q,payload:B,broadcast:!0})}async function GjQ(A,Q,B=new Date().toISOString()){let{record:w}=Q,$=JjQ(w.siteUrl),f=await A.entityService.getEntity({entityType:"agent",id:$}),I=f?lL1.parseEntity(f):void 0,D=w.brain.did,U=w.anchor.did,Y=YjQ(w),J=f?.metadata.status??"discovered",X=f?.metadata.url??w.siteUrl,G=f?.metadata.slug??fN(X),Z=f?.metadata.name??w.anchor.name,N=I?.frontmatter.kind??w.anchor.kind,V=f?.metadata.discoveredAt??B,L=w.brain.purpose||I?.body.about||"",M=Y.length>0?Y:I?.body.skills??[],O={...f?.metadata??{},name:Z,url:X,status:J,discoveredAt:V,slug:G,repoDid:Q.repoDid,...D&&{brainDid:D},...U&&{anchorDid:U},cardUri:Q.uri,cardCid:Q.cid},E=lL1.createAgentContent({name:Z,kind:N,...I?.frontmatter.organization&&{organization:I.frontmatter.organization},brainName:w.brain.name,url:X,...D&&{did:D,brainDid:D},...U&&{anchorDid:U},repoDid:Q.repoDid,cardUri:Q.uri,cardCid:Q.cid,...I?.frontmatter.a2aEndpoint&&{a2aEndpoint:I.frontmatter.a2aEndpoint},status:J,discoveredAt:V,about:L,skills:M,notes:XjQ({repoDid:Q.repoDid,uri:Q.uri,cid:Q.cid})});if(f){let T={...f,content:E,metadata:O,updated:B};return await A.entityService.updateEntity({entity:T}),{agent:T,created:!1}}let S={id:$,entityType:"agent",content:E,metadata:O,contentHash:"",visibility:"public",created:B,updated:B};return await A.entityService.createEntity({entity:S}),{agent:S,created:!0}}function pL1(A){A.messaging.subscribe(K5A,async(Q)=>{let B=oK1.parse(Q.payload),w=await GjQ(A,B),$=WjQ({agent:w.agent,repoDid:B.repoDid,uri:B.uri,cid:B.cid,record:B.record});return await HjQ(A,w.created?dK1:nK1,$),{success:!0,data:$}})}function iL1(){return'## Agent directory\n\nThese rules govern the local `agent` directory and agent-contact requests. They override the general wishlist rule and the general "always attempt tool calls" rule.\n\n### Directory CRUD\n- Add a new agent contact with `system_create` using `entityType: "agent"` and pass the domain or URL in `url`.\n- List saved agents with `system_list` using `entityType: "agent"`.\n- Approve a discovered agent with `system_update` on the `agent` entity using `fields` (for example `fields: { status: "approved" }`). Do not replace the full content just to change status.\n- When the user explicitly says `approve`, `approve it`, `yes approve`, or `approve <agent-id>`, call `system_update` immediately with `fields: { status: "approved" }` and let the standard confirmation flow ask the user to confirm. Never pass `confirmed: true` on the initial approval request.\n- If the previous turn identified one specific discovered agent, treat a short follow-up like `approve`, `approve it`, or `yes approve` as referring to that same agent id.\n- If `system_update` succeeds for an approval request, answer plainly that the agent is now approved. Do not say the operation failed, and do not ask to retry, unless the tool actually failed.\n- If `system_update` says to use `fields`, or says full content replacement is invalid/empty, retry once immediately with `fields` instead of surfacing that error to the user.\n- If the user gives an exact saved agent id like `old-agent.io`, call that single `system_update` directly instead of listing/searching first.\n\n### Contact requests (ask / talk to / what does X say)\n- Treat phrases like `what does <agent> have to say`, `what would <agent> say/think`, and asking a saved agent for its own skills/capabilities as contact requests. For an exact saved local agent id such as `yeehaa.io` or `docs.rizom.ai`, use `a2a_call` rather than answering from local saved agent metadata, unless the user explicitly asks for directory/profile details.\n- If a previous turn contacted an exact saved agent id with `a2a_call`, a follow-up like `what skills does it have`, `what does it say about X`, or `tell me more` is another contact request to the same saved agent. Call `a2a_call` again with that id, even if the previous remote response was a refusal or error. Do not inspect or summarize local `agent` metadata for these follow-ups.\n- If the user uses a display/contact name like `Brain` rather than an exact saved id, first inspect saved agents with `system_list({ entityType: "agent" })`. If multiple saved agents could match, ask which one and do not call any tool. Never choose the first match.\n- If a saved agent is archived/removed, do not call it and do not create a wish. Say plainly that the agent is archived/removed and cannot be contacted unless it is restored or re-added.\n\n### Save-first for unsaved agents\n- Calling and saving agents are separate actions. If the user asks to `call`, `talk to`, `ask`, message, contact, or reach out to an unsaved agent domain/URL, do **not** call `system_create` or `a2a_call` on that first request. Tell the user the agent is not yet in the local agent **directory** and ask them to **add/save it first**. The reply must include both the word **directory** (to be clear about what\'s missing) and the phrase **add/save it first**.\n- This applies equally to full URLs (`https://unknown-agent.io/a2a`) and bare domains/ids (`unknown-agent.io`). A URL-based or unsaved-domain agent contact request is a save-first directory case, not a wishlist case.\n- When refusing, cite the agent domain/URL **by name** in your reply (e.g. "you\'ll need to add/save `unknown-agent.io` first") \u2014 do not say "that agent" without naming it. This anchors the domain for any affirmative follow-up.\n- The save-first refusal turn must have **no tool calls**. Do not create a wish, note, reminder, task, or backlog item to remember the blocked contact request. Specifically: never call `system_create` with `entityType: "wish"` for an agent-contact request, and never create any other fallback entity for a missing, archived/removed, or ambiguous agent unless the user explicitly asks you to add/save/unarchive it.\n- In the user-facing save-first refusal, say only that the agent must be in the local directory and ask them to add/save it first. Do not mention wishes, wishlist, backlog, or fallback entities in that response.\n\n### Affirmative follow-up after save-first refusal\n- If a recent user message named exactly one unsaved agent domain/URL and you told them to add/save it first, treat a short affirmative follow-up like `yes`, `yes please`, `please do`, `go ahead`, `do that`, or `save it` as consent to save that same agent immediately with `system_create({ entityType: "agent", url: "that-domain" })`. The trigger is the user\'s prior reference to the domain, not whether your refusal echoed it back.\n- A bare affirmative follow-up is enough. For example, after `Can you talk to save-first-followup.example for me?` and your save-first refusal, `Yes please` means call `system_create({ entityType: "agent", url: "save-first-followup.example" })` immediately.\n- Do **not** repeat the save-first instruction, ask for a description, ask for the domain again, or return an empty response after such an affirmative follow-up; just call `system_create`.\n\n### Examples\n- User: "Ask https://unknown-agent.io about X" \u2192 do **not** call `a2a_call` and do **not** call `system_create` for a wish. Tell them to add/save `unknown-agent.io` first.\n- User: "Can you message this agent URL for me: https://unknown-agent.io/a2a?" \u2192 do **not** create a wish. Tell them the agent must be saved first.\n- User: "Ask Brain about X" with both `yeehaa.io` and `brain-labs.io` saved as "Brain" \u2192 ask the user to choose between those two saved ids and do not call `a2a_call`.'}aA();Xw();WA();import{jsxDEV as rL1}from"preact/jsx-dev-runtime";function K9A(A){try{return new URL(A).hostname}catch{return A}}var F9A=({name:A,className:Q=""})=>{let B=A.charAt(0).toUpperCase(),w=0;for(let f=0;f<A.length;f++)w=A.charCodeAt(f)+((w<<5)-w);let $=Math.abs(w)%360;return rL1("div",{className:`flex items-center justify-center rounded-full text-white font-bold flex-shrink-0 ${Q}`,style:{backgroundColor:`hsl(${$}, 55%, 45%)`},children:B},void 0,!1,void 0,this)},Z9A=({kind:A,size:Q="md"})=>{let w={professional:"bg-status-success text-status-success",team:"bg-status-info text-status-info",collective:"bg-brand/10 text-brand"}[A]??"bg-status-neutral text-status-neutral";return rL1("span",{className:`inline-flex items-center rounded-full font-medium ${Q==="sm"?"px-2 py-0.5 text-xs":"px-2.5 py-0.5 text-[13px]"} ${w}`,children:A},void 0,!1,void 0,this)};import{jsxDEV as L2,Fragment as ZjQ}from"preact/jsx-dev-runtime";var KjQ=({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 FjQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function dL1(A,Q,B){let w=new URLSearchParams({status:Q});if(B>1)w.set("page",String(B));return`${A}?${w.toString()}`}var wuA=({agent:A})=>{let{frontmatter:Q,about:B,skills:w,url:$}=A,f=Q.status==="approved";return L2("a",{href:$,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${f?"":"opacity-70"}`,children:[L2(F9A,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),L2("div",{className:"flex-1 min-w-0",children:[L2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[L2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),L2(Z9A,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&L2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),B&&L2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:B},void 0,!1,void 0,this),f&&L2(KjQ,{skills:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[L2("span",{className:"text-xs text-theme-muted",children:K9A(Q.url)},void 0,!1,void 0,this),L2("span",{className:"text-[11px] text-theme-muted opacity-60",children:f?`Discovered ${FjQ(Q.discoveredAt)}`:"Discovered \xB7 approve before calling"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},nL1=({agents:A,pageTitle:Q,pagination:B,baseUrl:w="/agents",selectedStatus:$})=>{let f=Q??"Agent Directory",I=B?.totalItems??A.length,D=A.filter((G)=>G.frontmatter.status==="approved"),U=A.filter((G)=>G.frontmatter.status==="discovered"),Y=D.length,J=U.length,X=`Your network of ${I} ${I===1?"brain":"brains"} and their anchors`;return L2(ZjQ,{children:[L2(ZQ,{title:f,description:X},void 0,!1,void 0,this),L2("div",{className:"agent-list bg-theme",children:L2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[L2("div",{className:"mb-8 pb-6 border-b border-theme",children:[L2("h1",{className:"text-4xl font-bold text-heading mb-2",children:f},void 0,!1,void 0,this),L2("p",{className:"text-theme-muted mb-4",children:X},void 0,!1,void 0,this),L2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[L2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[I," total"]},void 0,!0,void 0,this),L2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[Y," approved"]},void 0,!0,void 0,this),L2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-theme-muted",children:[J," discovered"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-wrap gap-2 text-sm",children:[L2("a",{href:w,className:`px-3 py-1 rounded-full border transition-colors ${$==="all"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"All"},void 0,!1,void 0,this),L2("a",{href:`${w}?status=approved`,className:`px-3 py-1 rounded-full border transition-colors ${$==="approved"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Approved"},void 0,!1,void 0,this),L2("a",{href:`${w}?status=discovered`,className:`px-3 py-1 rounded-full border transition-colors ${$==="discovered"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Discovered"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$==="all"&&D.length>0&&L2("section",{className:"mb-10",children:[L2("div",{className:"flex items-center justify-between mb-4",children:[L2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),L2("span",{className:"text-sm text-theme-muted",children:D.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col gap-4",children:D.map((G)=>L2(wuA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&U.length>0&&L2("section",{children:[L2("div",{className:"flex items-center justify-between mb-4",children:[L2("div",{children:[L2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),L2("p",{className:"text-sm text-theme-muted",children:"Review and approve these before calling them."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("span",{className:"text-sm text-theme-muted",children:U.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col gap-4",children:U.map((G)=>L2(wuA,{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(wuA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&L2("p",{className:"text-center text-theme-muted py-16",children:"No agents in your directory yet."},void 0,!1,void 0,this),B&&B.totalPages>1&&$==="all"&&L2("div",{className:"mt-12",children:L2(bF,{currentPage:B.currentPage,totalPages:B.totalPages,baseUrl:w},void 0,!1,void 0,this)},void 0,!1,void 0,this),B&&B.totalPages>1&&$!=="all"&&L2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[B.hasPrevPage?L2("a",{href:dL1(w,$,B.currentPage-1),className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted hover:text-heading transition-colors",children:"\u2190 Prev"},void 0,!1,void 0,this):L2("span",{className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted opacity-50",children:"\u2190 Prev"},void 0,!1,void 0,this),L2("span",{className:"text-sm text-theme-muted",children:["Page ",B.currentPage," of ",B.totalPages]},void 0,!0,void 0,this),B.hasNextPage?L2("a",{href:dL1(w,$,B.currentPage+1),className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted hover:text-heading transition-colors",children:"Next \u2192"},void 0,!1,void 0,this):L2("span",{className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted opacity-50",children:"Next \u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as X2,Fragment as LjQ}from"preact/jsx-dev-runtime";function NjQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var Lr=({children:A})=>X2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),zjQ=({skill:A})=>X2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[X2("div",{className:"flex-1",children:[X2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),X2("div",{className:"text-[13px] text-theme-muted",children:A.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.tags.length>0&&X2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>X2("span",{className:"text-[11px] px-2 py-0.5 bg-theme rounded-md text-theme-muted",children:Q},Q,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),qjQ=({label:A,value:Q,valueClassName:B})=>X2("div",{className:"flex justify-between text-[13px]",children:[X2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),X2("span",{className:B??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),oL1=({agent:A,prevAgent:Q,nextAgent:B})=>{let{frontmatter:w,about:$,skills:f,notes:I}=A,D=K9A(w.url),U=w.status==="approved";return X2(LjQ,{children:[X2(ZQ,{title:w.name,description:$||`Agent profile for ${w.name}`},void 0,!1,void 0,this),X2("article",{className:"agent-detail",children:X2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[X2("a",{href:"/agents",className:"text-sm text-theme-muted hover:text-brand transition-colors mb-6 inline-block",children:"\u2190 Back to Directory"},void 0,!1,void 0,this),X2("div",{className:"flex items-start gap-6 mb-8",children:[X2(F9A,{name:w.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),X2("div",{children:[X2("div",{className:"flex items-center gap-3 mb-1",children:[X2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:w.name},void 0,!1,void 0,this),X2(Z9A,{kind:w.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X2("div",{className:"text-base text-theme-muted mb-2",children:w.brainName},void 0,!1,void 0,this),X2("div",{className:"flex items-center gap-3 text-theme-muted",children:[w.organization&&X2("span",{className:"text-[15px]",children:w.organization},void 0,!1,void 0,this),w.organization&&X2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),X2("span",{className:"text-sm",children:["Discovered ",NjQ(w.discoveredAt)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!U&&X2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[X2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),X2("p",{className:"text-sm text-theme-muted",children:"This brain is discovered but not approved yet, so it cannot be called until you approve it."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X2("div",{className:"flex flex-col md:flex-row gap-12",children:[X2("div",{className:"flex-[2] min-w-0",children:[$&&X2("section",{className:"mb-8",children:[X2(Lr,{children:"About"},void 0,!1,void 0,this),X2("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f.length>0&&X2("section",{className:"mb-8",children:[X2(Lr,{children:"Skills"},void 0,!1,void 0,this),X2("div",{className:"flex flex-col gap-2.5",children:f.map((Y)=>X2(zjQ,{skill:Y},Y.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I&&X2("section",{className:"mb-8",children:[X2(Lr,{children:"Notes"},void 0,!1,void 0,this),X2("p",{className:"text-[15px] text-theme leading-relaxed",children:I},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[X2("section",{className:"mb-8",children:[X2(Lr,{children:"Brain"},void 0,!1,void 0,this),X2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[X2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:w.brainName},void 0,!1,void 0,this),w.did&&X2("div",{className:"text-xs text-theme-muted font-mono",children:w.did},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X2("section",{className:"mb-8",children:[X2(Lr,{children:"Connection"},void 0,!1,void 0,this),X2("div",{className:"flex flex-col gap-3",children:[X2("div",{children:[X2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),X2("div",{className:"text-xs text-heading font-mono",children:w.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X2(qjQ,{label:"Status",value:w.status==="approved"?"Approved":"Discovered",valueClassName:w.status==="approved"?"text-status-success font-medium":"text-theme-muted"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X2("a",{href:w.url.replace(/\/a2a\/?$/,""),target:"_blank",rel:"noopener noreferrer",className:"flex items-center justify-center px-5 py-3 bg-theme-dark text-theme-inverse rounded-lg text-sm font-medium hover:opacity-90 transition-opacity",children:["Visit ",D," \u2197"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),(Q??B)&&X2("nav",{className:"mt-12 pt-6 border-t border-theme flex flex-col gap-3 md:flex-row md:items-center md:justify-between",children:[X2("div",{className:"min-h-[1px]",children:Q&&X2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[X2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),X2("span",{className:"text-heading font-medium",children:Q.frontmatter.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X2("div",{className:"min-h-[1px] md:text-right",children:B&&X2("a",{href:B.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[X2("span",{children:"Next \u2192"},void 0,!1,void 0,this),X2("span",{className:"text-heading font-medium",children:B.frontmatter.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};var VjQ=H.object({agents:H.array(av),pageTitle:H.string().optional(),pagination:z7.nullable(),baseUrl:H.string().optional(),selectedStatus:H.union([H.literal("all"),$Y])});function sL1(){return{[tmA]:P1({name:tmA,description:"Agent directory list page template",schema:VjQ,dataSourceId:zr,requiredPermission:"public",layout:{component:nL1}}),[emA]:P1({name:emA,description:"Individual agent profile template",schema:H.object({agent:av,prevAgent:av.nullable(),nextAgent:av.nullable()}),dataSourceId:zr,requiredPermission:"public",layout:{component:oL1}})}}var N9A={name:"@brains/agent-discovery",private:!0,version:"0.2.0-alpha.127",description:"Agent discovery \u2014 brain+anchor contacts and skills",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var MjQ=new of;class $uA extends _Q{entityType=e9;schema=sv;adapter=MjQ;constructor(){super(ZL1,N9A)}interceptCreate(A,Q,B){return TL1(A,Q,B,this.id)}createGenerationHandler(A){return new AuA(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return sL1()}getDataSources(){return[new X9A(this.logger.child("AgentDataSource"))]}async onRegister(A){pL1(A),cL1(A,this.id)}async getInstructions(){return iL1()}}function fuA(){return new $uA}aA();WA();aA();var tv=jI,aL1=jI,Vr=A2.extend({entityType:H.literal(a6),metadata:aL1});aA();class ev extends q2{constructor(){super({entityType:a6,schema:Vr,frontmatterSchema:tv})}fromMarkdown(A){let Q=this.parseFrontMatter(A,tv);return{content:A,entityType:a6,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}aA();WA();var CjQ=H.object({skills:H.array(tv).max(8)}),tL1=P1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:CjQ,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
|
|
8290
8290
|
|
|
8291
8291
|
Given knowledge domains, CONSOLIDATE related topics into broader skills.
|
|
8292
8292
|
There should be FEWER skills than topics \u2014 combine related domains.
|
|
@@ -8436,9 +8436,9 @@ Context:
|
|
|
8436
8436
|
${JSON.stringify(w,null,2)}
|
|
8437
8437
|
|
|
8438
8438
|
Draft SWOT:
|
|
8439
|
-
${JSON.stringify(B,null,2)}`}function O9A(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function djQ(A,Q){let B=["strengths","weaknesses","opportunities","threats"];for(let w of B){let $=new Set(A[w].map((f)=>f.theme.trim().toLowerCase()));for(let f of Q[w]){let I=f.sourceTheme.trim().toLowerCase();if(!$.has(I))throw Error(`SWOT refinement invented theme "${f.sourceTheme}" in ${w}`)}}}class R9A{logger;context;adapter=new QZ;constructor(A,Q){this.logger=A;this.context=Q}validateAndParse(A){let Q=UuA.safeParse(A??{});return Q.success?Q.data:null}async process(A,Q,B){await B.report({progress:0.2,message:"Building SWOT context"});let w=await HuA(this.context),$;if(w.summary.brainSkillCount+w.summary.approvedAgentCount+w.summary.discoveredAgentCount===0)$={strengths:[],weaknesses:[],opportunities:[],threats:[]};else{await B.report({progress:0.6,message:"Synthesizing SWOT analysis"});let{object:Y}=await this.context.ai.generateObject(await pjQ(this.context,w),YuA),J=YuA.parse(Y);await B.report({progress:0.75,message:"Refining SWOT language"});let X=await this.context.ai.generateObject(await rjQ(this.context,w,J),E9A);$=E9A.parse(X.object),djQ(J,$)}let I=new Date().toISOString(),D=this.adapter.createSwotContent({strengths:O9A($.strengths),weaknesses:O9A($.weaknesses),opportunities:O9A($.opportunities),threats:O9A($.threats),derivedAt:I});await B.report({progress:0.9,message:"Saving SWOT entity"});let U=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(U)await this.context.entityService.updateEntity({entity:{...U,content:D,metadata:{derivedAt:I}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:D,metadata:{derivedAt:I}}});return this.logger.info("SWOT derivation complete",{derivedAt:I,brainSkillCount:w.summary.brainSkillCount,approvedAgentCount:w.summary.approvedAgentCount,discoveredAgentCount:w.summary.discoveredAgentCount}),{entityId:"swot"}}}WA();import{jsxDEV as p7}from"preact/jsx-dev-runtime";var b9A=H.object({title:H.string(),detail:H.string().optional()}),njQ=H.discriminatedUnion("status",[H.object({status:H.literal("generating")}),H.object({status:H.literal("ready"),strengths:H.array(b9A).default([]),weaknesses:H.array(b9A).default([]),opportunities:H.array(b9A).default([]),threats:H.array(b9A).default([]),derivedAt:H.string()})]);function ojQ({items:A}){if(A.length===0)return p7("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return p7("ul",{class:"swot-list",children:A.map((Q)=>p7("li",{class:"swot-item",children:[p7("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?p7("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 P9A({title:A,tone:Q,items:B}){return p7("section",{class:`swot-cell is-${Q}`,children:[p7("div",{class:"swot-head",children:A},void 0,!1,void 0,this),p7(ojQ,{items:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function FuA({data:A}){let Q=njQ.safeParse(A);if(!Q.success||Q.data.status==="generating")return p7("div",{"data-swot-widget":!0,children:p7("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let B=Q.data;return p7("div",{"data-swot-widget":!0,children:p7("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[p7(P9A,{title:"Strengths",tone:"s",items:B.strengths},void 0,!1,void 0,this),p7(P9A,{title:"Weaknesses",tone:"w",items:B.weaknesses},void 0,!1,void 0,this),p7(P9A,{title:"Opportunities",tone:"o",items:B.opportunities},void 0,!1,void 0,this),p7(P9A,{title:"Threats",tone:"t",items:B.threats},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}WA();var ZuA={name:"@brains/assessment",private:!0,version:"0.2.0-alpha.
|
|
8439
|
+
${JSON.stringify(B,null,2)}`}function O9A(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function djQ(A,Q){let B=["strengths","weaknesses","opportunities","threats"];for(let w of B){let $=new Set(A[w].map((f)=>f.theme.trim().toLowerCase()));for(let f of Q[w]){let I=f.sourceTheme.trim().toLowerCase();if(!$.has(I))throw Error(`SWOT refinement invented theme "${f.sourceTheme}" in ${w}`)}}}class R9A{logger;context;adapter=new QZ;constructor(A,Q){this.logger=A;this.context=Q}validateAndParse(A){let Q=UuA.safeParse(A??{});return Q.success?Q.data:null}async process(A,Q,B){await B.report({progress:0.2,message:"Building SWOT context"});let w=await HuA(this.context),$;if(w.summary.brainSkillCount+w.summary.approvedAgentCount+w.summary.discoveredAgentCount===0)$={strengths:[],weaknesses:[],opportunities:[],threats:[]};else{await B.report({progress:0.6,message:"Synthesizing SWOT analysis"});let{object:Y}=await this.context.ai.generateObject(await pjQ(this.context,w),YuA),J=YuA.parse(Y);await B.report({progress:0.75,message:"Refining SWOT language"});let X=await this.context.ai.generateObject(await rjQ(this.context,w,J),E9A);$=E9A.parse(X.object),djQ(J,$)}let I=new Date().toISOString(),D=this.adapter.createSwotContent({strengths:O9A($.strengths),weaknesses:O9A($.weaknesses),opportunities:O9A($.opportunities),threats:O9A($.threats),derivedAt:I});await B.report({progress:0.9,message:"Saving SWOT entity"});let U=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(U)await this.context.entityService.updateEntity({entity:{...U,content:D,metadata:{derivedAt:I}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:D,metadata:{derivedAt:I}}});return this.logger.info("SWOT derivation complete",{derivedAt:I,brainSkillCount:w.summary.brainSkillCount,approvedAgentCount:w.summary.approvedAgentCount,discoveredAgentCount:w.summary.discoveredAgentCount}),{entityId:"swot"}}}WA();import{jsxDEV as p7}from"preact/jsx-dev-runtime";var b9A=H.object({title:H.string(),detail:H.string().optional()}),njQ=H.discriminatedUnion("status",[H.object({status:H.literal("generating")}),H.object({status:H.literal("ready"),strengths:H.array(b9A).default([]),weaknesses:H.array(b9A).default([]),opportunities:H.array(b9A).default([]),threats:H.array(b9A).default([]),derivedAt:H.string()})]);function ojQ({items:A}){if(A.length===0)return p7("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return p7("ul",{class:"swot-list",children:A.map((Q)=>p7("li",{class:"swot-item",children:[p7("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?p7("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 P9A({title:A,tone:Q,items:B}){return p7("section",{class:`swot-cell is-${Q}`,children:[p7("div",{class:"swot-head",children:A},void 0,!1,void 0,this),p7(ojQ,{items:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function FuA({data:A}){let Q=njQ.safeParse(A);if(!Q.success||Q.data.status==="generating")return p7("div",{"data-swot-widget":!0,children:p7("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let B=Q.data;return p7("div",{"data-swot-widget":!0,children:p7("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[p7(P9A,{title:"Strengths",tone:"s",items:B.strengths},void 0,!1,void 0,this),p7(P9A,{title:"Weaknesses",tone:"w",items:B.weaknesses},void 0,!1,void 0,this),p7(P9A,{title:"Opportunities",tone:"o",items:B.opportunities},void 0,!1,void 0,this),p7(P9A,{title:"Threats",tone:"t",items:B.threats},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}WA();var ZuA={name:"@brains/assessment",private:!0,version:"0.2.0-alpha.127",description:"Assessment outputs and capability-profile analysis",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var NuA=new QZ;class zuA extends _Q{entityType="swot";schema=Ay;adapter=NuA;initialSyncComplete=!1;constructor(){super("swot",ZuA)}async onRegister(A){let Q=new R9A(this.logger.child("SwotDerivationHandler"),A);A.jobs.registerHandler("derive",Q),A.eval.registerHandler("deriveSwot",async()=>{let f=R9.from(async()=>{});if(!f)throw Error("Expected progress reporter to be created");await Q.process({reason:"eval"},"eval-swot-derive",f);let I=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!I)throw Error("Expected SWOT entity to be created during eval");return NuA.parseSwotContent(I.content).frontmatter});let B=async(f)=>{try{return await A.jobs.enqueue({type:"derive",data:{reason:f},options:{source:this.id,priority:10,deduplication:"coalesce",deduplicationKey:"swot",metadata:{operationType:"data_processing",operationTarget:`swot:${f}`}}})}catch(I){return this.logger.error("Failed to queue SWOT derivation",{error:I,reason:f}),null}},w=async(f)=>{if(!await A.entityService.getEntity({entityType:"swot",id:"swot"}))await B(f)};A.messaging.subscribe("sync:initial:completed",async()=>{return this.initialSyncComplete=!0,await w("initial-missing-entity"),{success:!0}}),A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:"swot",pluginId:this.id,title:"SWOT",section:"secondary",priority:14,rendererName:"SwotWidget",component:FuA,dataProvider:async()=>{let f=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!f)return{status:"generating"};let{frontmatter:I}=NuA.parseSwotContent(f.content);return{status:"ready",...I}}}}),{success:!0}});let $=async(f)=>{let{entityType:I}=f.payload;if(!this.initialSyncComplete)return{success:!0};if(I!=="agent"&&I!=="skill")return{success:!0};return await B("entity-change"),{success:!0}};A.messaging.subscribe("entity:created",$),A.messaging.subscribe("entity:updated",$),A.messaging.subscribe("entity:deleted",$)}}function quA(){return new zuA}aA();t$();WA();var OI8=new QZ,WV1=H.object({name:H.string(),description:H.string(),tags:H.array(H.string())}),LuA=H.enum(["discovered","approved"]),ajQ=H.object({name:H.string(),kind:H.enum(["professional","team","collective"]),organization:H.string().optional(),brainName:H.string(),url:H.string().url(),did:H.string().optional(),status:LuA,discoveredAt:H.string().datetime()}),tjQ=A2.extend({entityType:H.literal("agent"),metadata:H.object({name:H.string(),url:H.string().url(),status:LuA,slug:H.string()})}),ejQ=A2.extend({entityType:H.literal("skill"),metadata:jI}),A_Q=H.object({about:H.string(),skills:H.array(WV1),notes:H.string()});function Q_Q(A){if(!Array.isArray(A)||A.length===0)return"";return A.map((B)=>{let w=B.tags.length>0?` [${B.tags.join(", ")}]`:"";return`- ${B.name}: ${B.description}${w}`}).join(`
|
|
8440
8440
|
`)}function B_Q(A){if(!A.trim())return[];return A.split(`
|
|
8441
|
-
`).map((Q)=>Q.match(/^- (.+?): (.+?)(?:\s+\[(.+?)\])?$/)).filter((Q)=>Q!==null).map((Q)=>({name:Q[1]??"",description:Q[2]??"",tags:Q[3]?Q[3].split(",").map((B)=>B.trim()).filter(Boolean):[]}))}var w_Q=new lB(A_Q,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:Q_Q,parser:B_Q},{key:"notes",label:"Notes",type:"string"}]});class HV1 extends q2{constructor(){super({entityType:"agent",schema:tjQ,frontmatterSchema:ajQ})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=w_Q.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 GV1 extends q2{constructor(){super({entityType:"skill",schema:ejQ,frontmatterSchema:jI})}fromMarkdown(A){let Q=this.parseFrontMatter(A,jI);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var RI8=new HV1,bI8=new GV1,PI8=H.object({skills:H.array(jI),agents:H.array(H.object({id:H.string().optional(),name:H.string(),kind:H.enum(["professional","team","collective"]),organization:H.string().optional(),brainName:H.string(),url:H.string().url(),did:H.string().optional(),status:LuA,discoveredAt:H.string().datetime().optional(),about:H.string(),skills:H.array(WV1),notes:H.string().default("")}))});var $_Q=H.object({}).strict();function k9A(A={}){return $_Q.parse(A),[quA()]}aA();WA();WA();var VuA=H.object({enabled:H.boolean().default(!0),pdsEndpoint:H.string().url().default("https://bsky.social").describe("AT Protocol PDS service endpoint"),identifier:H.string().optional().describe("PDS login identifier, usually a handle or account DID"),repoDid:H.string().optional().describe("DID of the PDS repo that owns records"),appPassword:H.string().optional().describe("App password for prototype authentication; supply via ${ENV_VAR} interpolation, never a committed literal"),anchorDid:H.string().optional().describe("Optional human/operator DID referenced from records; defaults to did:web:<site-host>:anchor when omitted"),brainDid:H.string().optional().describe("Optional public brain DID referenced from records; defaults to did:web:<site-host> when omitted")});function f_Q(A){return A.replace(/\/+$/,"")}var I_Q=(A,Q)=>fetch(A,Q);async function Mr(A){let Q=await A.json();if(!A.ok){let B=typeof Q==="object"&&Q!==null&&"message"in Q&&typeof Q.message==="string"?Q.message:`AT Protocol request failed with ${A.status}`;throw Error(B)}return Q}class Cr{pdsEndpoint;identifier;appPassword;fetchFn;session;constructor(A){this.pdsEndpoint=f_Q(A.pdsEndpoint),this.identifier=A.identifier,this.appPassword=A.appPassword,this.fetchFn=A.fetch??I_Q}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 Mr(A);return this.session=Q,Q}async createRecord(A){let Q=await this.getSession(),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.createRecord`,{method:"POST",headers:{Authorization:`Bearer ${Q.accessJwt}`,"Content-Type":"application/json"},body:JSON.stringify({repo:A.repo,collection:A.collection,record:A.record,...A.rkey&&{rkey:A.rkey},...A.validate!==void 0&&{validate:A.validate}})});return Mr(B)}async putRecord(A){let Q=await this.getSession(),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.putRecord`,{method:"POST",headers:{Authorization:`Bearer ${Q.accessJwt}`,"Content-Type":"application/json"},body:JSON.stringify({repo:A.repo,collection:A.collection,record:A.record,rkey:A.rkey,...A.validate!==void 0&&{validate:A.validate},...A.swapRecord!==void 0&&{swapRecord:A.swapRecord}})});return Mr(B)}async getRecord(A){let Q=new URLSearchParams({repo:A.repo,collection:A.collection,rkey:A.rkey}),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.getRecord?${Q.toString()}`,{method:"GET"});return Mr(B)}async uploadBlob(A){let Q=await this.getSession(),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.uploadBlob`,{method:"POST",headers:{Authorization:`Bearer ${Q.accessJwt}`,"Content-Type":A.mimeType},body:new Blob([new Uint8Array(A.data)],{type:A.mimeType})});return Mr(B)}async getSession(){return this.session??=await this.createSession(),this.session}}function kC(A){return A?.startsWith("did:web:")??!1}function j9A(A){if(!kC(A))return;let Q=A.slice(8);if(!Q)return;let[B]=Q.split(":");if(!B)return;try{return decodeURIComponent(B)}catch{return B}}function FV1(A){if(!kC(A))return;let Q=A.slice(8);if(!Q)return;let[,...B]=Q.split(":");if(B.length===0)return"/.well-known/did.json";return`/${B.map(($)=>{try{return decodeURIComponent($)}catch{return $}}).join("/")}/did.json`}function ZV1(A){return A.replace(/\/+$/,"")}function Or(A){return`did:web:${encodeURIComponent(A)}`}function _9A(A){return`${Or(A)}:anchor`}function EuA(A){return{"@context":["https://www.w3.org/ns/did/v1"],id:A}}function NV1(A,Q){let B=A.identifier?.startsWith("did:")?void 0:A.identifier?[`at://${A.identifier}`]:void 0;return{...EuA(Q),...B&&{alsoKnownAs:B},service:[{id:"#atproto_pds",type:"AtprotoPersonalDataServer",serviceEndpoint:ZV1(A.pdsEndpoint)}]}}function zV1(A){if(!kC(A.brainDid))return null;return NV1(A,A.brainDid)}function KV1(A,Q){if(!A||!Q)return;let B=j9A(A),w=FV1(A);if(!B||!w)return;return{path:w,hostname:B,document:Q}}function v9A(A){let Q=[],B=KV1(A.brainDid,zV1(A));if(B)Q.push(B);if(kC(A.anchorDid)&&A.anchorDid!==A.brainDid){let w=KV1(A.anchorDid,EuA(A.anchorDid));if(w)Q.push(w)}return Q}function MuA(A,Q){let B=[];if(!A.brainDid){let w=Or(Q);B.push({path:"/.well-known/did.json",hostname:Q,document:NV1(A,w)})}if(!A.anchorDid){let w=_9A(Q);B.push({path:"/anchor/did.json",hostname:Q,document:EuA(w)})}return B}function D_Q(A,Q){if(!A)return;try{return new URL(A,Q).toString()}catch{return}}function U_Q(A){let Q=A.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,200);return Q.length>0?Q:"skill"}function qV1(A,Q){let B=A[Q];return typeof B==="string"&&B.length>0?B:void 0}function LV1(A,Q){let B=A[Q];if(!Array.isArray(B))return;let w=B.filter(($)=>typeof $==="string"&&$.length>0);return w.length>0?w:void 0}function Y_Q(A){let Q=A.metadata,B=qV1(Q,"name"),w=qV1(Q,"description");if(!B||!w)return;let $=LV1(Q,"tags"),f=LV1(Q,"examples");return{id:U_Q(B),name:B,description:w,...$&&{tags:$},...f&&{examples:f}}}async function J_Q(A){if(!A.entityService.hasEntityType("skill"))return[];return(await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}})).map((B)=>Y_Q(B)).filter((B)=>B!==void 0).slice(0,100)}async function CuA(A,Q,B=new Date){let w=A.identity.get(),$=A.identity.getProfile(),f=await A.identity.getAppInfo(),I=D_Q(A.siteUrl??$.website,void 0);if(!I)throw Error("AT Protocol brain card publishing requires siteUrl");let D=new URL(I).hostname,U=Q.brainDid??Or(D),Y=Q.anchorDid??_9A(D);if(kC(U)){if(j9A(U)!==D)throw Error("AT Protocol brain card did:web host must match siteUrl host")}let J=await J_Q(A);return{$type:"ai.rizom.brain.card",siteUrl:I,brain:{did:U,name:w.name,role:w.role,purpose:w.purpose,values:w.values},anchor:{did:Y,name:$.name,kind:$.kind},skills:J,model:f.model,version:f.version,createdAt:B.toISOString(),updatedAt:B.toISOString()}}WA();var VV1={dryRun:H.boolean().default(!1).describe("Build and return the card record without writing to the PDS")},X_Q={},EV1={entityType:H.string().describe("Local entity type with a registered AT Protocol projection"),entityId:H.string().optional().describe("Local entity ID to publish"),slug:H.string().optional().describe("Local entity slug to publish"),dryRun:H.boolean().default(!1).describe("Build and return the record without writing to the PDS"),topics:H.array(H.string()).optional().describe("Optional topic labels to include in the AT Protocol record")},MV1={repos:H.array(H.string().min(1)).min(1).max(50).describe("Candidate AT Protocol repo DIDs or handles to inspect")},CV1={entityId:H.string().optional().describe("Local blog post entity ID to publish"),slug:H.string().optional().describe("Local blog post slug to publish"),dryRun:H.boolean().default(!1).describe("Build and return the post record without writing to the PDS"),topics:H.array(H.string()).optional().describe("Optional topic labels to include in the AT Protocol record")};function OV1(A,Q,B){return[W_Q(A,Q),H_Q(A,Q,B),G_Q(A,Q,B),F_Q(A,Q,B),K_Q(A,Q,B)]}function W_Q(A,Q){return{name:`${A}_validate_credentials`,description:"Validate AT Protocol PDS credentials without publishing records.",inputSchema:X_Q,handler:async()=>{return{success:!0,data:{valid:await Q.validatePdsCredentials()}}}}}function H_Q(A,Q,B){return{name:`${A}_publish_card`,description:"Publish this brain's AT Protocol discovery card to the configured PDS, or dry-run the record payload.",inputSchema:VV1,handler:async(w)=>{let $=H.object(VV1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{return{success:!0,data:await Q.publishBrainCard(B,{dryRun:$.data.dryRun})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Publish failed"}}}}}function G_Q(A,Q,B){return{name:`${A}_publish_entity`,description:"Publish any public local entity with a registered AT Protocol projection, or dry-run the record payload.",inputSchema:EV1,handler:async(w)=>{let $=H.object(EV1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{if(!$.data.entityId&&!$.data.slug)return{success:!1,error:"Invalid input: entityId or slug is required"};return{success:!0,data:await Q.publishEntity(B,{entityType:$.data.entityType,...$.data.entityId&&{entityId:$.data.entityId},...$.data.slug&&{slug:$.data.slug},dryRun:$.data.dryRun,...$.data.topics&&{topics:$.data.topics}})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Publish failed"}}}}}function K_Q(A,Q,B){return{name:`${A}_discover_brain_cards`,description:"Read public ai.rizom.brain.card/self records from candidate AT Protocol repo DIDs or handles and emit internal discovery events.",inputSchema:MV1,handler:async(w)=>{let $=H.object(MV1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{return{success:!0,data:await Q.discoverBrainCards(B,{repos:$.data.repos})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Discovery failed"}}}}}function F_Q(A,Q,B){return{name:`${A}_publish_post`,description:"Publish a local blog post entity as an ai.rizom.brain.post AT Protocol record, or dry-run the record payload.",inputSchema:CV1,handler:async(w)=>{let $=H.object(CV1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{if(!$.data.entityId&&!$.data.slug)return{success:!1,error:"Invalid input: entityId or slug is required"};return{success:!0,data:await Q.publishPost(B,{...$.data.entityId&&{entityId:$.data.entityId},...$.data.slug&&{slug:$.data.slug},dryRun:$.data.dryRun,...$.data.topics&&{topics:$.data.topics}})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Publish failed"}}}}}var RV1={name:"@brains/atproto",private:!0,version:"0.2.0-alpha.125",description:"AT Protocol integration for identity, publishing, discovery, and feeds",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var bV1=Kw["ai.rizom.brain.card"],N_Q="ai.rizom.brain.card",z_Q="self",PV1=50;class OuA extends YB{deps;projectionRegistry;constructor(A={},Q={}){super("atproto",RV1,A,VuA);this.deps=Q,this.projectionRegistry=Q.projectionRegistry??o6.getInstance()}getWebRoutes(){if(!this.config.enabled)return[];let A=v9A(this.config),Q=[...!this.config.brainDid?["/.well-known/did.json"]:[],...!this.config.anchorDid?["/anchor/did.json"]:[]];return[...new Set([...A.map((w)=>w.path),...Q])].map((w)=>({path:w,method:"GET",public:!0,handler:($)=>{let f=new URL($.url).hostname,I=[...v9A(this.config),...MuA(this.config,f)].filter((U)=>U.path===w),D=I.find((U)=>U.hostname===f)??I[0];if(!D)return new Response("Not found",{status:404});return new Response(JSON.stringify(D.document),{headers:{"Content-Type":"application/did+json"}})}}))}async publishBrainCard(A,Q={}){let B=await CuA(A,this.config);cz(bV1,B);let w=this.config.repoDid;if(Q.dryRun)return{record:B,dryRun:!0,...w&&{repo:w}};let $=this.resolveAppPassword();if(!this.config.identifier||!$)throw Error("AT Protocol publishing requires identifier and app password configuration");let f=this.createPdsClient($),I=await f.createSession(),D=w??I.did;if(!f.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let U=await f.putRecord({repo:D,collection:"ai.rizom.brain.card",rkey:"self",validate:!1,record:B});return{record:B,repo:D,uri:U.uri,cid:U.cid,dryRun:!1}}async publishEntity(A,Q){let B=this.projectionRegistry.get(Q.entityType);if(!B)throw Error(`No AT Protocol projection registered for ${Q.entityType}`);return this.publishProjectedEntity(A,Q,B)}async publishPost(A,Q){let B=this.projectionRegistry.get("post");if(!B)throw Error("No AT Protocol projection registered for post");return this.publishProjectedEntity(A,{entityType:"post",...Q},B)}async discoverBrainCards(A,Q){let B=[...new Set(Q.repos.map((f)=>f.trim()))].filter((f)=>f.length>0);if(B.length===0)throw Error("AT Protocol discovery requires at least one repo DID or handle");if(B.length>PV1)throw Error(`AT Protocol discovery accepts at most ${PV1} repos per batch`);let w=new Set,$=[];for(let f of B)try{let I=await this.resolveRepoPdsEndpoint(f),D=this.createPublicPdsClient(I.pdsEndpoint);if(!D.getRecord)throw Error("AT Protocol PDS client does not support record reads");let U=await D.getRecord({repo:I.repoDid,collection:N_Q,rkey:z_Q});cz(bV1,U.value);let Y=L_Q(U.uri)??I.repoDid,J=`${Y}:${U.uri}:${U.cid}`;if(w.has(J)){$.push({repo:f,status:"skipped",repoDid:Y,uri:U.uri,cid:U.cid,error:"Duplicate brain card in discovery batch"});continue}w.add(J),await A.messaging.send({type:K5A,payload:{repoDid:Y,uri:U.uri,cid:U.cid,record:U.value},broadcast:!0}),$.push({repo:f,status:"discovered",repoDid:Y,uri:U.uri,cid:U.cid})}catch(I){$.push({repo:f,status:"skipped",error:y0(I)})}return{discovered:$.filter((f)=>f.status==="discovered").length,skipped:$.filter((f)=>f.status==="skipped").length,results:$}}async validatePdsCredentials(){let A=this.resolveAppPassword();if(!this.config.identifier||!A)return!1;try{return await this.createPdsClient(A).createSession(),!0}catch(Q){return this.logger.warn("AT Protocol PDS authentication failed",{error:y0(Q)}),!1}}async getTools(){if(!this.config.enabled)return[];return OV1(this.id,this,this.getContext())}async getInstructions(){if(!this.config.enabled)return;return"## AT Protocol publishing\n- Use `atproto_validate_credentials` to check PDS credentials before publishing.\n- Use `atproto_publish_card` to publish or dry-run this brain's public discovery card.\n- Use `atproto_publish_entity` to publish any public entity with a registered AT Protocol projection.\n- Use `atproto_publish_post` for the blog-post convenience path by `entityId` or `slug`.\n- Use `atproto_discover_brain_cards` to read public `ai.rizom.brain.card/self` records from candidate repo DIDs or handles and emit internal discovery events.\n- Prefer `dryRun: true` first when publishing new AT Protocol records.\n- Only public posts and public cover images can be published."}async publishProjectedEntity(A,Q,B){let w=await this.findPublishEntity(A,Q),$=Q.entityId??Q.slug;if(!$)throw Error(`${Q.entityType} publish requires entityId or slug`);if(!w)throw Error(`${Q.entityType} not found: ${$}`);if(w.visibility!=="public")throw Error(`Cannot publish non-public ${Q.entityType}: ${$}`);let f=this.config.repoDid;if(Q.dryRun){let G=await B.buildRecord({entity:w,context:A,config:this.config,...Q.topics&&{topics:Q.topics},dryRun:!0});return cz(B.lexicon,G),{record:G,dryRun:!0,...f&&{repo:f}}}let I=this.resolveAppPassword();if(!this.config.identifier||!I)throw Error("AT Protocol publishing requires identifier and app password configuration");let D=this.createPdsClient(I),U=await D.createSession(),Y=f??U.did,J=await B.buildRecord({entity:w,context:A,config:this.config,client:D,...Q.topics&&{topics:Q.topics}});if(cz(B.lexicon,J),!D.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let X=await D.putRecord({repo:Y,collection:B.collection,rkey:q_Q(w.id),...B.validate!==void 0&&{validate:B.validate},record:J});return await B.onPublished?.({entity:w,context:A,record:J,uri:X.uri,cid:X.cid}),{record:J,repo:Y,uri:X.uri,cid:X.cid,dryRun:!1}}async findPublishEntity(A,Q){if(Q.entityId)return A.entityService.getEntity({entityType:Q.entityType,id:Q.entityId});if(Q.slug)return(await A.entityService.listEntities({entityType:Q.entityType,options:{filter:{metadata:{slug:Q.slug}}}}))[0]??null;return null}createPublicPdsClient(A){if(this.deps.createPdsClient)return this.deps.createPdsClient({pdsEndpoint:A,identifier:this.config.identifier??"",appPassword:this.config.appPassword??""});return new Cr({pdsEndpoint:A,identifier:this.config.identifier??"",appPassword:this.config.appPassword??""})}async resolveRepoPdsEndpoint(A){let Q=A.startsWith("did:")?A:await this.resolveHandleToDid(A);if(!Q)throw Error(`Could not resolve AT Protocol repo: ${A}`);let B=await this.resolveDidToPdsEndpoint(Q);if(!B)throw Error(`Could not resolve AT Protocol PDS for repo: ${Q}`);return{repoDid:Q,pdsEndpoint:B}}async resolveHandleToDid(A){let Q=new URL("/xrpc/com.atproto.identity.resolveHandle",this.config.pdsEndpoint);Q.searchParams.set("handle",A);let B=await this.fetch(Q.toString());if(!B.ok)return;let w=await B.json();if(typeof w!=="object"||w===null||!("did"in w))return;return typeof w.did==="string"?w.did:void 0}async resolveDidToPdsEndpoint(A){let Q=A.startsWith("did:plc:")?await this.fetchJson(`https://plc.directory/${encodeURIComponent(A)}`):A.startsWith("did:web:")?await this.fetchJson(V_Q(A)):void 0;if(typeof Q!=="object"||Q===null)return;let B=Q.service;if(!Array.isArray(B))return;let w=B.find(($)=>{return typeof $==="object"&&$!==null&&($.id==="#atproto_pds"||$.type==="AtprotoPersonalDataServer")});return typeof w?.serviceEndpoint==="string"?w.serviceEndpoint:void 0}async fetchJson(A){let Q=await this.fetch(A);if(!Q.ok)return;return Q.json()}fetch(A){return(this.deps.fetch??fetch)(A)}createPdsClient(A){if(this.deps.createPdsClient)return this.deps.createPdsClient({pdsEndpoint:this.config.pdsEndpoint,identifier:this.config.identifier??"",appPassword:A});return new Cr({pdsEndpoint:this.config.pdsEndpoint,identifier:this.config.identifier??"",appPassword:A})}resolveAppPassword(){return this.config.appPassword}}function q_Q(A){let Q=A.replace(/[^A-Za-z0-9._~:-]/g,"_").slice(0,512);return Q.length>0?Q:"self"}function L_Q(A){return/^at:\/\/([^/]+)/.exec(A)?.[1]}function V_Q(A){let Q=A.slice(8).split(":").map(decodeURIComponent),[B,...w]=Q;if(!B)throw Error(`Invalid did:web value: ${A}`);if(w.length===0)return`https://${B}/.well-known/did.json`;return`https://${B}/${w.join("/")}/did.json`}function y9A(A,Q){return new OuA(A,Q)}aA();WA();Xw();I5();WA();aA();var T9A=zs.extend({expertise:H.array(H.string()).optional().describe("Skills, domains, areas of focus"),currentFocus:H.string().optional().describe("What you're currently working on"),availability:H.string().optional().describe("What you're open to (consulting, speaking, etc.)")}),Dq=oY.extend(T9A.shape);aA();BK();WA();var E_Q=new JW;class x9A{postsListUrl;decksListUrl;id="professional:homepage-list";name="Homepage List DataSource";description="Fetches profile, blog posts, and presentation decks for homepage";constructor(A,Q){this.postsListUrl=A;this.decksListUrl=Q}async fetch(A,Q,B){let w=B.entityService,[$,f,I,D]=await Promise.all([dR(w),w.listEntities({entityType:"post",options:{limit:20}}),w.listEntities({entityType:"deck",options:{limit:20}}),Di(w)]),U=E_Q.parseProfileBody($,Dq),Y=f.sort(aT).slice(0,3).map(Ji),J=I.sort(aT).slice(0,3).map(Fi);if(!D.cta)throw Error("CTA not configured in site-info");let X={profile:U,posts:Y,decks:J,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:D.cta,sections:D.sections??{}};return Q.parse(X)}}aA();BK();var M_Q=new JW;class S9A{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,B){let w=await dR(B.entityService),f={profile:M_Q.parseProfileBody(w,Dq)};return Q.parse(f)}}import{jsxDEV as $8,Fragment as R_Q}from"preact/jsx-dev-runtime";var C_Q="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",O_Q="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",RuA=({number:A,title:Q,blurb:B,children:w})=>$8("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:$8("div",{className:"max-w-6xl mx-auto",children:$8("div",{className:C_Q,children:[$8(syA,{title:Q,number:A,blurb:B},void 0,!1,void 0,this),$8("div",{className:O_Q,"aria-hidden":"true"},void 0,!1,void 0,this),$8("div",{className:"mt-6 md:mt-0",children:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),buA=({profile:A,posts:Q,decks:B,postsListUrl:w,decksListUrl:$,cta:f,sections:I})=>{let D=A.tagline||A.description,U=Q.map((Z)=>({id:Z.id,url:Z.url,title:Z.metadata.title,date:Z.metadata.publishedAt||Z.created,description:Z.frontmatter.excerpt,series:Z.frontmatter.seriesName&&Z.frontmatter.seriesIndex?{name:Z.frontmatter.seriesName,index:Z.frontmatter.seriesIndex}:void 0})),Y=B.map((Z)=>({id:Z.id,url:Z.url,title:Z.frontmatter.title||Z.id,date:Z.frontmatter.publishedAt??Z.created,description:Z.frontmatter.description})),J=A.name||"Home",X=A.intro||A.description||D||"Professional site",G=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return $8(R_Q,{children:[$8(ZQ,{title:J,description:X,ogType:"website"},void 0,!1,void 0,this),$8("div",{className:"homepage-list bg-theme",children:[$8("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:$8("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&$8("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[$8("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),$8("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D&&$8("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:P8A(D,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&$8("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:P8A(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),$8(RuA,{number:"01",title:"Essays",blurb:I.essays?.blurb,children:$8(b8A,{items:U,viewAllUrl:w,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Y.length>0&&$8(RuA,{number:"02",title:"Presentations",blurb:I.presentations?.blurb,children:$8(b8A,{items:Y,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G&&$8(RuA,{number:"03",title:"About",blurb:I.about?.blurb,children:$8("div",{className:"flex flex-col gap-8",children:[A.description&&$8("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&&$8(ayA,{subjects:A.expertise},void 0,!1,void 0,this),$8("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",$8("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),$8(TyA,{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 Zw,Fragment as b_Q}from"preact/jsx-dev-runtime";var PuA=({profile:A})=>{let Q=`About ${A.name||"Me"}`,B=A.description||A.intro||"About page",w=A.expertise&&A.expertise.length>0||A.currentFocus||A.availability||A.email||A.website||A.socialLinks&&A.socialLinks.length>0;return Zw(b_Q,{children:[Zw(ZQ,{title:Q,description:B,ogType:"profile"},void 0,!1,void 0,this),Zw("div",{className:"about-page bg-theme",children:[Zw("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:Zw("div",{className:"relative z-10 max-w-4xl mx-auto",children:[Zw("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&&Zw("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),Zw("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&Zw("section",{className:"content-section-reveal mb-20 md:mb-28",children:Zw(M$,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&Zw("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&Zw("section",{children:[Zw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),Zw("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,f)=>Zw("li",{className:Yp({variant:"accent",size:"lg"}),children:$},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&Zw("section",{children:[Zw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),Zw("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&&Zw("section",{children:[Zw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),Zw("p",{className:"text-lg text-theme leading-relaxed",children:A.availability},void 0,!1,void 0,this)]},void 0,!0,void 0,this),(A.email||A.website||A.socialLinks&&A.socialLinks.length>0)&&Zw("section",{children:[Zw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),Zw("div",{className:"space-y-4",children:[A.email&&Zw("p",{className:"text-lg",children:Zw("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&&Zw("p",{className:"text-lg",children:Zw("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&&Zw("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,f)=>Zw(E$,{href:$.url,external:!0,variant:"secondary",size:"md",children:$.label||$.platform},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as i7,Fragment as kV1}from"preact/jsx-dev-runtime";var kuA=()=>{return i7(kV1,{children:[i7(ZQ,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),i7("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:i7("div",{className:"text-center max-w-md",children:[i7("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),i7("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),i7("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),i7(E$,{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)},juA=()=>{return i7(kV1,{children:[i7(ZQ,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),i7("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:i7("div",{className:"text-center max-w-md",children:[i7("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),i7("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),i7("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),i7(E$,{href:"/",variant:"primary",children:"Back to Home"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};WA();var jV1=H.object({label:H.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:H.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')")}),_V1=H.object({entityDisplay:H.object({post:jV1,deck:jV1}).describe("Display metadata for post and deck entity types (required for homepage)")});var vV1={name:"@brains/site-professional",private:!0,version:"0.2.0-alpha.125",description:"Professional site composition package",type:"module",exports:{".":"./src/index.ts"},files:["src"],scripts:{typecheck:"tsc --noEmit",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/blog":"workspace:*","@brains/decks":"workspace:*","@brains/identity-service":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-engine":"workspace:*","@brains/site-info":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class _uA extends YB{dependencies=["blog","decks"];constructor(A){super("professional-site",vV1,A,_V1)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",T9A);let Q=this.config.entityDisplay.post,B=this.config.entityDisplay.deck,w=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,$=`/${B.pluralName??B.label.toLowerCase()+"s"}`,f=new x9A(w,$);A.entities.registerDataSource(f);let I=new S9A;A.entities.registerDataSource(I);let D=H.object({profile:Dq,posts:H.array(lF),decks:H.array(WC),postsListUrl:H.string(),decksListUrl:H.string(),cta:ZSA,sections:H.record(H.string(),Ro)}),U=H.object({profile:Dq}),Y=H.object({});A.templates.register({"homepage-list":P1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:D,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:buA}}),about:P1({name:"about",description:"About page with full profile information",schema:U,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:PuA}}),"subscribe-thanks":P1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:Y,requiredPermission:"public",layout:{component:kuA}}),"subscribe-error":P1({name:"subscribe-error",description:"Newsletter subscription error page",schema:Y,requiredPermission:"public",layout:{component:juA}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function yV1(A){return new _uA(A??{})}var TV1=[{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 g9A}from"preact/jsx-dev-runtime";function xV1({sections:A,siteInfo:Q,slots:B,wordmark:w}){return g9A("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[g9A(hyA,{title:Q.title,navigation:Q.navigation.primary,showThemeToggle:!0,...Q.logo!==void 0?{logo:Q.logo}:{},...w!==void 0?{wordmark:w}:{}},void 0,!1,void 0,this),g9A("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),g9A(SyA,{primaryNavigation:Q.navigation.primary,secondaryNavigation:Q.navigation.secondary,copyright:Q.copyright,socialLinks:Q.socialLinks,title:Q.title,tagline:Q.description,children:B?.getSlot("footer-top").map(($)=>$.render())},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var k_Q={layouts:{default:xV1},routes:TV1,plugin:yV1,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"}}}},Rr=k_Q;var SV1=`/*
|
|
8441
|
+
`).map((Q)=>Q.match(/^- (.+?): (.+?)(?:\s+\[(.+?)\])?$/)).filter((Q)=>Q!==null).map((Q)=>({name:Q[1]??"",description:Q[2]??"",tags:Q[3]?Q[3].split(",").map((B)=>B.trim()).filter(Boolean):[]}))}var w_Q=new lB(A_Q,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:Q_Q,parser:B_Q},{key:"notes",label:"Notes",type:"string"}]});class HV1 extends q2{constructor(){super({entityType:"agent",schema:tjQ,frontmatterSchema:ajQ})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=w_Q.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 GV1 extends q2{constructor(){super({entityType:"skill",schema:ejQ,frontmatterSchema:jI})}fromMarkdown(A){let Q=this.parseFrontMatter(A,jI);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var RI8=new HV1,bI8=new GV1,PI8=H.object({skills:H.array(jI),agents:H.array(H.object({id:H.string().optional(),name:H.string(),kind:H.enum(["professional","team","collective"]),organization:H.string().optional(),brainName:H.string(),url:H.string().url(),did:H.string().optional(),status:LuA,discoveredAt:H.string().datetime().optional(),about:H.string(),skills:H.array(WV1),notes:H.string().default("")}))});var $_Q=H.object({}).strict();function k9A(A={}){return $_Q.parse(A),[quA()]}aA();WA();WA();var VuA=H.object({enabled:H.boolean().default(!0),pdsEndpoint:H.string().url().default("https://bsky.social").describe("AT Protocol PDS service endpoint"),identifier:H.string().optional().describe("PDS login identifier, usually a handle or account DID"),repoDid:H.string().optional().describe("DID of the PDS repo that owns records"),appPassword:H.string().optional().describe("App password for prototype authentication; supply via ${ENV_VAR} interpolation, never a committed literal"),anchorDid:H.string().optional().describe("Optional human/operator DID referenced from records; defaults to did:web:<site-host>:anchor when omitted"),brainDid:H.string().optional().describe("Optional public brain DID referenced from records; defaults to did:web:<site-host> when omitted")});function f_Q(A){return A.replace(/\/+$/,"")}var I_Q=(A,Q)=>fetch(A,Q);async function Mr(A){let Q=await A.json();if(!A.ok){let B=typeof Q==="object"&&Q!==null&&"message"in Q&&typeof Q.message==="string"?Q.message:`AT Protocol request failed with ${A.status}`;throw Error(B)}return Q}class Cr{pdsEndpoint;identifier;appPassword;fetchFn;session;constructor(A){this.pdsEndpoint=f_Q(A.pdsEndpoint),this.identifier=A.identifier,this.appPassword=A.appPassword,this.fetchFn=A.fetch??I_Q}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 Mr(A);return this.session=Q,Q}async createRecord(A){let Q=await this.getSession(),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.createRecord`,{method:"POST",headers:{Authorization:`Bearer ${Q.accessJwt}`,"Content-Type":"application/json"},body:JSON.stringify({repo:A.repo,collection:A.collection,record:A.record,...A.rkey&&{rkey:A.rkey},...A.validate!==void 0&&{validate:A.validate}})});return Mr(B)}async putRecord(A){let Q=await this.getSession(),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.putRecord`,{method:"POST",headers:{Authorization:`Bearer ${Q.accessJwt}`,"Content-Type":"application/json"},body:JSON.stringify({repo:A.repo,collection:A.collection,record:A.record,rkey:A.rkey,...A.validate!==void 0&&{validate:A.validate},...A.swapRecord!==void 0&&{swapRecord:A.swapRecord}})});return Mr(B)}async getRecord(A){let Q=new URLSearchParams({repo:A.repo,collection:A.collection,rkey:A.rkey}),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.getRecord?${Q.toString()}`,{method:"GET"});return Mr(B)}async uploadBlob(A){let Q=await this.getSession(),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.uploadBlob`,{method:"POST",headers:{Authorization:`Bearer ${Q.accessJwt}`,"Content-Type":A.mimeType},body:new Blob([new Uint8Array(A.data)],{type:A.mimeType})});return Mr(B)}async getSession(){return this.session??=await this.createSession(),this.session}}function kC(A){return A?.startsWith("did:web:")??!1}function j9A(A){if(!kC(A))return;let Q=A.slice(8);if(!Q)return;let[B]=Q.split(":");if(!B)return;try{return decodeURIComponent(B)}catch{return B}}function FV1(A){if(!kC(A))return;let Q=A.slice(8);if(!Q)return;let[,...B]=Q.split(":");if(B.length===0)return"/.well-known/did.json";return`/${B.map(($)=>{try{return decodeURIComponent($)}catch{return $}}).join("/")}/did.json`}function ZV1(A){return A.replace(/\/+$/,"")}function Or(A){return`did:web:${encodeURIComponent(A)}`}function _9A(A){return`${Or(A)}:anchor`}function EuA(A){return{"@context":["https://www.w3.org/ns/did/v1"],id:A}}function NV1(A,Q){let B=A.identifier?.startsWith("did:")?void 0:A.identifier?[`at://${A.identifier}`]:void 0;return{...EuA(Q),...B&&{alsoKnownAs:B},service:[{id:"#atproto_pds",type:"AtprotoPersonalDataServer",serviceEndpoint:ZV1(A.pdsEndpoint)}]}}function zV1(A){if(!kC(A.brainDid))return null;return NV1(A,A.brainDid)}function KV1(A,Q){if(!A||!Q)return;let B=j9A(A),w=FV1(A);if(!B||!w)return;return{path:w,hostname:B,document:Q}}function v9A(A){let Q=[],B=KV1(A.brainDid,zV1(A));if(B)Q.push(B);if(kC(A.anchorDid)&&A.anchorDid!==A.brainDid){let w=KV1(A.anchorDid,EuA(A.anchorDid));if(w)Q.push(w)}return Q}function MuA(A,Q){let B=[];if(!A.brainDid){let w=Or(Q);B.push({path:"/.well-known/did.json",hostname:Q,document:NV1(A,w)})}if(!A.anchorDid){let w=_9A(Q);B.push({path:"/anchor/did.json",hostname:Q,document:EuA(w)})}return B}function D_Q(A,Q){if(!A)return;try{return new URL(A,Q).toString()}catch{return}}function U_Q(A){let Q=A.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,200);return Q.length>0?Q:"skill"}function qV1(A,Q){let B=A[Q];return typeof B==="string"&&B.length>0?B:void 0}function LV1(A,Q){let B=A[Q];if(!Array.isArray(B))return;let w=B.filter(($)=>typeof $==="string"&&$.length>0);return w.length>0?w:void 0}function Y_Q(A){let Q=A.metadata,B=qV1(Q,"name"),w=qV1(Q,"description");if(!B||!w)return;let $=LV1(Q,"tags"),f=LV1(Q,"examples");return{id:U_Q(B),name:B,description:w,...$&&{tags:$},...f&&{examples:f}}}async function J_Q(A){if(!A.entityService.hasEntityType("skill"))return[];return(await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}})).map((B)=>Y_Q(B)).filter((B)=>B!==void 0).slice(0,100)}async function CuA(A,Q,B=new Date){let w=A.identity.get(),$=A.identity.getProfile(),f=await A.identity.getAppInfo(),I=D_Q(A.siteUrl??$.website,void 0);if(!I)throw Error("AT Protocol brain card publishing requires siteUrl");let D=new URL(I).hostname,U=Q.brainDid??Or(D),Y=Q.anchorDid??_9A(D);if(kC(U)){if(j9A(U)!==D)throw Error("AT Protocol brain card did:web host must match siteUrl host")}let J=await J_Q(A);return{$type:"ai.rizom.brain.card",siteUrl:I,brain:{did:U,name:w.name,role:w.role,purpose:w.purpose,values:w.values},anchor:{did:Y,name:$.name,kind:$.kind},skills:J,model:f.model,version:f.version,createdAt:B.toISOString(),updatedAt:B.toISOString()}}WA();var VV1={dryRun:H.boolean().default(!1).describe("Build and return the card record without writing to the PDS")},X_Q={},EV1={entityType:H.string().describe("Local entity type with a registered AT Protocol projection"),entityId:H.string().optional().describe("Local entity ID to publish"),slug:H.string().optional().describe("Local entity slug to publish"),dryRun:H.boolean().default(!1).describe("Build and return the record without writing to the PDS"),topics:H.array(H.string()).optional().describe("Optional topic labels to include in the AT Protocol record")},MV1={repos:H.array(H.string().min(1)).min(1).max(50).describe("Candidate AT Protocol repo DIDs or handles to inspect")},CV1={entityId:H.string().optional().describe("Local blog post entity ID to publish"),slug:H.string().optional().describe("Local blog post slug to publish"),dryRun:H.boolean().default(!1).describe("Build and return the post record without writing to the PDS"),topics:H.array(H.string()).optional().describe("Optional topic labels to include in the AT Protocol record")};function OV1(A,Q,B){return[W_Q(A,Q),H_Q(A,Q,B),G_Q(A,Q,B),F_Q(A,Q,B),K_Q(A,Q,B)]}function W_Q(A,Q){return{name:`${A}_validate_credentials`,description:"Validate AT Protocol PDS credentials without publishing records.",inputSchema:X_Q,handler:async()=>{return{success:!0,data:{valid:await Q.validatePdsCredentials()}}}}}function H_Q(A,Q,B){return{name:`${A}_publish_card`,description:"Publish this brain's AT Protocol discovery card to the configured PDS, or dry-run the record payload.",inputSchema:VV1,handler:async(w)=>{let $=H.object(VV1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{return{success:!0,data:await Q.publishBrainCard(B,{dryRun:$.data.dryRun})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Publish failed"}}}}}function G_Q(A,Q,B){return{name:`${A}_publish_entity`,description:"Publish any public local entity with a registered AT Protocol projection, or dry-run the record payload.",inputSchema:EV1,handler:async(w)=>{let $=H.object(EV1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{if(!$.data.entityId&&!$.data.slug)return{success:!1,error:"Invalid input: entityId or slug is required"};return{success:!0,data:await Q.publishEntity(B,{entityType:$.data.entityType,...$.data.entityId&&{entityId:$.data.entityId},...$.data.slug&&{slug:$.data.slug},dryRun:$.data.dryRun,...$.data.topics&&{topics:$.data.topics}})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Publish failed"}}}}}function K_Q(A,Q,B){return{name:`${A}_discover_brain_cards`,description:"Read public ai.rizom.brain.card/self records from candidate AT Protocol repo DIDs or handles and emit internal discovery events.",inputSchema:MV1,handler:async(w)=>{let $=H.object(MV1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{return{success:!0,data:await Q.discoverBrainCards(B,{repos:$.data.repos})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Discovery failed"}}}}}function F_Q(A,Q,B){return{name:`${A}_publish_post`,description:"Publish a local blog post entity as an ai.rizom.brain.post AT Protocol record, or dry-run the record payload.",inputSchema:CV1,handler:async(w)=>{let $=H.object(CV1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{if(!$.data.entityId&&!$.data.slug)return{success:!1,error:"Invalid input: entityId or slug is required"};return{success:!0,data:await Q.publishPost(B,{...$.data.entityId&&{entityId:$.data.entityId},...$.data.slug&&{slug:$.data.slug},dryRun:$.data.dryRun,...$.data.topics&&{topics:$.data.topics}})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Publish failed"}}}}}var RV1={name:"@brains/atproto",private:!0,version:"0.2.0-alpha.127",description:"AT Protocol integration for identity, publishing, discovery, and feeds",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var bV1=Kw["ai.rizom.brain.card"],N_Q="ai.rizom.brain.card",z_Q="self",PV1=50;class OuA extends YB{deps;projectionRegistry;constructor(A={},Q={}){super("atproto",RV1,A,VuA);this.deps=Q,this.projectionRegistry=Q.projectionRegistry??o6.getInstance()}getWebRoutes(){if(!this.config.enabled)return[];let A=v9A(this.config),Q=[...!this.config.brainDid?["/.well-known/did.json"]:[],...!this.config.anchorDid?["/anchor/did.json"]:[]];return[...new Set([...A.map((w)=>w.path),...Q])].map((w)=>({path:w,method:"GET",public:!0,handler:($)=>{let f=new URL($.url).hostname,I=[...v9A(this.config),...MuA(this.config,f)].filter((U)=>U.path===w),D=I.find((U)=>U.hostname===f)??I[0];if(!D)return new Response("Not found",{status:404});return new Response(JSON.stringify(D.document),{headers:{"Content-Type":"application/did+json"}})}}))}async publishBrainCard(A,Q={}){let B=await CuA(A,this.config);cz(bV1,B);let w=this.config.repoDid;if(Q.dryRun)return{record:B,dryRun:!0,...w&&{repo:w}};let $=this.resolveAppPassword();if(!this.config.identifier||!$)throw Error("AT Protocol publishing requires identifier and app password configuration");let f=this.createPdsClient($),I=await f.createSession(),D=w??I.did;if(!f.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let U=await f.putRecord({repo:D,collection:"ai.rizom.brain.card",rkey:"self",validate:!1,record:B});return{record:B,repo:D,uri:U.uri,cid:U.cid,dryRun:!1}}async publishEntity(A,Q){let B=this.projectionRegistry.get(Q.entityType);if(!B)throw Error(`No AT Protocol projection registered for ${Q.entityType}`);return this.publishProjectedEntity(A,Q,B)}async publishPost(A,Q){let B=this.projectionRegistry.get("post");if(!B)throw Error("No AT Protocol projection registered for post");return this.publishProjectedEntity(A,{entityType:"post",...Q},B)}async discoverBrainCards(A,Q){let B=[...new Set(Q.repos.map((f)=>f.trim()))].filter((f)=>f.length>0);if(B.length===0)throw Error("AT Protocol discovery requires at least one repo DID or handle");if(B.length>PV1)throw Error(`AT Protocol discovery accepts at most ${PV1} repos per batch`);let w=new Set,$=[];for(let f of B)try{let I=await this.resolveRepoPdsEndpoint(f),D=this.createPublicPdsClient(I.pdsEndpoint);if(!D.getRecord)throw Error("AT Protocol PDS client does not support record reads");let U=await D.getRecord({repo:I.repoDid,collection:N_Q,rkey:z_Q});cz(bV1,U.value);let Y=L_Q(U.uri)??I.repoDid,J=`${Y}:${U.uri}:${U.cid}`;if(w.has(J)){$.push({repo:f,status:"skipped",repoDid:Y,uri:U.uri,cid:U.cid,error:"Duplicate brain card in discovery batch"});continue}w.add(J),await A.messaging.send({type:K5A,payload:{repoDid:Y,uri:U.uri,cid:U.cid,record:U.value},broadcast:!0}),$.push({repo:f,status:"discovered",repoDid:Y,uri:U.uri,cid:U.cid})}catch(I){$.push({repo:f,status:"skipped",error:y0(I)})}return{discovered:$.filter((f)=>f.status==="discovered").length,skipped:$.filter((f)=>f.status==="skipped").length,results:$}}async validatePdsCredentials(){let A=this.resolveAppPassword();if(!this.config.identifier||!A)return!1;try{return await this.createPdsClient(A).createSession(),!0}catch(Q){return this.logger.warn("AT Protocol PDS authentication failed",{error:y0(Q)}),!1}}async getTools(){if(!this.config.enabled)return[];return OV1(this.id,this,this.getContext())}async getInstructions(){if(!this.config.enabled)return;return"## AT Protocol publishing\n- Use `atproto_validate_credentials` to check PDS credentials before publishing.\n- Use `atproto_publish_card` to publish or dry-run this brain's public discovery card.\n- Use `atproto_publish_entity` to publish any public entity with a registered AT Protocol projection.\n- Use `atproto_publish_post` for the blog-post convenience path by `entityId` or `slug`.\n- Use `atproto_discover_brain_cards` to read public `ai.rizom.brain.card/self` records from candidate repo DIDs or handles and emit internal discovery events.\n- Prefer `dryRun: true` first when publishing new AT Protocol records.\n- Only public posts and public cover images can be published."}async publishProjectedEntity(A,Q,B){let w=await this.findPublishEntity(A,Q),$=Q.entityId??Q.slug;if(!$)throw Error(`${Q.entityType} publish requires entityId or slug`);if(!w)throw Error(`${Q.entityType} not found: ${$}`);if(w.visibility!=="public")throw Error(`Cannot publish non-public ${Q.entityType}: ${$}`);let f=this.config.repoDid;if(Q.dryRun){let G=await B.buildRecord({entity:w,context:A,config:this.config,...Q.topics&&{topics:Q.topics},dryRun:!0});return cz(B.lexicon,G),{record:G,dryRun:!0,...f&&{repo:f}}}let I=this.resolveAppPassword();if(!this.config.identifier||!I)throw Error("AT Protocol publishing requires identifier and app password configuration");let D=this.createPdsClient(I),U=await D.createSession(),Y=f??U.did,J=await B.buildRecord({entity:w,context:A,config:this.config,client:D,...Q.topics&&{topics:Q.topics}});if(cz(B.lexicon,J),!D.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let X=await D.putRecord({repo:Y,collection:B.collection,rkey:q_Q(w.id),...B.validate!==void 0&&{validate:B.validate},record:J});return await B.onPublished?.({entity:w,context:A,record:J,uri:X.uri,cid:X.cid}),{record:J,repo:Y,uri:X.uri,cid:X.cid,dryRun:!1}}async findPublishEntity(A,Q){if(Q.entityId)return A.entityService.getEntity({entityType:Q.entityType,id:Q.entityId});if(Q.slug)return(await A.entityService.listEntities({entityType:Q.entityType,options:{filter:{metadata:{slug:Q.slug}}}}))[0]??null;return null}createPublicPdsClient(A){if(this.deps.createPdsClient)return this.deps.createPdsClient({pdsEndpoint:A,identifier:this.config.identifier??"",appPassword:this.config.appPassword??""});return new Cr({pdsEndpoint:A,identifier:this.config.identifier??"",appPassword:this.config.appPassword??""})}async resolveRepoPdsEndpoint(A){let Q=A.startsWith("did:")?A:await this.resolveHandleToDid(A);if(!Q)throw Error(`Could not resolve AT Protocol repo: ${A}`);let B=await this.resolveDidToPdsEndpoint(Q);if(!B)throw Error(`Could not resolve AT Protocol PDS for repo: ${Q}`);return{repoDid:Q,pdsEndpoint:B}}async resolveHandleToDid(A){let Q=new URL("/xrpc/com.atproto.identity.resolveHandle",this.config.pdsEndpoint);Q.searchParams.set("handle",A);let B=await this.fetch(Q.toString());if(!B.ok)return;let w=await B.json();if(typeof w!=="object"||w===null||!("did"in w))return;return typeof w.did==="string"?w.did:void 0}async resolveDidToPdsEndpoint(A){let Q=A.startsWith("did:plc:")?await this.fetchJson(`https://plc.directory/${encodeURIComponent(A)}`):A.startsWith("did:web:")?await this.fetchJson(V_Q(A)):void 0;if(typeof Q!=="object"||Q===null)return;let B=Q.service;if(!Array.isArray(B))return;let w=B.find(($)=>{return typeof $==="object"&&$!==null&&($.id==="#atproto_pds"||$.type==="AtprotoPersonalDataServer")});return typeof w?.serviceEndpoint==="string"?w.serviceEndpoint:void 0}async fetchJson(A){let Q=await this.fetch(A);if(!Q.ok)return;return Q.json()}fetch(A){return(this.deps.fetch??fetch)(A)}createPdsClient(A){if(this.deps.createPdsClient)return this.deps.createPdsClient({pdsEndpoint:this.config.pdsEndpoint,identifier:this.config.identifier??"",appPassword:A});return new Cr({pdsEndpoint:this.config.pdsEndpoint,identifier:this.config.identifier??"",appPassword:A})}resolveAppPassword(){return this.config.appPassword}}function q_Q(A){let Q=A.replace(/[^A-Za-z0-9._~:-]/g,"_").slice(0,512);return Q.length>0?Q:"self"}function L_Q(A){return/^at:\/\/([^/]+)/.exec(A)?.[1]}function V_Q(A){let Q=A.slice(8).split(":").map(decodeURIComponent),[B,...w]=Q;if(!B)throw Error(`Invalid did:web value: ${A}`);if(w.length===0)return`https://${B}/.well-known/did.json`;return`https://${B}/${w.join("/")}/did.json`}function y9A(A,Q){return new OuA(A,Q)}aA();WA();Xw();I5();WA();aA();var T9A=zs.extend({expertise:H.array(H.string()).optional().describe("Skills, domains, areas of focus"),currentFocus:H.string().optional().describe("What you're currently working on"),availability:H.string().optional().describe("What you're open to (consulting, speaking, etc.)")}),Dq=oY.extend(T9A.shape);aA();BK();WA();var E_Q=new JW;class x9A{postsListUrl;decksListUrl;id="professional:homepage-list";name="Homepage List DataSource";description="Fetches profile, blog posts, and presentation decks for homepage";constructor(A,Q){this.postsListUrl=A;this.decksListUrl=Q}async fetch(A,Q,B){let w=B.entityService,[$,f,I,D]=await Promise.all([dR(w),w.listEntities({entityType:"post",options:{limit:20}}),w.listEntities({entityType:"deck",options:{limit:20}}),Di(w)]),U=E_Q.parseProfileBody($,Dq),Y=f.sort(aT).slice(0,3).map(Ji),J=I.sort(aT).slice(0,3).map(Fi);if(!D.cta)throw Error("CTA not configured in site-info");let X={profile:U,posts:Y,decks:J,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:D.cta,sections:D.sections??{}};return Q.parse(X)}}aA();BK();var M_Q=new JW;class S9A{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,B){let w=await dR(B.entityService),f={profile:M_Q.parseProfileBody(w,Dq)};return Q.parse(f)}}import{jsxDEV as $8,Fragment as R_Q}from"preact/jsx-dev-runtime";var C_Q="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",O_Q="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",RuA=({number:A,title:Q,blurb:B,children:w})=>$8("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:$8("div",{className:"max-w-6xl mx-auto",children:$8("div",{className:C_Q,children:[$8(syA,{title:Q,number:A,blurb:B},void 0,!1,void 0,this),$8("div",{className:O_Q,"aria-hidden":"true"},void 0,!1,void 0,this),$8("div",{className:"mt-6 md:mt-0",children:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),buA=({profile:A,posts:Q,decks:B,postsListUrl:w,decksListUrl:$,cta:f,sections:I})=>{let D=A.tagline||A.description,U=Q.map((Z)=>({id:Z.id,url:Z.url,title:Z.metadata.title,date:Z.metadata.publishedAt||Z.created,description:Z.frontmatter.excerpt,series:Z.frontmatter.seriesName&&Z.frontmatter.seriesIndex?{name:Z.frontmatter.seriesName,index:Z.frontmatter.seriesIndex}:void 0})),Y=B.map((Z)=>({id:Z.id,url:Z.url,title:Z.frontmatter.title||Z.id,date:Z.frontmatter.publishedAt??Z.created,description:Z.frontmatter.description})),J=A.name||"Home",X=A.intro||A.description||D||"Professional site",G=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return $8(R_Q,{children:[$8(ZQ,{title:J,description:X,ogType:"website"},void 0,!1,void 0,this),$8("div",{className:"homepage-list bg-theme",children:[$8("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:$8("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&$8("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[$8("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),$8("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D&&$8("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:P8A(D,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&$8("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:P8A(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),$8(RuA,{number:"01",title:"Essays",blurb:I.essays?.blurb,children:$8(b8A,{items:U,viewAllUrl:w,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Y.length>0&&$8(RuA,{number:"02",title:"Presentations",blurb:I.presentations?.blurb,children:$8(b8A,{items:Y,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G&&$8(RuA,{number:"03",title:"About",blurb:I.about?.blurb,children:$8("div",{className:"flex flex-col gap-8",children:[A.description&&$8("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&&$8(ayA,{subjects:A.expertise},void 0,!1,void 0,this),$8("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",$8("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),$8(TyA,{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 Zw,Fragment as b_Q}from"preact/jsx-dev-runtime";var PuA=({profile:A})=>{let Q=`About ${A.name||"Me"}`,B=A.description||A.intro||"About page",w=A.expertise&&A.expertise.length>0||A.currentFocus||A.availability||A.email||A.website||A.socialLinks&&A.socialLinks.length>0;return Zw(b_Q,{children:[Zw(ZQ,{title:Q,description:B,ogType:"profile"},void 0,!1,void 0,this),Zw("div",{className:"about-page bg-theme",children:[Zw("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:Zw("div",{className:"relative z-10 max-w-4xl mx-auto",children:[Zw("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&&Zw("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),Zw("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&Zw("section",{className:"content-section-reveal mb-20 md:mb-28",children:Zw(M$,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&Zw("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&Zw("section",{children:[Zw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),Zw("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,f)=>Zw("li",{className:Yp({variant:"accent",size:"lg"}),children:$},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&Zw("section",{children:[Zw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),Zw("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&&Zw("section",{children:[Zw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),Zw("p",{className:"text-lg text-theme leading-relaxed",children:A.availability},void 0,!1,void 0,this)]},void 0,!0,void 0,this),(A.email||A.website||A.socialLinks&&A.socialLinks.length>0)&&Zw("section",{children:[Zw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),Zw("div",{className:"space-y-4",children:[A.email&&Zw("p",{className:"text-lg",children:Zw("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&&Zw("p",{className:"text-lg",children:Zw("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&&Zw("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,f)=>Zw(E$,{href:$.url,external:!0,variant:"secondary",size:"md",children:$.label||$.platform},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as i7,Fragment as kV1}from"preact/jsx-dev-runtime";var kuA=()=>{return i7(kV1,{children:[i7(ZQ,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),i7("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:i7("div",{className:"text-center max-w-md",children:[i7("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),i7("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),i7("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),i7(E$,{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)},juA=()=>{return i7(kV1,{children:[i7(ZQ,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),i7("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:i7("div",{className:"text-center max-w-md",children:[i7("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),i7("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),i7("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),i7(E$,{href:"/",variant:"primary",children:"Back to Home"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};WA();var jV1=H.object({label:H.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:H.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')")}),_V1=H.object({entityDisplay:H.object({post:jV1,deck:jV1}).describe("Display metadata for post and deck entity types (required for homepage)")});var vV1={name:"@brains/site-professional",private:!0,version:"0.2.0-alpha.127",description:"Professional site composition package",type:"module",exports:{".":"./src/index.ts"},files:["src"],scripts:{typecheck:"tsc --noEmit",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/blog":"workspace:*","@brains/decks":"workspace:*","@brains/identity-service":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-engine":"workspace:*","@brains/site-info":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class _uA extends YB{dependencies=["blog","decks"];constructor(A){super("professional-site",vV1,A,_V1)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",T9A);let Q=this.config.entityDisplay.post,B=this.config.entityDisplay.deck,w=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,$=`/${B.pluralName??B.label.toLowerCase()+"s"}`,f=new x9A(w,$);A.entities.registerDataSource(f);let I=new S9A;A.entities.registerDataSource(I);let D=H.object({profile:Dq,posts:H.array(lF),decks:H.array(WC),postsListUrl:H.string(),decksListUrl:H.string(),cta:ZSA,sections:H.record(H.string(),Ro)}),U=H.object({profile:Dq}),Y=H.object({});A.templates.register({"homepage-list":P1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:D,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:buA}}),about:P1({name:"about",description:"About page with full profile information",schema:U,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:PuA}}),"subscribe-thanks":P1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:Y,requiredPermission:"public",layout:{component:kuA}}),"subscribe-error":P1({name:"subscribe-error",description:"Newsletter subscription error page",schema:Y,requiredPermission:"public",layout:{component:juA}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function yV1(A){return new _uA(A??{})}var TV1=[{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 g9A}from"preact/jsx-dev-runtime";function xV1({sections:A,siteInfo:Q,slots:B,wordmark:w}){return g9A("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[g9A(hyA,{title:Q.title,navigation:Q.navigation.primary,showThemeToggle:!0,...Q.logo!==void 0?{logo:Q.logo}:{},...w!==void 0?{wordmark:w}:{}},void 0,!1,void 0,this),g9A("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),g9A(SyA,{primaryNavigation:Q.navigation.primary,secondaryNavigation:Q.navigation.secondary,copyright:Q.copyright,socialLinks:Q.socialLinks,title:Q.title,tagline:Q.description,children:B?.getSlot("footer-top").map(($)=>$.render())},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var k_Q={layouts:{default:xV1},routes:TV1,plugin:yV1,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"}}}},Rr=k_Q;var SV1=`/*
|
|
8442
8442
|
* Default theme \u2014 simplified editorial base inspired by the Rizom family.
|
|
8443
8443
|
*
|
|
8444
8444
|
* This theme is intentionally less branded than @brains/theme-rizom. It
|
|
@@ -8826,8 +8826,8 @@ ${JSON.stringify(B,null,2)}`}function O9A(A){return A.map((Q)=>Q.detail===null?{
|
|
|
8826
8826
|
|
|
8827
8827
|
.btn-primary:disabled { opacity: 0.5; }
|
|
8828
8828
|
}
|
|
8829
|
-
`;var By=SV1;import{join as v_Q}from"path";var gV1={name:"@brains/rover",version:"0.2.0-alpha.
|
|
8830
|
-
`,{headers:{"Content-Type":"application/json"}})}class yuA extends YB{constructor(A={}){super("atproto-registry",cV1,A,pV1)}getWebRoutes(){if(!this.config.enabled)return[];return[{path:`${vuA}/index.json`,method:"GET",public:!0,handler:()=>lV1(this.getIndex())},...DC().map((A)=>({path:`${vuA}/${A.id}.json`,method:"GET",public:!0,handler:()=>lV1(A)}))]}getIndex(){return{lexicons:VSA().map((A)=>({...A,path:`${vuA}/${A.id}.json`}))}}getLexicon(A){return LSA(A)}async getTools(){return[this.createListLexiconsTool(),this.createValidateLexiconTool(),this.createCheckContractsTool()]}createListLexiconsTool(){return{name:`${this.id}_list_lexicons`,description:"List canonical Rizom AT Protocol lexicons.",inputSchema:{},handler:async()=>({success:!0,data:this.getIndex()})}}createValidateLexiconTool(){return{name:`${this.id}_validate_lexicon`,description:"Validate a record payload against a canonical Rizom AT Protocol lexicon.",inputSchema:{nsid:H.string().describe("Canonical lexicon NSID"),record:H.record(H.unknown()).describe("Record payload to validate")},handler:async(A)=>{let Q=H.object({nsid:H.string(),record:H.record(H.unknown())}).safeParse(A);if(!Q.success)return{success:!1,error:`Invalid input: ${Q.error.message}`};let B=this.getLexicon(Q.data.nsid);if(!B)return{success:!1,error:`Unknown AT Protocol lexicon: ${Q.data.nsid}`};try{return cz(B,Q.data.record),{success:!0,data:{valid:!0}}}catch(w){return{success:!0,data:{valid:!1,error:w instanceof Error?w.message:"Invalid record"}}}}}}createCheckContractsTool(){return{name:`${this.id}_check_contracts`,description:"Check that canonical Rizom AT Protocol lexicon contracts are available.",inputSchema:{},handler:async()=>({success:!0,data:{lexiconCount:DC().length,nsids:DC().map((A)=>A.id),metadata:VSA()}})}}}function TuA(A={}){return new yuA(A)}aA();WA();WA();aA();var h9A=H.object({routeId:H.string(),sectionId:H.string()}),br=A2.extend({entityType:H.literal("site-content"),template:H.string().optional(),content:H.string(),metadata:h9A});aA();class iV1 extends q2{constructor(){super({entityType:"site-content",schema:br,frontmatterSchema:h9A})}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 xuA=new iV1;WA();var m9A=H.object({routeId:H.string().optional().describe("Optional: specific route filter"),sectionId:H.string().optional().describe("Optional: specific section filter"),dryRun:H.boolean().optional().default(!1).describe("Optional: preview changes without executing"),force:H.boolean().optional().default(!1).describe("Force regeneration even if content exists")}),RY8=H.object({jobs:H.array(H.object({jobId:H.string(),routeId:H.string(),sectionId:H.string()})),totalSections:H.number(),queuedSections:H.number(),skippedSections:H.number().optional(),batchId:H.string().optional()});class SuA{context;constructor(A){this.context=A}createJobOptions(A,Q){if(!A)return;return{source:A.operationType??Q,rootJobId:A.rootJobId??`${Q}-${Date.now()}`,metadata:{operationType:A.operationType??"content_operations",progressToken:A.progressToken,pluginId:A.pluginId??"site-content"}}}async fetchRoutes(){let A=await this.context.messaging.send({type:"site-builder:routes:list",payload:{}});if("noop"in A)throw Error("No handler for site-builder:routes:list \u2014 is site-builder plugin loaded?");if(!A.success||!A.data)throw Error("Failed to fetch routes from site-builder");return A.data}async generate(A,Q,B){let w=this.context.logger.child("SiteContentOperations"),$=await this.fetchRoutes(),f=$;if(A.routeId){if(f=$.filter((J)=>J.id===A.routeId),f.length===0)throw Error(`Route not found: ${A.routeId}`)}let I=[];for(let J of f)for(let X of J.sections){if(A.sectionId&&X.id!==A.sectionId)continue;if(X.content){w.debug("Section has static content, skipping",{routeId:J.id,sectionId:X.id});continue}if(X.template){let G=this.context.templates.getCapabilities(X.template);if(!G){w.warn("Template not found, skipping section",{routeId:J.id,sectionId:X.id,templateName:X.template});continue}if(!G.canGenerate){w.debug("Template doesn't support generation, skipping",{routeId:J.id,sectionId:X.id,templateName:X.template,capabilities:G});continue}}else{w.debug("Section has no template, skipping",{routeId:J.id,sectionId:X.id});continue}if(!A.force&&!A.dryRun){let G=`${J.id}:${X.id}`;if(await this.context.entityService.getEntity({entityType:"site-content",id:G})){w.debug("Content already exists, skipping",{routeId:J.id,sectionId:X.id});continue}}I.push({route:J,section:X})}let D=I.length;if(A.dryRun)return{jobs:[],totalSections:D,queuedSections:D,batchId:`dry-run-${Date.now()}`};let U=[],Y=[];for(let{route:J,section:X}of I){let G=`${J.id}:${X.id}`,Z=X.template,N={routeId:J.id,sectionId:X.id,entityId:G,entityType:"site-content",templateName:Z,context:{prompt:typeof X.content==="string"?X.content:void 0,data:{routeId:J.id,sectionId:X.id,routeTitle:J.title??Q?.title??"",routeDescription:J.description??Q?.description??"",sectionContent:X.content},conversationId:"system"},siteConfig:Q};Y.push({type:"shell:content-generation",data:N})}if(Y.length>0){let J=this.createJobOptions(B,"site:content-generation"),X=await this.context.jobs.enqueueBatch(Y,J);for(let G=0;G<I.length;G++){let Z=I[G];if(Z)U.push({jobId:`${X}-${G}`,routeId:Z.route.id,sectionId:Z.section.id})}return{jobs:U,totalSections:D,queuedSections:U.length,batchId:X}}return{jobs:[],totalSections:D,queuedSections:0,batchId:`empty-${Date.now()}`}}}class guA{siteConfig;operations;constructor(A,Q){this.siteConfig=Q;this.operations=new SuA(A)}async generateContent(A,Q){let B=m9A.parse(A);return this.operations.generate(B,this.siteConfig,Q)}}t$();WA();function Pr(A,Q){return Q?A.optional():A}function muA(A){switch(A.type){case"string":return Pr(H.string(),A.optional);case"number":return Pr(H.number(),A.optional);case"enum":{let Q=[...A.options];return Pr(H.enum(Q),A.optional)}case"object":{let Q={};for(let[B,w]of Object.entries(A.fields))Q[B]=muA(w);return Pr(H.object(Q),A.optional)}case"array":{let Q=H.array(S_Q(A));if(A.minItems!==void 0)Q=Q.min(A.minItems);if(A.length!==void 0)Q=Q.length(A.length);return Pr(Q,A.optional)}}}function S_Q(A){let{items:Q}=A;switch(Q.type){case"string":return H.string();case"number":return H.number();case"enum":{let B=[...Q.options];return H.enum(B)}case"object":{let B={};for(let[w,$]of Object.entries(Q.fields))B[w]=muA($);return H.object(B)}}}function huA(A,Q){switch(Q.type){case"string":case"enum":return{key:A,label:Q.label,type:"string"};case"number":return{key:A,label:Q.label,type:"number"};case"object":return{key:A,label:Q.label,type:"object",children:Object.entries(Q.fields).map(([B,w])=>huA(B,w))};case"array":{let B={key:A,label:Q.label,type:"array"};switch(Q.items.type){case"string":case"enum":return B.itemType="string",B;case"number":return B.itemType="number",B;case"object":return B.itemType="object",B.itemMappings=Object.entries(Q.items.fields).map(([w,$])=>huA(w,$)),B}}}}function g_Q(A,Q){let B={};for(let[f,I]of Object.entries(Q.fields))B[f]=muA(I);let w=H.object(B),$=new lB(w,{title:Q.title,mappings:Object.entries(Q.fields).map(([f,I])=>huA(f,I))});return{name:A,description:Q.description,schema:w,formatter:$,requiredPermission:Q.requiredPermission??"public",layout:{component:Q.layout,...Q.fullscreen!==void 0?{fullscreen:Q.fullscreen}:{}},...Q.runtimeScripts?{runtimeScripts:Q.runtimeScripts}:{}}}function uuA(A){return Object.fromEntries(Object.entries(A.sections).map(([Q,B])=>[Q,g_Q(Q,B)]))}WA();var rV1=H.object({namespace:H.string(),sections:H.record(H.any())}),dV1=H.object({definitions:H.union([rV1,H.array(rV1)]).optional()});aA();function nV1(A,Q){return[oQ(Q,"generate","Generate content for all routes, a specific route, or a specific section",m9A,async(B,w)=>{let $=A();if(!$)return{success:!1,error:"Site content service not initialized"};if(B.sectionId&&!B.routeId)return{success:!1,error:"sectionId requires routeId to be specified"};let f={rootJobId:`generate-${Date.now()}`,progressToken:w.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:w.interfaceType,channelId:w.channelId},I=await $.generateContent(B,f);return{success:!0,message:`Generated ${I.queuedSections} of ${I.totalSections} sections. ${I.queuedSections>0?"Jobs are running in the background.":"No new content to generate."}`,data:{batchId:I.batchId,jobsQueued:I.queuedSections,totalSections:I.totalSections,jobs:I.jobs}}})]}var oV1={name:"@brains/site-content",private:!0,version:"0.2.0-alpha.125",description:"Site content entity and generation orchestration",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/plugins":"workspace:*","@brains/site-info":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class cuA extends YB{siteContentService;constructor(A={}){super("site-content",oV1,A,dV1)}async onRegister(A){A.entities.register("site-content",br,xuA);for(let Q of eX(this.config.definitions))A.templates.register(uuA(Q),Q.namespace);this.siteContentService=new guA(A)}async getTools(){return nV1(()=>this.siteContentService,this.id)}}function kr(A={}){return new cuA(A)}aA();WA();Xw();WA();aA();var sV1=H.enum(["available","early access","coming soon","planned"]),aV1=H.object({title:H.string(),description:H.string()}),kD=H.object({name:H.string(),availability:sV1,order:H.number(),ogImageId:H.string().optional()}),u9A=H.object({tagline:H.string(),promise:H.string(),role:H.string(),purpose:H.string(),audience:H.string(),values:H.array(H.string()).min(1),features:H.array(aV1).min(1).max(6),story:H.string()}),m_Q=kD.pick({name:!0,availability:!0,order:!0}).extend({slug:H.string()}),wy=A2.extend({entityType:H.literal("product"),metadata:m_Q}),c9A=wy.extend({frontmatter:kD,body:u9A,labels:H.record(H.string(),H.string()),ogImageUrl:H.string().optional()}),l9A=c9A.extend({url:H.string().optional(),typeLabel:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),ogImageUrl:H.string().optional()});aA();WA();t$();class $y extends lB{constructor(){super(u9A,{title:"Product",mappings:[{key:"tagline",label:"Tagline",type:"string"},{key:"promise",label:"Promise",type:"string"},{key:"role",label:"Role",type:"string"},{key:"purpose",label:"Purpose",type:"string"},{key:"audience",label:"Audience",type:"string"},{key:"values",label:"Values",type:"array",itemType:"string"},{key:"features",label:"Capabilities",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"story",label:"Story",type:"string"}]})}}class luA extends q2{constructor(){super({entityType:"product",schema:wy,frontmatterSchema:kD,bodyFormatter:new $y})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,kD);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,kD),B=X1(Q.name);return{content:A,entityType:"product",metadata:{name:Q.name,slug:B,availability:Q.availability,order:Q.order}}}}var p9A=new luA;WA();aA();var tV1=H.object({title:H.string(),description:H.string()}),eV1=H.object({title:H.string(),description:H.string()}),u_Q=H.object({title:H.string(),description:H.string()}),AE1=H.object({heading:H.string(),buttonText:H.string(),link:H.string()}),BZ=H.object({headline:H.string(),tagline:H.string()}),c_Q=H.object({title:H.string(),description:H.string()}),i9A=H.object({vision:H.string(),pillars:H.array(tV1).min(1).max(6),approach:H.array(c_Q).min(1).max(6),productsIntro:H.string(),technologies:H.array(u_Q).min(1).max(6),benefits:H.array(eV1).min(1).max(6),cta:AE1}),QE1=BZ.pick({headline:!0}).extend({slug:H.string()}),fy=A2.extend({entityType:H.literal("products-overview"),metadata:QE1}),jr=fy.extend({frontmatter:BZ,body:i9A,labels:H.record(H.string(),H.string())});aA();WA();t$();class Iy extends lB{constructor(){super(i9A,{title:"Products Overview",mappings:[{key:"vision",label:"Vision",type:"string"},{key:"pillars",label:"Core Principles",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"approach",label:"How It Works",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"productsIntro",label:"Products",type:"string"},{key:"technologies",label:"Built With",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"benefits",label:"Why Brains",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"cta",label:"Ready to Build",type:"object",children:[{key:"heading",label:"Heading",type:"string"},{key:"buttonText",label:"Button Text",type:"string"},{key:"link",label:"Link",type:"string"}]}]})}}class puA extends q2{constructor(){super({entityType:"products-overview",schema:fy,frontmatterSchema:BZ,bodyFormatter:new Iy})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,BZ);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,BZ),B=X1(Q.headline);return{content:A,entityType:"products-overview",metadata:{headline:Q.headline,slug:B}}}}var iuA=new puA;aA();WA();var l_Q=H.object({entityType:H.string(),query:H.object({id:H.string().optional()}).optional()});function BE1(A,Q){let B=b2(A.content,kD),w=Q.parse(B.content),$=Q.getLabels();return c9A.parse({...A,frontmatter:B.metadata,body:w,labels:$})}function wE1(A,Q){let B=b2(A.content,BZ),w=Q.parse(B.content),$=Q.getLabels();return jr.parse({...A,frontmatter:B.metadata,body:w,labels:$})}class r9A{logger;id="products:entities";name="Products Entity DataSource";description="Fetches products and overview for the products page";overviewFormatter=new Iy;productFormatter=new $y;constructor(A){this.logger=A;this.logger.debug("ProductsDataSource initialized")}async fetch(A,Q,B){let w=l_Q.parse(A),$=B.entityService;if(w.entityType==="products-overview"){let Y=(await $.listEntities({entityType:"products-overview",options:{limit:1}}))[0];if(!Y)throw Error("Products overview entity not found");let J=wE1(Y,this.overviewFormatter);return Q.parse(J)}if(w.query?.id){let Y=(await $.listEntities({entityType:"product",options:{filter:{metadata:{slug:w.query.id}},limit:1}}))[0];if(!Y)throw Error(`Product not found: ${w.query.id}`);return Q.parse({product:BE1(Y,this.productFormatter)})}let[f,I]=await Promise.all([$.listEntities({entityType:"products-overview",options:{limit:1}}),$.listEntities({entityType:"product",options:{sortFields:[{field:"order",direction:"asc"}]}})]),D=f[0];if(!D)throw Error("Products overview entity not found");return Q.parse({overview:wE1(D,this.overviewFormatter),products:I.map((U)=>BE1(U,this.productFormatter))})}}import{jsxDEV as A1,Fragment as r_Q}from"preact/jsx-dev-runtime";var $E1=({overview:A,products:Q})=>{let{frontmatter:B,body:w,labels:$}=A;return A1(r_Q,{children:[A1(ZQ,{title:B.headline,description:B.tagline},void 0,!1,void 0,this),A1("header",{className:"relative w-full min-h-[80vh] flex items-end px-6 md:px-12 bg-brand-dark overflow-hidden",children:[A1("style",{children:`
|
|
8829
|
+
`;var By=SV1;import{join as v_Q}from"path";var gV1={name:"@brains/rover",version:"0.2.0-alpha.127",type:"module",private:!0,main:"./src/index.ts",files:["src","brain.eval.yaml","env.schema.template"],scripts:{"build:web-chat":"turbo run build --filter=@brains/web-chat","start:core":"bun run build:web-chat && cd test-apps/core && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:default":"bun run build:web-chat && cd test-apps/default && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:full":"bun run build:web-chat && cd test-apps/full && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start",typecheck:"tsc --noEmit",eval:"brain-eval","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 .","lint:fix":"eslint . --fix"},dependencies:{"@brains/a2a":"workspace:*","@brains/agent-discovery":"workspace:*","@brains/analytics":"workspace:*","@brains/app":"workspace:*","@brains/assessment":"workspace:*","@brains/atproto":"workspace:*","@brains/auth-service":"workspace:*","@brains/blog":"workspace:*","@brains/cms":"workspace:*","@brains/content-pipeline":"workspace:*","@brains/dashboard":"workspace:*","@brains/decks":"workspace:*","@brains/directory-sync":"workspace:*","@brains/discord":"workspace:*","@brains/document-plugin":"workspace:*","@brains/email-resend":"workspace:*","@brains/image-plugin":"workspace:*","@brains/link":"workspace:*","@brains/mcp":"workspace:*","@brains/newsletter":"workspace:*","@brains/note":"workspace:*","@brains/notifications":"workspace:*","@brains/obsidian-vault":"workspace:*","@brains/portfolio":"workspace:*","@brains/prompt":"workspace:*","@brains/rizom-ecosystem":"workspace:*","@brains/series":"workspace:*","@brains/site-builder-plugin":"workspace:*","@brains/site-default":"workspace:*","@brains/site-info":"workspace:*","@brains/social-media":"workspace:*","@brains/stock-photo":"workspace:*","@brains/theme-default":"workspace:*","@brains/topics":"workspace:*","@brains/web-chat":"workspace:*","@brains/webserver":"workspace:*","@brains/wishlist":"workspace:*"},devDependencies:{"@brains/ai-evaluation":"workspace:*","@brains/typescript-config":"workspace:*",typescript:"^5.3.3"}};var hV1=["prompt","image","document","note","link","wishlist","topics","directory-sync","atproto","agents","assessment","auth-service","notifications","email-resend","cms","dashboard-root","mcp","webserver","web-chat","discord","a2a"],mV1=[...hV1.filter((A)=>A!=="dashboard-root"),"dashboard","blog","series","decks","analytics","obsidian-vault","site-info","site-builder"],y_Q=[...mV1,"portfolio","topics","content-pipeline","social-media","newsletter","stock-photo"],T_Q=["Rover is a personal professional knowledge and publishing brain for an independent professional. Prioritize personal knowledge management, professional website content, essays, projects, decks, newsletters, and social distribution workflows.",'Rover entity mappings: "blog post", "post", "essay", "article" \u2192 entityType: post; "case study", "portfolio piece", "project" \u2192 entityType: project; "presentation", "deck", "slides" \u2192 entityType: deck; "newsletter" \u2192 entityType: newsletter; "LinkedIn post", "social post" \u2192 entityType: social-post.',"When a user asks for a publishing/content overview, use the available publishing entity types directly instead of treating the request as generic team memory.","Draft blog posts are only post entities with status draft. If the user asks whether draft blog posts exist, call only system_list for entityType post with status draft; do not also list social-post, newsletter, deck, or other draft entity types."],uV1=nN({name:"rover",version:gV1.version,model:"gpt-5.4-mini",site:Rr,theme:By,presets:{core:hV1,default:mV1,full:y_Q},evalDisable:["discord","webserver","web-chat","mcp","atproto","analytics","dashboard","dashboard-root","email-resend"],agentInstructions:T_Q,capabilities:[["prompt",RC,void 0],["image",zh,void 0],["cms",OC,(A)=>({...A.CMS_CONTENT_REPO_PAT?{passkeyLogin:{contentRepoToken:A.CMS_CONTENT_REPO_PAT}}:{}})],["auth-service",Ju,void 0],["notifications",A1A,void 0],["email-resend",vwA,void 0],["dashboard",fq,void 0],["dashboard-root",fq,{routePath:"/"}],["blog",gSA,{}],["series",pSA,void 0],["decks",Zi,void 0],["document",ogA,void 0],["note",NC,{}],["link",qC,{}],["portfolio",EhA,{}],["topics",v$A,{includeEntityTypes:["post","deck","project","link","anchor-profile"]}],["content-pipeline",JmA,{generationSchedules:{newsletter:"0 9 * * 1","social-post":"0 10 * * *"},generationConditions:{newsletter:{skipIfDraftExists:!0,minSourceEntities:1,sourceEntityType:"post"},"social-post":{skipIfDraftExists:!0,maxUnpublishedDrafts:5}}}],["social-media",Ar,{autoGenerateOnBlogPublish:!0}],["newsletter",iq1,{doubleOptIn:!0}],["obsidian-vault",vmA,{autoSync:!0}],["wishlist",w9A,{}],["stock-photo",cmA,{}],["agents",q9A,void 0],["assessment",k9A,void 0],["atproto",y9A,(A)=>({...A.ATPROTO_APP_PASSWORD?{appPassword:A.ATPROTO_APP_PASSWORD}:{}})],["directory-sync",LM,{seedContent:!0,seedContentPath:v_Q(import.meta.dir,"..","seed-content"),initialSync:!0}],["analytics",o$A,{}],["rizom-ecosystem",bC,void 0],["site-info",IC,void 0],["site-builder",fC,{cms:{}}]],interfaces:[["mcp",P3,()=>({})],["discord",Jz,()=>({})],["webserver",Xz,()=>({})],["web-chat",f_,()=>({})],["a2a",I_,()=>({})]],permissions:{rules:[{pattern:"cli:*",level:"anchor"},{pattern:"mcp:stdio",level:"anchor"},{pattern:"mcp:http",level:"public"},{pattern:"discord:*",level:"public"},{pattern:"web-chat:*",level:"anchor"}],entityActions:{"*":{create:"anchor",update:"anchor",delete:"anchor",extract:"anchor"}}},deployment:{cdn:{enabled:!0,provider:"bunny"},dns:{enabled:!0,provider:"bunny"}}});aN();aA();WA();var cV1={name:"@brains/atproto-registry",private:!0,version:"0.2.0-alpha.127",description:"Canonical Rizom AT Protocol lexicon registry",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var pV1=H.object({enabled:H.boolean().default(!0)}),vuA="/atproto/lexicons";function lV1(A){return new Response(`${JSON.stringify(A,null,2)}
|
|
8830
|
+
`,{headers:{"Content-Type":"application/json"}})}class yuA extends YB{constructor(A={}){super("atproto-registry",cV1,A,pV1)}getWebRoutes(){if(!this.config.enabled)return[];return[{path:`${vuA}/index.json`,method:"GET",public:!0,handler:()=>lV1(this.getIndex())},...DC().map((A)=>({path:`${vuA}/${A.id}.json`,method:"GET",public:!0,handler:()=>lV1(A)}))]}getIndex(){return{lexicons:VSA().map((A)=>({...A,path:`${vuA}/${A.id}.json`}))}}getLexicon(A){return LSA(A)}async getTools(){return[this.createListLexiconsTool(),this.createValidateLexiconTool(),this.createCheckContractsTool()]}createListLexiconsTool(){return{name:`${this.id}_list_lexicons`,description:"List canonical Rizom AT Protocol lexicons.",inputSchema:{},handler:async()=>({success:!0,data:this.getIndex()})}}createValidateLexiconTool(){return{name:`${this.id}_validate_lexicon`,description:"Validate a record payload against a canonical Rizom AT Protocol lexicon.",inputSchema:{nsid:H.string().describe("Canonical lexicon NSID"),record:H.record(H.unknown()).describe("Record payload to validate")},handler:async(A)=>{let Q=H.object({nsid:H.string(),record:H.record(H.unknown())}).safeParse(A);if(!Q.success)return{success:!1,error:`Invalid input: ${Q.error.message}`};let B=this.getLexicon(Q.data.nsid);if(!B)return{success:!1,error:`Unknown AT Protocol lexicon: ${Q.data.nsid}`};try{return cz(B,Q.data.record),{success:!0,data:{valid:!0}}}catch(w){return{success:!0,data:{valid:!1,error:w instanceof Error?w.message:"Invalid record"}}}}}}createCheckContractsTool(){return{name:`${this.id}_check_contracts`,description:"Check that canonical Rizom AT Protocol lexicon contracts are available.",inputSchema:{},handler:async()=>({success:!0,data:{lexiconCount:DC().length,nsids:DC().map((A)=>A.id),metadata:VSA()}})}}}function TuA(A={}){return new yuA(A)}aA();WA();WA();aA();var h9A=H.object({routeId:H.string(),sectionId:H.string()}),br=A2.extend({entityType:H.literal("site-content"),template:H.string().optional(),content:H.string(),metadata:h9A});aA();class iV1 extends q2{constructor(){super({entityType:"site-content",schema:br,frontmatterSchema:h9A})}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 xuA=new iV1;WA();var m9A=H.object({routeId:H.string().optional().describe("Optional: specific route filter"),sectionId:H.string().optional().describe("Optional: specific section filter"),dryRun:H.boolean().optional().default(!1).describe("Optional: preview changes without executing"),force:H.boolean().optional().default(!1).describe("Force regeneration even if content exists")}),RY8=H.object({jobs:H.array(H.object({jobId:H.string(),routeId:H.string(),sectionId:H.string()})),totalSections:H.number(),queuedSections:H.number(),skippedSections:H.number().optional(),batchId:H.string().optional()});class SuA{context;constructor(A){this.context=A}createJobOptions(A,Q){if(!A)return;return{source:A.operationType??Q,rootJobId:A.rootJobId??`${Q}-${Date.now()}`,metadata:{operationType:A.operationType??"content_operations",progressToken:A.progressToken,pluginId:A.pluginId??"site-content"}}}async fetchRoutes(){let A=await this.context.messaging.send({type:"site-builder:routes:list",payload:{}});if("noop"in A)throw Error("No handler for site-builder:routes:list \u2014 is site-builder plugin loaded?");if(!A.success||!A.data)throw Error("Failed to fetch routes from site-builder");return A.data}async generate(A,Q,B){let w=this.context.logger.child("SiteContentOperations"),$=await this.fetchRoutes(),f=$;if(A.routeId){if(f=$.filter((J)=>J.id===A.routeId),f.length===0)throw Error(`Route not found: ${A.routeId}`)}let I=[];for(let J of f)for(let X of J.sections){if(A.sectionId&&X.id!==A.sectionId)continue;if(X.content){w.debug("Section has static content, skipping",{routeId:J.id,sectionId:X.id});continue}if(X.template){let G=this.context.templates.getCapabilities(X.template);if(!G){w.warn("Template not found, skipping section",{routeId:J.id,sectionId:X.id,templateName:X.template});continue}if(!G.canGenerate){w.debug("Template doesn't support generation, skipping",{routeId:J.id,sectionId:X.id,templateName:X.template,capabilities:G});continue}}else{w.debug("Section has no template, skipping",{routeId:J.id,sectionId:X.id});continue}if(!A.force&&!A.dryRun){let G=`${J.id}:${X.id}`;if(await this.context.entityService.getEntity({entityType:"site-content",id:G})){w.debug("Content already exists, skipping",{routeId:J.id,sectionId:X.id});continue}}I.push({route:J,section:X})}let D=I.length;if(A.dryRun)return{jobs:[],totalSections:D,queuedSections:D,batchId:`dry-run-${Date.now()}`};let U=[],Y=[];for(let{route:J,section:X}of I){let G=`${J.id}:${X.id}`,Z=X.template,N={routeId:J.id,sectionId:X.id,entityId:G,entityType:"site-content",templateName:Z,context:{prompt:typeof X.content==="string"?X.content:void 0,data:{routeId:J.id,sectionId:X.id,routeTitle:J.title??Q?.title??"",routeDescription:J.description??Q?.description??"",sectionContent:X.content},conversationId:"system"},siteConfig:Q};Y.push({type:"shell:content-generation",data:N})}if(Y.length>0){let J=this.createJobOptions(B,"site:content-generation"),X=await this.context.jobs.enqueueBatch(Y,J);for(let G=0;G<I.length;G++){let Z=I[G];if(Z)U.push({jobId:`${X}-${G}`,routeId:Z.route.id,sectionId:Z.section.id})}return{jobs:U,totalSections:D,queuedSections:U.length,batchId:X}}return{jobs:[],totalSections:D,queuedSections:0,batchId:`empty-${Date.now()}`}}}class guA{siteConfig;operations;constructor(A,Q){this.siteConfig=Q;this.operations=new SuA(A)}async generateContent(A,Q){let B=m9A.parse(A);return this.operations.generate(B,this.siteConfig,Q)}}t$();WA();function Pr(A,Q){return Q?A.optional():A}function muA(A){switch(A.type){case"string":return Pr(H.string(),A.optional);case"number":return Pr(H.number(),A.optional);case"enum":{let Q=[...A.options];return Pr(H.enum(Q),A.optional)}case"object":{let Q={};for(let[B,w]of Object.entries(A.fields))Q[B]=muA(w);return Pr(H.object(Q),A.optional)}case"array":{let Q=H.array(S_Q(A));if(A.minItems!==void 0)Q=Q.min(A.minItems);if(A.length!==void 0)Q=Q.length(A.length);return Pr(Q,A.optional)}}}function S_Q(A){let{items:Q}=A;switch(Q.type){case"string":return H.string();case"number":return H.number();case"enum":{let B=[...Q.options];return H.enum(B)}case"object":{let B={};for(let[w,$]of Object.entries(Q.fields))B[w]=muA($);return H.object(B)}}}function huA(A,Q){switch(Q.type){case"string":case"enum":return{key:A,label:Q.label,type:"string"};case"number":return{key:A,label:Q.label,type:"number"};case"object":return{key:A,label:Q.label,type:"object",children:Object.entries(Q.fields).map(([B,w])=>huA(B,w))};case"array":{let B={key:A,label:Q.label,type:"array"};switch(Q.items.type){case"string":case"enum":return B.itemType="string",B;case"number":return B.itemType="number",B;case"object":return B.itemType="object",B.itemMappings=Object.entries(Q.items.fields).map(([w,$])=>huA(w,$)),B}}}}function g_Q(A,Q){let B={};for(let[f,I]of Object.entries(Q.fields))B[f]=muA(I);let w=H.object(B),$=new lB(w,{title:Q.title,mappings:Object.entries(Q.fields).map(([f,I])=>huA(f,I))});return{name:A,description:Q.description,schema:w,formatter:$,requiredPermission:Q.requiredPermission??"public",layout:{component:Q.layout,...Q.fullscreen!==void 0?{fullscreen:Q.fullscreen}:{}},...Q.runtimeScripts?{runtimeScripts:Q.runtimeScripts}:{}}}function uuA(A){return Object.fromEntries(Object.entries(A.sections).map(([Q,B])=>[Q,g_Q(Q,B)]))}WA();var rV1=H.object({namespace:H.string(),sections:H.record(H.any())}),dV1=H.object({definitions:H.union([rV1,H.array(rV1)]).optional()});aA();function nV1(A,Q){return[oQ(Q,"generate","Generate content for all routes, a specific route, or a specific section",m9A,async(B,w)=>{let $=A();if(!$)return{success:!1,error:"Site content service not initialized"};if(B.sectionId&&!B.routeId)return{success:!1,error:"sectionId requires routeId to be specified"};let f={rootJobId:`generate-${Date.now()}`,progressToken:w.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:w.interfaceType,channelId:w.channelId},I=await $.generateContent(B,f);return{success:!0,message:`Generated ${I.queuedSections} of ${I.totalSections} sections. ${I.queuedSections>0?"Jobs are running in the background.":"No new content to generate."}`,data:{batchId:I.batchId,jobsQueued:I.queuedSections,totalSections:I.totalSections,jobs:I.jobs}}})]}var oV1={name:"@brains/site-content",private:!0,version:"0.2.0-alpha.127",description:"Site content entity and generation orchestration",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/plugins":"workspace:*","@brains/site-info":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class cuA extends YB{siteContentService;constructor(A={}){super("site-content",oV1,A,dV1)}async onRegister(A){A.entities.register("site-content",br,xuA);for(let Q of eX(this.config.definitions))A.templates.register(uuA(Q),Q.namespace);this.siteContentService=new guA(A)}async getTools(){return nV1(()=>this.siteContentService,this.id)}}function kr(A={}){return new cuA(A)}aA();WA();Xw();WA();aA();var sV1=H.enum(["available","early access","coming soon","planned"]),aV1=H.object({title:H.string(),description:H.string()}),kD=H.object({name:H.string(),availability:sV1,order:H.number(),ogImageId:H.string().optional()}),u9A=H.object({tagline:H.string(),promise:H.string(),role:H.string(),purpose:H.string(),audience:H.string(),values:H.array(H.string()).min(1),features:H.array(aV1).min(1).max(6),story:H.string()}),m_Q=kD.pick({name:!0,availability:!0,order:!0}).extend({slug:H.string()}),wy=A2.extend({entityType:H.literal("product"),metadata:m_Q}),c9A=wy.extend({frontmatter:kD,body:u9A,labels:H.record(H.string(),H.string()),ogImageUrl:H.string().optional()}),l9A=c9A.extend({url:H.string().optional(),typeLabel:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),ogImageUrl:H.string().optional()});aA();WA();t$();class $y extends lB{constructor(){super(u9A,{title:"Product",mappings:[{key:"tagline",label:"Tagline",type:"string"},{key:"promise",label:"Promise",type:"string"},{key:"role",label:"Role",type:"string"},{key:"purpose",label:"Purpose",type:"string"},{key:"audience",label:"Audience",type:"string"},{key:"values",label:"Values",type:"array",itemType:"string"},{key:"features",label:"Capabilities",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"story",label:"Story",type:"string"}]})}}class luA extends q2{constructor(){super({entityType:"product",schema:wy,frontmatterSchema:kD,bodyFormatter:new $y})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,kD);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,kD),B=X1(Q.name);return{content:A,entityType:"product",metadata:{name:Q.name,slug:B,availability:Q.availability,order:Q.order}}}}var p9A=new luA;WA();aA();var tV1=H.object({title:H.string(),description:H.string()}),eV1=H.object({title:H.string(),description:H.string()}),u_Q=H.object({title:H.string(),description:H.string()}),AE1=H.object({heading:H.string(),buttonText:H.string(),link:H.string()}),BZ=H.object({headline:H.string(),tagline:H.string()}),c_Q=H.object({title:H.string(),description:H.string()}),i9A=H.object({vision:H.string(),pillars:H.array(tV1).min(1).max(6),approach:H.array(c_Q).min(1).max(6),productsIntro:H.string(),technologies:H.array(u_Q).min(1).max(6),benefits:H.array(eV1).min(1).max(6),cta:AE1}),QE1=BZ.pick({headline:!0}).extend({slug:H.string()}),fy=A2.extend({entityType:H.literal("products-overview"),metadata:QE1}),jr=fy.extend({frontmatter:BZ,body:i9A,labels:H.record(H.string(),H.string())});aA();WA();t$();class Iy extends lB{constructor(){super(i9A,{title:"Products Overview",mappings:[{key:"vision",label:"Vision",type:"string"},{key:"pillars",label:"Core Principles",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"approach",label:"How It Works",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"productsIntro",label:"Products",type:"string"},{key:"technologies",label:"Built With",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"benefits",label:"Why Brains",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"cta",label:"Ready to Build",type:"object",children:[{key:"heading",label:"Heading",type:"string"},{key:"buttonText",label:"Button Text",type:"string"},{key:"link",label:"Link",type:"string"}]}]})}}class puA extends q2{constructor(){super({entityType:"products-overview",schema:fy,frontmatterSchema:BZ,bodyFormatter:new Iy})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,BZ);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,BZ),B=X1(Q.headline);return{content:A,entityType:"products-overview",metadata:{headline:Q.headline,slug:B}}}}var iuA=new puA;aA();WA();var l_Q=H.object({entityType:H.string(),query:H.object({id:H.string().optional()}).optional()});function BE1(A,Q){let B=b2(A.content,kD),w=Q.parse(B.content),$=Q.getLabels();return c9A.parse({...A,frontmatter:B.metadata,body:w,labels:$})}function wE1(A,Q){let B=b2(A.content,BZ),w=Q.parse(B.content),$=Q.getLabels();return jr.parse({...A,frontmatter:B.metadata,body:w,labels:$})}class r9A{logger;id="products:entities";name="Products Entity DataSource";description="Fetches products and overview for the products page";overviewFormatter=new Iy;productFormatter=new $y;constructor(A){this.logger=A;this.logger.debug("ProductsDataSource initialized")}async fetch(A,Q,B){let w=l_Q.parse(A),$=B.entityService;if(w.entityType==="products-overview"){let Y=(await $.listEntities({entityType:"products-overview",options:{limit:1}}))[0];if(!Y)throw Error("Products overview entity not found");let J=wE1(Y,this.overviewFormatter);return Q.parse(J)}if(w.query?.id){let Y=(await $.listEntities({entityType:"product",options:{filter:{metadata:{slug:w.query.id}},limit:1}}))[0];if(!Y)throw Error(`Product not found: ${w.query.id}`);return Q.parse({product:BE1(Y,this.productFormatter)})}let[f,I]=await Promise.all([$.listEntities({entityType:"products-overview",options:{limit:1}}),$.listEntities({entityType:"product",options:{sortFields:[{field:"order",direction:"asc"}]}})]),D=f[0];if(!D)throw Error("Products overview entity not found");return Q.parse({overview:wE1(D,this.overviewFormatter),products:I.map((U)=>BE1(U,this.productFormatter))})}}import{jsxDEV as A1,Fragment as r_Q}from"preact/jsx-dev-runtime";var $E1=({overview:A,products:Q})=>{let{frontmatter:B,body:w,labels:$}=A;return A1(r_Q,{children:[A1(ZQ,{title:B.headline,description:B.tagline},void 0,!1,void 0,this),A1("header",{className:"relative w-full min-h-[80vh] flex items-end px-6 md:px-12 bg-brand-dark overflow-hidden",children:[A1("style",{children:`
|
|
8831
8831
|
@keyframes wave-drift {
|
|
8832
8832
|
from { transform: translateX(0); }
|
|
8833
8833
|
to { transform: translateX(-50%); }
|
|
@@ -9022,7 +9022,7 @@ ${JSON.stringify(B,null,2)}`}function O9A(A){return A.map((Q)=>Q.detail===null?{
|
|
|
9022
9022
|
font: 10px/1.45 var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
|
|
9023
9023
|
}
|
|
9024
9024
|
`}},void 0,!1,void 0,this),jD("section",{className:"product-shell",children:[jD("header",{className:"product-hero",children:[Q.brandLabel&&jD("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this),jD("h1",{className:"printable-title",children:Q.name},void 0,!1,void 0,this),Q.availability&&jD("div",{className:"printable-meta",children:jD("span",{children:Q.availability},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),jD("div",{className:"product-body-wrap",children:[jD("aside",{className:"product-rail","aria-hidden":"true",children:jD("p",{className:"product-rail-label",children:"Product brief / capabilities"},void 0,!1,void 0,this)},void 0,!1,void 0,this),jD(M$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.brandLabel&&jD("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 AvQ=26214400,QvQ=60000;class duA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??WX}async resolve(A){if(A.sourceEntityType!=="product"||A.attachmentType!==d9A)return;let Q=await this.context.entityService.getEntity({entityType:"product",id:A.sourceEntityId});if(!Q)return;let B=BvQ(Q,{brandLabel:this.resolveBrandLabel()}),w=await s_Q(e_Q(t_Q(),"brain-product-printable-"));try{let $=await VD({outputDir:w,mediaPath:`/_media/printable/product/${Q.id}`,template:DE1,format:"pdf",content:B,siteConfig:{title:B.name,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ED({rootDir:w});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:AvQ,timeoutMs:QvQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${wvQ(Q)}-printable.pdf`}}finally{await f.close()}}finally{await a_Q(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}}function BvQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=kD.parse(B);return{name:$.name,body:w,availability:$.availability,...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function wvQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.name)}WA();WA();import{jsxDEV as IvQ}from"preact/jsx-dev-runtime";var n9A="og-image",$vQ="products:og-image",UE1=H.object({name:H.string().min(1),tagline:H.string().optional(),availability:H.string().optional(),brandLabel:H.string().optional()}),YE1={name:$vQ,pluginId:"products",schema:UE1,renderers:{image:fvQ}};function fvQ(A){let Q=UE1.parse(A);return IvQ(CF,{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 nuA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="product"||A.attachmentType!==n9A)return;let Q=await this.context.entityService.getEntity({entityType:"product",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B,content:w}=jB(Q.content),$=kD.parse(B),f=DvQ(w,"Tagline"),I=this.resolveBrandLabel(),D={name:$.name,availability:$.availability,...f?{tagline:f}:{},...I?{brandLabel:I}:{}};return{type:"image",data:await YC({mediaPath:`/_media/og/product/${Q.id}`,template:YE1,content:D,title:D.name,themeMode:"light",themeCSS:this.context.themeCSS,tmpPrefix:"brain-product-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${UvQ(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 DvQ(A,Q){let B=A.split(/\r?\n/),w=B.findIndex((I)=>I.trim().toLowerCase()===`## ${Q.toLowerCase()}`);if(w===-1)return;let $=[];for(let I of B.slice(w+1)){if(I.trim().startsWith("## "))break;$.push(I)}let f=$.join(`
|
|
9025
|
-
`).trim();return f.length>0?f:void 0}function UvQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.name)}var JE1={name:"@brains/products",private:!0,version:"0.2.0-alpha.
|
|
9025
|
+
`).trim();return f.length>0?f:void 0}function UvQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.name)}var JE1={name:"@brains/products",private:!0,version:"0.2.0-alpha.127",description:"Product entity management and overview page for marketing showcase",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var JvQ=H.object({overview:jr,products:H.array(l9A)}),XvQ=H.object({product:l9A});class ouA extends _Q{entityType=p9A.entityType;schema=wy;adapter=p9A;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("products",JE1,A,ruA)}getTemplates(){return{"product-list":P1({name:"product-list",description:"Products page \u2014 overview + brain model cards",schema:JvQ,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:$E1}}),"product-detail":P1({name:"product-detail",description:"Individual product detail page",schema:XvQ,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:fE1}})}}getDataSources(){return[new r9A(this.logger.child("ProductsDataSource"))]}async onRegister(A){this.unregisterPrintableAttachmentProvider=A.attachments.register("product",d9A,new duA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("product",n9A,new nuA(A)),A.entities.register("products-overview",fy,iuA)}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0}}function suA(A={}){return new ouA(A)}import{join as hvQ}from"path";import{jsxDEV as o9A,Fragment as WvQ}from"preact/jsx-dev-runtime";var Dy=({children:A})=>o9A(WvQ,{children:[o9A("div",{id:"bgCanvasWrap",className:"rizom-frame-canvas-wrap fixed top-0 left-0 w-full h-full pointer-events-none",children:o9A("canvas",{id:"heroCanvas",className:"w-full h-full block"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o9A("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 hX8}from"preact/jsx-dev-runtime";import{jsxDEV as GvQ}from"preact/jsx-dev-runtime";var s9A="px-6 md:px-10 xl:px-20",HvQ=`${s9A} relative z-[1]`,Uq=({id:A,className:Q,children:B})=>GvQ("section",{id:A,className:B2(HvQ,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as dX8}from"preact/jsx-dev-runtime";import{jsxDEV as sX8}from"preact/jsx-dev-runtime";import{jsxDEV as zvQ}from"preact/jsx-dev-runtime";var KvQ="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)]",FvQ={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)]"},ZvQ={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)]"},NvQ="w-full md:w-auto",jC=({href:A,variant:Q="primary",size:B="md",block:w=!1,className:$,children:f})=>zvQ("a",{href:A,className:B2("rizom-btn",`rizom-btn-${Q}`,`rizom-btn-${B}`,w&&"rizom-btn-block",KvQ,FvQ[Q],ZvQ[B],w&&NvQ,$),children:f},void 0,!1,void 0,this);import{jsxDEV as wW8}from"preact/jsx-dev-runtime";import{jsxDEV as DW8}from"preact/jsx-dev-runtime";import{Fragment as JW8}from"preact";import{jsxDEV as WW8}from"preact/jsx-dev-runtime";import{jsxDEV as XE1}from"preact/jsx-dev-runtime";var a9A=({sections:A})=>XE1(Dy,{children:XE1("main",{children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this);aA();WA();var WE1=`/*
|
|
9026
9026
|
* Shared globals + helpers used by tree / constellation / roots canvas
|
|
9027
9027
|
* scripts. Loaded as a shared static asset by the Rizom runtime package
|
|
9028
9028
|
* so the variant canvases
|
|
@@ -11512,7 +11512,7 @@ facts, owners, or tasks. Return only the required structured JSON.`});WA();var a
|
|
|
11512
11512
|
`);return this.truncateContent(w||Q||Fy(A))}truncateContent(A){if(A.length<=oE1)return A;let Q=A.slice(0,oE1-1),B=Q.search(/\s\S*$/);return`${(B>0?Q.slice(0,B):Q).trimEnd()}\u2026`}isSummaryEntity(A){return A.entityType===t6}isDecisionEntity(A){return A.entityType===_D}getEntitySpaceId(A){let Q=A.metadata;if("spaceId"in Q&&typeof Q.spaceId==="string")return Q.spaceId;return zX(Q)}}var VyQ=5,EyQ=3;function IcA(A){A.messaging.subscribe(Ux,async(Q)=>{let B=NDA.parse(Q.payload);return{success:!0,data:await J7A(A,B)}})}async function J7A(A,Q){let B=s$(Q.userPermissionLevel);if(!Q.channelId)return sE1(A,Q,{visibilityScope:B,reason:"no-channel-context",items:[]}),{items:[]};let w=new Zy(A),$=await w.retrieve({query:Q.message,conversationId:Q.conversationId,interfaceType:Q.interfaceType,channelId:Q.channelId,limit:VyQ,visibilityScope:B}),f=$.results.length===0?await w.retrieve({conversationId:Q.conversationId,interfaceType:Q.interfaceType,channelId:Q.channelId,limit:EyQ,visibilityScope:B}):void 0,I=$.results.length>0,D=I?$.results:f?.results??[];return sE1(A,Q,{visibilityScope:B,spaceId:$.spaceId??f?.spaceId,reason:D.length>0?"memory-injected":"no-same-space-memory",items:D.map((U)=>MyQ(U,I))}),{items:D.map(CyQ)}}function sE1(A,Q,B){A.logger.info("Conversation memory agent context audit",{conversationId:Q.conversationId,interfaceType:Q.interfaceType,channelId:Q.channelId,channelName:Q.channelName,userPermissionLevel:Q.userPermissionLevel,visibilityScope:B.visibilityScope,spaceId:B.spaceId,reason:B.reason,itemCount:B.items.length,items:B.items})}function MyQ(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 CyQ(A){let Q=A.channelName??A.channelId;return{id:A.id,source:"conversation-memory",title:`${A.entityType} from ${Q}`,content:A.content,provenance:{entityType:A.entityType,entityId:A.id,conversationId:A.conversationId,spaceId:A.spaceId,interfaceType:A.interfaceType,channelId:A.channelId,channelName:A.channelName,updated:A.updated,score:A.score,messageCount:A.messageCount,entryCount:A.entryCount,status:A.status}}}aA();o8();WA();JU();var UcA=H.object({role:pG,content:H.string(),timestamp:H.string().datetime().optional(),actor:gL.optional(),source:hL.optional()}),OyQ=H.object({conversationId:H.string().default("eval-conversation"),messages:H.array(UcA)}),RyQ=H.object({conversationId:H.string()}),byQ=H.object({conversationId:H.string().default("eval-conversation"),interfaceType:H.string().default("eval"),channelId:H.string().default("eval-channel"),channelName:H.string().optional(),projectionDecision:H.enum(["update","append"]).default("update"),existingSummary:H.string().optional(),existingMessageCount:H.number().int().min(0).default(0),messages:H.array(UcA)}),X7A=H.object({actorId:H.string(),canonicalId:H.string().optional(),displayName:H.string().optional()}),PyQ=X7A.extend({roles:H.array(H.enum(["user","assistant","system"])).default(["user"]),sourceActorIds:H.array(H.string()).optional()}),kyQ=H.object({actorId:H.string().optional(),canonicalId:H.string().optional(),displayName:H.string()}),eE1=H.object({id:H.string(),entityType:H.enum(["summary","decision","action-item"]),content:H.string(),excerpt:H.string().optional(),score:H.number().optional(),conversationId:H.string(),interfaceType:H.string(),channelId:H.string(),channelName:H.string().optional(),updated:H.string().datetime().optional(),visibility:P9,status:H.string().optional(),participants:H.array(PyQ).optional(),decidedBy:H.array(X7A).optional(),mentionedBy:H.array(X7A).optional(),assignedTo:H.array(kyQ).optional(),requestedBy:H.array(X7A).optional()}),jyQ=H.object({query:H.string().optional(),conversationId:H.string().optional(),interfaceType:H.string().optional(),channelId:H.string().optional(),limit:H.number().int().min(1).optional(),includeOtherSpaces:H.boolean().optional(),actorId:H.string().optional(),canonicalId:H.string().optional(),visibilityScope:P9.optional(),memory:H.array(eE1).optional()}),_yQ=H.object({conversationId:H.string().default("eval-conversation"),message:H.string(),interfaceType:H.string().default("eval"),channelId:H.string().optional(),channelName:H.string().optional(),userPermissionLevel:H.enum(["anchor","trusted","public"]).default("trusted"),memory:H.array(eE1).optional()}),vyQ=H.object({conversationId:H.string().default("eval-conversation"),existingSummary:H.string().optional(),existingMessageCount:H.number().int().min(0).default(0),messages:H.array(UcA)});function AM1(A){let{context:Q,logger:B,config:w}=A;Q.eval.registerHandler("summarizeMessages",async($)=>{let f=OyQ.parse($),I=DcA(f.messages,f.conversationId),U=await new Hy(Q,B,w).extract(I);return U.entries.map((Y)=>{let J=U.decisions.filter((G)=>G.timeRange.start>=Y.timeRange.start).filter((G)=>G.timeRange.end<=Y.timeRange.end).map((G)=>G.text),X=U.actionItems.filter((G)=>G.timeRange.start>=Y.timeRange.start).filter((G)=>G.timeRange.end<=Y.timeRange.end).map((G)=>G.text);return{...Y,decisions:J,actionItems:X,keyPointsText:Y.keyPoints.join(`
|
|
11513
11513
|
`),decisionsText:J.join(`
|
|
11514
11514
|
`),actionItemsText:X.join(`
|
|
11515
|
-
`)}})}),Q.eval.registerHandler("decideProjection",async($)=>{let f=vyQ.parse($),I=DcA(f.messages,f.conversationId),D=f.existingSummary?aE1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion,visibility:w.memoryVisibility}):null;return new Jq(Q,B,w).decideProjection(I,D)}),Q.eval.registerHandler("retrieveMemory",async($)=>{let f=jyQ.parse($),I=f.memory?tE1(Q,f.memory):Q;return new Zy(I).retrieve(f)}),Q.eval.registerHandler("buildAgentContext",async($)=>{let f=_yQ.parse($),I=f.memory?tE1(Q,f.memory):Q;return J7A(I,f)}),Q.eval.registerHandler("projectMessages",async($)=>{let f=byQ.parse($),I=DcA(f.messages,f.conversationId),D=yyQ({conversationId:f.conversationId,interfaceType:f.interfaceType,channelId:f.channelId,channelName:f.channelName,messages:I}),U=f.existingSummary?aE1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion,visibility:w.memoryVisibility}):null,Y=[],J=[],X=TyQ({context:Q,conversation:D,messages:I,existing:U,upserted:Y,deleted:J,projectionDecision:f.projectionDecision});return{result:await new Jq(X,B,w).projectConversation(f.conversationId),summaries:Y.filter((N)=>N.entityType==="summary"),decisions:Y.filter((N)=>N.entityType==="decision"),actionItems:Y.filter((N)=>N.entityType==="action-item"),deleted:J}}),Q.eval.registerHandler("projectConversation",async($)=>{let f=RyQ.parse($);return new Jq(Q,B,w).projectConversation(f.conversationId)})}function aE1(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 DcA(A,Q){return A.map((B,w)=>{let $=B.timestamp??new Date(Date.UTC(2026,0,1,0,w)).toISOString();return{id:`eval-message-${w+1}`,conversationId:Q,role:B.role,content:B.content,timestamp:$,metadata:{...B.actor?{actor:B.actor}:{},...B.source?{source:B.source}:{}}}})}function yyQ(A){let Q=A.messages[0],B=A.messages[A.messages.length-1],w=Q?.timestamp??"2026-01-01T00:00:00.000Z",$=B?.timestamp??w;return{id:A.conversationId,sessionId:A.conversationId,interfaceType:A.interfaceType,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},startedAt:w,lastActiveAt:$,createdAt:w,updatedAt:$,metadata:{}}}function TyQ(A){let Q=zX(A.conversation);return{...A.context,spaces:[Q],conversations:{...A.context.conversations,get:async()=>A.conversation,getMessages:async()=>A.messages},ai:{...A.context.ai,generateObject:async()=>({object:{decision:A.projectionDecision,rationale:"Forced by eval input"}})},entityService:{...A.context.entityService,getEntity:async({entityType:B})=>B==="summary"?A.existing:null,listEntities:async()=>[],deleteEntity:async(B)=>{return A.deleted.push(B),!0},upsertEntity:async({entity:B})=>{return A.upserted.push(B),{entityId:B.id,jobId:"eval-upsert",created:!0,skipped:!1}}}}}function tE1(A,Q){let B=Q.map(xyQ),w=B.map(($,f)=>({entity:$,score:Q[f]?.score??1,excerpt:Q[f]?.excerpt??Fy($)}));return{...A,entityService:{...A.entityService,search:async()=>w,listEntities:async({entityType:$})=>B.filter((f)=>f.entityType===$)}}}function xyQ(A){if(A.entityType==="summary")return SyQ(A);if(A.entityType==="decision")return gyQ(A);return hyQ(A)}function YcA(A){let Q=A.updated??"2026-01-01T00:00:00.000Z";return{id:A.id,content:A.content,contentHash:gB(A.content),visibility:A.visibility,created:Q,updated:Q}}function SyQ(A){return{...YcA(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 gyQ(A){return{...YcA(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:zX(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 hyQ(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{...YcA(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:zX(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 QM1={name:"@brains/conversation-memory",private:!0,version:"0.2.0-alpha.125",description:"Plugin for deriving durable conversation memory",type:"module",main:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint src test --ext .ts,.tsx",eval:"cd evals && bun run brain-eval","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/conversation-service":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/node":"^20.0.0",eslint:"^8.56.0",typescript:"^5.3.3"}};var uyQ=new IY,cyQ=new Jy,lyQ=new Xy,pyQ=H.object({conversationId:H.string()});class JcA extends _Q{entityType=t6;schema=vr;adapter=uyQ;constructor(A={}){super(e9A,QM1,A,AcA)}getConfig(){return this.config}getTemplates(){return{"summary-list":RE1,"summary-detail":bE1,"ai-response":PE1}}getDataSources(){return[new fcA(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:t6,job:{type:qE1,handler:new f7A(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await yL(A,t6,{outputVisibility:this.config.memoryVisibility}),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:euA,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:e9A}}},sourceChange:{sourceKind:mx,sourceTypes:[mx],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[uR],jobData:(Q)=>{let{conversationId:B}=this.parseConversationMessagePayload(Q);return{mode:"conversation",conversationId:B,reason:"message-added"}},jobOptions:(Q)=>{let{conversationId:B}=this.parseConversationMessagePayload(Q);return{priority:5,delayMs:this.config.projectionDelayMs,source:euA,deduplication:"skip",deduplicationKey:`conversation-memory:${B}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${B}`,pluginId:e9A}}}}}]}parseConversationMessagePayload(A){return pyQ.parse(A)}async shouldEnqueueConversationProjection(A,Q){let{conversationId:B}=this.parseConversationMessagePayload(Q),w=await A.conversations.get(B);if(!w)return!1;return yC({conversation:w,spaces:A.spaces}).eligible}async onRegister(A){A.entities.register(_D,yr,cyQ),A.entities.register(fY,Tr,lyQ),_E1({context:A,pluginId:this.id}),yE1({context:A,pluginId:this.id}),pE1({context:A,pluginId:this.id}),dE1({context:A,pluginId:this.id,config:this.config}),IcA(A),AM1({context:A,logger:this.logger,config:this.config})}}function XcA(A){return new JcA(A)}aA();WA();aA();var wZ=H.object({title:H.string(),section:H.string(),order:H.number().int(),sourcePath:H.string(),description:H.string().optional(),slug:H.string().optional()}),BM1=wZ.pick({title:!0,section:!0,order:!0,description:!0}).extend({slug:H.string()}),Ny=A2.extend({entityType:H.literal("doc"),metadata:BM1}),$Z=Ny.extend({frontmatter:wZ,body:H.string()});aA();WA();class WcA extends q2{constructor(){super({entityType:"doc",schema:Ny,frontmatterSchema:wZ})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,wZ);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,wZ),B=Q.slug??X1(Q.title);return{content:A,entityType:"doc",metadata:{title:Q.title,section:Q.section,order:Q.order,slug:B,...Q.description?{description:Q.description}:{}}}}}var W7A=new WcA;aA();function wM1(A){return[...A].sort((Q,B)=>{let w=Q.metadata.order-B.metadata.order;if(w!==0)return w;return Q.metadata.title.localeCompare(B.metadata.title)})}function $M1(A){let Q=b2(A.content,wZ);return $Z.parse({...A,frontmatter:Q.metadata,body:Q.content})}class H7A extends u5{id="docs:entities";name="Docs Entity DataSource";description="Fetches and transforms doc entities for rendering";config={entityType:"doc",defaultSort:[{field:"order",direction:"asc"},{field:"section",direction:"asc"},{field:"title",direction:"asc"}],defaultLimit:100,enableNavigation:!0};constructor(A){super(A)}transformEntity(A){return $M1(A)}async fetch(A,Q,B){let w=this.parseQuery(A);if(!w.query.id){let J=await this.fetchList({...w.query,limit:1000,page:void 0,pageSize:void 0},B.entityService);return Q.parse(this.buildListResult(J.items,null,w.query))}let[$,f]=await Promise.all([this.fetchDetail(w.query.id,B.entityService),this.fetchList({limit:1000},B.entityService)]),I=wM1(f.items),D=I.findIndex((J)=>J.id===$.item.id),U=D>0?I[D-1]:null,Y=D>=0&&D<I.length-1?I[D+1]:null;return Q.parse({doc:$.item,docs:I,prevDoc:U,nextDoc:Y})}buildDetailResult(A,Q){return{doc:A,docs:[A],prevDoc:Q?.prev??null,nextDoc:Q?.next??null}}buildListResult(A,Q,B){return{docs:wM1(A),pagination:Q,baseUrl:B.baseUrl}}}aA();Xw();WA();import{jsxDEV as $$}from"preact/jsx-dev-runtime";var iyQ=["I","II","III","IV","V","VI","VII","VIII","IX","X"];function gr(A){return[...A].sort((Q,B)=>{let w=Q.metadata.order-B.metadata.order;if(w!==0)return w;return Q.metadata.title.localeCompare(B.metadata.title)})}function G7A(A){let Q=new Map;for(let B of gr(A)){let w=B.metadata.section;Q.set(w,[...Q.get(w)??[],B])}return[...Q.entries()].map(([B,w])=>({section:B,docs:w}))}function zy(A){return`/docs/${A.metadata.slug}`}function K7A(A){return`section-${A+1}`}function qy(A){return iyQ[A]??String(A+1)}var DM1="text-[var(--docs-text)] font-bold",UM1="text-[var(--docs-accent)] font-bold",YM1="text-[var(--docs-text-muted)]",ryQ="docs-font-label text-xs uppercase tracking-[0.18em] text-[var(--docs-accent)]",dyQ="docs-font-display text-[var(--docs-heading)]",fM1="inline-flex items-center justify-center rounded-lg border px-[18px] py-2.5 text-sm font-semibold transition-colors duration-150",IM1="relative hidden py-1 text-[15px] text-[var(--docs-text-muted)] transition-colors duration-150 after:absolute after:bottom-0 after:left-0 after:h-px after:w-0 after:bg-[var(--docs-accent)] after:transition-[width] after:duration-300 hover:text-[var(--docs-text)] hover:after:w-full min-[861px]:inline-block",HcA="docs-font-label text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:text-[var(--docs-text)]",iH={wrap:"mx-auto max-w-6xl px-6 pt-20 md:px-12 md:pt-24",label:ryQ,display:dyQ,button:`${fM1} border-[var(--docs-text)] text-[var(--docs-text)] hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)]`,primaryButton:`${fM1} border-[var(--docs-accent)] bg-[var(--docs-accent)] text-white hover:bg-transparent hover:text-[var(--docs-accent)]`},JM1=()=>$$("nav",{className:"docs-header fixed inset-x-0 top-0 z-[100] flex items-center justify-between px-6 py-4 md:px-10 md:py-5 xl:px-20",children:[$$("a",{href:"/docs",className:"docs-font-body text-xl font-bold","aria-label":"Brains docs",children:[$$("span",{className:DM1,children:"brains"},void 0,!1,void 0,this),$$("span",{className:UM1,children:"."},void 0,!1,void 0,this),$$("span",{className:YM1,children:"docs"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$$("div",{className:"docs-header__nav flex items-center gap-4 md:gap-8",children:[$$("a",{className:IM1,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),$$("a",{className:IM1,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),$$("a",{href:"https://rizom.ai",className:"inline-flex items-center justify-center rounded-lg border border-[var(--docs-text)] px-4 py-2 text-[13px] font-semibold text-[var(--docs-text)] transition-colors duration-150 hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)] md:px-6 md:py-2.5 md:text-[15px]",children:"Get Brains"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),XM1=()=>$$("footer",{className:"flex flex-col items-center justify-between gap-4 border-t border-[var(--docs-border-light)] py-8 text-center md:flex-row md:gap-6 md:py-6 md:text-left",children:[$$("a",{href:"https://rizom.ai",className:"docs-font-body text-[15px] font-bold",children:[$$("span",{className:DM1,children:"rizom"},void 0,!1,void 0,this),$$("span",{className:UM1,children:"."},void 0,!1,void 0,this),$$("span",{className:YM1,children:"ai"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$$("div",{className:"flex flex-wrap items-center justify-center gap-6 md:justify-end",children:[$$("a",{className:HcA,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),$$("a",{className:HcA,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),$$("a",{className:HcA,href:"https://rizom.ai",children:"Rizom"},void 0,!1,void 0,this),$$("button",{id:"themeToggle",className:"docs-font-label cursor-pointer rounded-md border border-[var(--docs-text-light)] bg-transparent px-2.5 py-1.5 text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:border-[var(--docs-text)] hover:text-[var(--docs-text)]",type:"button",children:"\u2600 Light"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),nyQ=`
|
|
11515
|
+
`)}})}),Q.eval.registerHandler("decideProjection",async($)=>{let f=vyQ.parse($),I=DcA(f.messages,f.conversationId),D=f.existingSummary?aE1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion,visibility:w.memoryVisibility}):null;return new Jq(Q,B,w).decideProjection(I,D)}),Q.eval.registerHandler("retrieveMemory",async($)=>{let f=jyQ.parse($),I=f.memory?tE1(Q,f.memory):Q;return new Zy(I).retrieve(f)}),Q.eval.registerHandler("buildAgentContext",async($)=>{let f=_yQ.parse($),I=f.memory?tE1(Q,f.memory):Q;return J7A(I,f)}),Q.eval.registerHandler("projectMessages",async($)=>{let f=byQ.parse($),I=DcA(f.messages,f.conversationId),D=yyQ({conversationId:f.conversationId,interfaceType:f.interfaceType,channelId:f.channelId,channelName:f.channelName,messages:I}),U=f.existingSummary?aE1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion,visibility:w.memoryVisibility}):null,Y=[],J=[],X=TyQ({context:Q,conversation:D,messages:I,existing:U,upserted:Y,deleted:J,projectionDecision:f.projectionDecision});return{result:await new Jq(X,B,w).projectConversation(f.conversationId),summaries:Y.filter((N)=>N.entityType==="summary"),decisions:Y.filter((N)=>N.entityType==="decision"),actionItems:Y.filter((N)=>N.entityType==="action-item"),deleted:J}}),Q.eval.registerHandler("projectConversation",async($)=>{let f=RyQ.parse($);return new Jq(Q,B,w).projectConversation(f.conversationId)})}function aE1(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 DcA(A,Q){return A.map((B,w)=>{let $=B.timestamp??new Date(Date.UTC(2026,0,1,0,w)).toISOString();return{id:`eval-message-${w+1}`,conversationId:Q,role:B.role,content:B.content,timestamp:$,metadata:{...B.actor?{actor:B.actor}:{},...B.source?{source:B.source}:{}}}})}function yyQ(A){let Q=A.messages[0],B=A.messages[A.messages.length-1],w=Q?.timestamp??"2026-01-01T00:00:00.000Z",$=B?.timestamp??w;return{id:A.conversationId,sessionId:A.conversationId,interfaceType:A.interfaceType,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},startedAt:w,lastActiveAt:$,createdAt:w,updatedAt:$,metadata:{}}}function TyQ(A){let Q=zX(A.conversation);return{...A.context,spaces:[Q],conversations:{...A.context.conversations,get:async()=>A.conversation,getMessages:async()=>A.messages},ai:{...A.context.ai,generateObject:async()=>({object:{decision:A.projectionDecision,rationale:"Forced by eval input"}})},entityService:{...A.context.entityService,getEntity:async({entityType:B})=>B==="summary"?A.existing:null,listEntities:async()=>[],deleteEntity:async(B)=>{return A.deleted.push(B),!0},upsertEntity:async({entity:B})=>{return A.upserted.push(B),{entityId:B.id,jobId:"eval-upsert",created:!0,skipped:!1}}}}}function tE1(A,Q){let B=Q.map(xyQ),w=B.map(($,f)=>({entity:$,score:Q[f]?.score??1,excerpt:Q[f]?.excerpt??Fy($)}));return{...A,entityService:{...A.entityService,search:async()=>w,listEntities:async({entityType:$})=>B.filter((f)=>f.entityType===$)}}}function xyQ(A){if(A.entityType==="summary")return SyQ(A);if(A.entityType==="decision")return gyQ(A);return hyQ(A)}function YcA(A){let Q=A.updated??"2026-01-01T00:00:00.000Z";return{id:A.id,content:A.content,contentHash:gB(A.content),visibility:A.visibility,created:Q,updated:Q}}function SyQ(A){return{...YcA(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 gyQ(A){return{...YcA(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:zX(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 hyQ(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{...YcA(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:zX(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 QM1={name:"@brains/conversation-memory",private:!0,version:"0.2.0-alpha.127",description:"Plugin for deriving durable conversation memory",type:"module",main:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint src test --ext .ts,.tsx",eval:"cd evals && bun run brain-eval","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/conversation-service":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/node":"^20.0.0",eslint:"^8.56.0",typescript:"^5.3.3"}};var uyQ=new IY,cyQ=new Jy,lyQ=new Xy,pyQ=H.object({conversationId:H.string()});class JcA extends _Q{entityType=t6;schema=vr;adapter=uyQ;constructor(A={}){super(e9A,QM1,A,AcA)}getConfig(){return this.config}getTemplates(){return{"summary-list":RE1,"summary-detail":bE1,"ai-response":PE1}}getDataSources(){return[new fcA(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:t6,job:{type:qE1,handler:new f7A(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await yL(A,t6,{outputVisibility:this.config.memoryVisibility}),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:euA,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:e9A}}},sourceChange:{sourceKind:mx,sourceTypes:[mx],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[uR],jobData:(Q)=>{let{conversationId:B}=this.parseConversationMessagePayload(Q);return{mode:"conversation",conversationId:B,reason:"message-added"}},jobOptions:(Q)=>{let{conversationId:B}=this.parseConversationMessagePayload(Q);return{priority:5,delayMs:this.config.projectionDelayMs,source:euA,deduplication:"skip",deduplicationKey:`conversation-memory:${B}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${B}`,pluginId:e9A}}}}}]}parseConversationMessagePayload(A){return pyQ.parse(A)}async shouldEnqueueConversationProjection(A,Q){let{conversationId:B}=this.parseConversationMessagePayload(Q),w=await A.conversations.get(B);if(!w)return!1;return yC({conversation:w,spaces:A.spaces}).eligible}async onRegister(A){A.entities.register(_D,yr,cyQ),A.entities.register(fY,Tr,lyQ),_E1({context:A,pluginId:this.id}),yE1({context:A,pluginId:this.id}),pE1({context:A,pluginId:this.id}),dE1({context:A,pluginId:this.id,config:this.config}),IcA(A),AM1({context:A,logger:this.logger,config:this.config})}}function XcA(A){return new JcA(A)}aA();WA();aA();var wZ=H.object({title:H.string(),section:H.string(),order:H.number().int(),sourcePath:H.string(),description:H.string().optional(),slug:H.string().optional()}),BM1=wZ.pick({title:!0,section:!0,order:!0,description:!0}).extend({slug:H.string()}),Ny=A2.extend({entityType:H.literal("doc"),metadata:BM1}),$Z=Ny.extend({frontmatter:wZ,body:H.string()});aA();WA();class WcA extends q2{constructor(){super({entityType:"doc",schema:Ny,frontmatterSchema:wZ})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,wZ);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,wZ),B=Q.slug??X1(Q.title);return{content:A,entityType:"doc",metadata:{title:Q.title,section:Q.section,order:Q.order,slug:B,...Q.description?{description:Q.description}:{}}}}}var W7A=new WcA;aA();function wM1(A){return[...A].sort((Q,B)=>{let w=Q.metadata.order-B.metadata.order;if(w!==0)return w;return Q.metadata.title.localeCompare(B.metadata.title)})}function $M1(A){let Q=b2(A.content,wZ);return $Z.parse({...A,frontmatter:Q.metadata,body:Q.content})}class H7A extends u5{id="docs:entities";name="Docs Entity DataSource";description="Fetches and transforms doc entities for rendering";config={entityType:"doc",defaultSort:[{field:"order",direction:"asc"},{field:"section",direction:"asc"},{field:"title",direction:"asc"}],defaultLimit:100,enableNavigation:!0};constructor(A){super(A)}transformEntity(A){return $M1(A)}async fetch(A,Q,B){let w=this.parseQuery(A);if(!w.query.id){let J=await this.fetchList({...w.query,limit:1000,page:void 0,pageSize:void 0},B.entityService);return Q.parse(this.buildListResult(J.items,null,w.query))}let[$,f]=await Promise.all([this.fetchDetail(w.query.id,B.entityService),this.fetchList({limit:1000},B.entityService)]),I=wM1(f.items),D=I.findIndex((J)=>J.id===$.item.id),U=D>0?I[D-1]:null,Y=D>=0&&D<I.length-1?I[D+1]:null;return Q.parse({doc:$.item,docs:I,prevDoc:U,nextDoc:Y})}buildDetailResult(A,Q){return{doc:A,docs:[A],prevDoc:Q?.prev??null,nextDoc:Q?.next??null}}buildListResult(A,Q,B){return{docs:wM1(A),pagination:Q,baseUrl:B.baseUrl}}}aA();Xw();WA();import{jsxDEV as $$}from"preact/jsx-dev-runtime";var iyQ=["I","II","III","IV","V","VI","VII","VIII","IX","X"];function gr(A){return[...A].sort((Q,B)=>{let w=Q.metadata.order-B.metadata.order;if(w!==0)return w;return Q.metadata.title.localeCompare(B.metadata.title)})}function G7A(A){let Q=new Map;for(let B of gr(A)){let w=B.metadata.section;Q.set(w,[...Q.get(w)??[],B])}return[...Q.entries()].map(([B,w])=>({section:B,docs:w}))}function zy(A){return`/docs/${A.metadata.slug}`}function K7A(A){return`section-${A+1}`}function qy(A){return iyQ[A]??String(A+1)}var DM1="text-[var(--docs-text)] font-bold",UM1="text-[var(--docs-accent)] font-bold",YM1="text-[var(--docs-text-muted)]",ryQ="docs-font-label text-xs uppercase tracking-[0.18em] text-[var(--docs-accent)]",dyQ="docs-font-display text-[var(--docs-heading)]",fM1="inline-flex items-center justify-center rounded-lg border px-[18px] py-2.5 text-sm font-semibold transition-colors duration-150",IM1="relative hidden py-1 text-[15px] text-[var(--docs-text-muted)] transition-colors duration-150 after:absolute after:bottom-0 after:left-0 after:h-px after:w-0 after:bg-[var(--docs-accent)] after:transition-[width] after:duration-300 hover:text-[var(--docs-text)] hover:after:w-full min-[861px]:inline-block",HcA="docs-font-label text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:text-[var(--docs-text)]",iH={wrap:"mx-auto max-w-6xl px-6 pt-20 md:px-12 md:pt-24",label:ryQ,display:dyQ,button:`${fM1} border-[var(--docs-text)] text-[var(--docs-text)] hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)]`,primaryButton:`${fM1} border-[var(--docs-accent)] bg-[var(--docs-accent)] text-white hover:bg-transparent hover:text-[var(--docs-accent)]`},JM1=()=>$$("nav",{className:"docs-header fixed inset-x-0 top-0 z-[100] flex items-center justify-between px-6 py-4 md:px-10 md:py-5 xl:px-20",children:[$$("a",{href:"/docs",className:"docs-font-body text-xl font-bold","aria-label":"Brains docs",children:[$$("span",{className:DM1,children:"brains"},void 0,!1,void 0,this),$$("span",{className:UM1,children:"."},void 0,!1,void 0,this),$$("span",{className:YM1,children:"docs"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$$("div",{className:"docs-header__nav flex items-center gap-4 md:gap-8",children:[$$("a",{className:IM1,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),$$("a",{className:IM1,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),$$("a",{href:"https://rizom.ai",className:"inline-flex items-center justify-center rounded-lg border border-[var(--docs-text)] px-4 py-2 text-[13px] font-semibold text-[var(--docs-text)] transition-colors duration-150 hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)] md:px-6 md:py-2.5 md:text-[15px]",children:"Get Brains"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),XM1=()=>$$("footer",{className:"flex flex-col items-center justify-between gap-4 border-t border-[var(--docs-border-light)] py-8 text-center md:flex-row md:gap-6 md:py-6 md:text-left",children:[$$("a",{href:"https://rizom.ai",className:"docs-font-body text-[15px] font-bold",children:[$$("span",{className:DM1,children:"rizom"},void 0,!1,void 0,this),$$("span",{className:UM1,children:"."},void 0,!1,void 0,this),$$("span",{className:YM1,children:"ai"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$$("div",{className:"flex flex-wrap items-center justify-center gap-6 md:justify-end",children:[$$("a",{className:HcA,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),$$("a",{className:HcA,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),$$("a",{className:HcA,href:"https://rizom.ai",children:"Rizom"},void 0,!1,void 0,this),$$("button",{id:"themeToggle",className:"docs-font-label cursor-pointer rounded-md border border-[var(--docs-text-light)] bg-transparent px-2.5 py-1.5 text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:border-[var(--docs-text)] hover:text-[var(--docs-text)]",type:"button",children:"\u2600 Light"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),nyQ=`
|
|
11516
11516
|
.docs-handbook {
|
|
11517
11517
|
--docs-bg: var(--color-bg, #0d0a1a);
|
|
11518
11518
|
--docs-bg-card: var(--color-bg-card, #1a0a3e);
|
|
@@ -11664,7 +11664,7 @@ facts, owners, or tasks. Return only the required structured JSON.`});WA();var a
|
|
|
11664
11664
|
background: transparent;
|
|
11665
11665
|
}
|
|
11666
11666
|
|
|
11667
|
-
`,WM1=()=>$$("style",{children:nyQ},void 0,!1,void 0,this);import{jsxDEV as K2,Fragment as oyQ}from"preact/jsx-dev-runtime";var F7A=({title:A,description:Q,children:B,detail:w=!1,footer:$=!1,contentClassName:f=""})=>K2(oyQ,{children:[K2(ZQ,{title:A,description:Q},void 0,!1,void 0,this),K2(WM1,{},void 0,!1,void 0,this),K2("div",{className:`docs-handbook${w?" docs-handbook--detail":""}`,children:[K2(JM1,{},void 0,!1,void 0,this),K2("div",{className:`${iH.wrap} ${f}`.trim(),children:[B,$&&K2(XM1,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),HM1=({docsCount:A,sectionsCount:Q,startDoc:B})=>K2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[K2("p",{className:`${iH.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),K2("h1",{className:`${iH.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",K2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("p",{className:"mt-8 max-w-[52ch] text-lg leading-[1.65] text-[var(--docs-text-muted)]",children:"Documentation for composing brain models, managing markdown entities, wiring interfaces, and shipping generated sites."},void 0,!1,void 0,this),K2("dl",{className:"mt-10 flex flex-wrap gap-7 docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)] md:mt-14 md:gap-12",children:[K2("div",{children:[K2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:A},void 0,!1,void 0,this),"Documents"]},void 0,!0,void 0,this),K2("div",{children:[K2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:Q},void 0,!1,void 0,this),"Sections"]},void 0,!0,void 0,this),K2("div",{children:[K2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:"April 2026"},void 0,!1,void 0,this),"Updated"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[B&&K2("a",{className:iH.primaryButton,href:zy(B),children:"Start reading"},void 0,!1,void 0,this),K2("a",{className:iH.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),GM1=({groups:A})=>K2("aside",{className:"docs-rail sticky top-8 hidden docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)] min-[861px]:block","aria-label":"Documentation sections",children:[K2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),K2("ol",{className:"m-0 list-none p-0",children:A.map((Q,B)=>K2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[K2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[qy(B),"."]},void 0,!0,void 0,this),K2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${K7A(B)}`,children:Q.section},void 0,!1,void 0,this)]},Q.section,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),KM1=({group:A,index:Q})=>K2("article",{className:"mb-16 last:mb-0",id:K7A(Q),children:[K2("header",{className:"mb-2 grid grid-cols-[36px_auto_1fr] items-baseline gap-x-3 border-b border-[var(--docs-border)] pb-3.5 md:grid-cols-[48px_auto_1fr] md:gap-x-5",children:[K2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[qy(Q),"."]},void 0,!0,void 0,this),K2("h2",{className:`${iH.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),K2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("ol",{className:"m-0 list-none p-0",children:A.docs.map((B)=>K2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:K2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:zy(B),children:[K2("p",{className:"m-0 text-[22px] leading-[1.2] tracking-[-0.005em] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:B.metadata.title},void 0,!1,void 0,this),B.metadata.description&&K2("p",{className:"mt-1.5 mb-0 max-w-[70ch] text-sm leading-[1.55] text-[var(--docs-text-muted)]",children:B.metadata.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},B.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),FM1=({title:A})=>K2("nav",{className:"mb-8 flex flex-wrap items-baseline gap-2.5 docs-font-label text-[11px] uppercase tracking-[0.06em] text-[var(--docs-text-light)]","aria-label":"Breadcrumb",children:[K2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),K2("span",{children:"/"},void 0,!1,void 0,this),K2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),K2("span",{children:"/"},void 0,!1,void 0,this),K2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),ZM1=({groups:A,activeGroupIndex:Q,activeSlug:B})=>K2("aside",{className:"docs-detail-rail sticky top-24 hidden max-h-[calc(100vh-120px)] overflow-auto pr-2 min-[861px]:block","aria-label":"Documentation navigation",children:K2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[K2("p",{className:"m-0 mb-4 border-b border-[var(--docs-text)] pb-3 text-[11px] uppercase tracking-[0.08em] text-[var(--docs-text-light)]",children:"Documentation"},void 0,!1,void 0,this),K2("ol",{className:"m-0 list-none p-0",children:A.map((w,$)=>{let f=$===Q;return K2("li",{className:f?"mb-[22px]":"mb-3.5",children:[K2("a",{className:`mb-2 flex items-baseline gap-2.5 docs-font-label text-[11px] uppercase leading-[1.4] tracking-[0.06em] transition-colors duration-150 hover:text-[var(--docs-text)] ${f?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${K7A($)}`,children:[K2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[qy($),"."]},void 0,!0,void 0,this)," ",w.section]},void 0,!0,void 0,this),f&&K2("ol",{className:"mt-0.5 list-none p-0",children:w.docs.map((I)=>{let D=I.metadata.slug===B;return K2("li",{children:K2("a",{className:`docs-rail__doc relative block py-1.5 docs-font-body text-sm leading-[1.4] tracking-normal transition-[color,padding-left] duration-150 hover:text-[var(--docs-text)] ${D?"pl-3.5 font-medium text-[var(--docs-accent)]":"text-[var(--docs-text-muted)]"}`,href:zy(I),"aria-current":D?"page":void 0,children:I.metadata.title},void 0,!1,void 0,this)},I.id,!1,void 0,this)})},void 0,!1,void 0,this)]},w.section,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),NM1=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return K2("nav",{className:"mt-12 grid grid-cols-1 gap-5 border-t border-[var(--docs-border)] pt-7 md:grid-cols-2","aria-label":"Previous and next docs",children:[A?K2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:zy(A),children:[K2("span",{className:"block docs-font-label text-[10.5px] uppercase tracking-[0.22em] text-[var(--docs-text-light)]",children:"Previous"},void 0,!1,void 0,this),K2("span",{className:"mt-2 block docs-font-display text-[22px] leading-[1.2] text-[var(--docs-heading)] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:["\u2190 ",A.metadata.title]},void 0,!0,void 0,this)]},void 0,!0,void 0,this):K2("span",{},void 0,!1,void 0,this),Q&&K2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] text-left transition-colors duration-150 hover:border-[var(--docs-accent)] md:text-right",href:zy(Q),children:[K2("span",{className:"block docs-font-label text-[10.5px] uppercase tracking-[0.22em] text-[var(--docs-text-light)]",children:"Next"},void 0,!1,void 0,this),K2("span",{className:"mt-2 block docs-font-display text-[22px] leading-[1.2] text-[var(--docs-heading)] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:[Q.metadata.title," \u2192"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as Ly}from"preact/jsx-dev-runtime";var GcA=({docs:A})=>{let Q=gr(A),B=G7A(Q),$=Q.filter((f)=>f.metadata.slug!=="index")[0]??Q[0];return Ly(F7A,{title:"Documentation",description:"Brains documentation",children:[Ly(HM1,{docsCount:A.length,sectionsCount:B.length,startDoc:$},void 0,!1,void 0,this),Ly("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:[Ly(GM1,{groups:B},void 0,!1,void 0,this),Ly("div",{children:B.map((f,I)=>Ly(KM1,{group:f,index:I},f.section,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as vD}from"preact/jsx-dev-runtime";var KcA=({doc:A,docs:Q,prevDoc:B,nextDoc:w})=>{let $=G7A(Q.length>0?Q:[A]),f=gr(Q.length>0?Q:[A]),I=f.findIndex((U)=>U.metadata.slug===A.metadata.slug),D=Math.max($.findIndex((U)=>U.docs.some((Y)=>Y.metadata.slug===A.metadata.slug)),0);return vD(F7A,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[vD(FM1,{title:A.metadata.title},void 0,!1,void 0,this),vD("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[vD(ZM1,{groups:$,activeGroupIndex:D,activeSlug:A.metadata.slug},void 0,!1,void 0,this),vD("article",{className:"min-w-0",children:[vD("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[vD("p",{className:`${iH.label} m-0 mb-6 flex items-baseline gap-3`,children:[vD("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[qy(D),"."]},void 0,!0,void 0,this)," ",A.metadata.section,I>=0?` \xB7 ${I+1}/${f.length}`:""]},void 0,!0,void 0,this),vD("h1",{className:`${iH.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&&vD("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),vD("div",{className:"docs-article__body",children:vD(M$,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),vD(NM1,{prevDoc:B,nextDoc:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};var syQ=H.object({docs:H.array($Z),pagination:z7.nullable(),baseUrl:H.string().optional()}),ayQ=H.object({doc:$Z,docs:H.array($Z),prevDoc:$Z.nullable(),nextDoc:$Z.nullable()});function zM1(){return{"doc-list":P1({name:"doc-list",description:"Documentation index template",schema:syQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:GcA}}),"doc-detail":P1({name:"doc-detail",description:"Documentation page template",schema:ayQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:KcA}})}}var qM1={name:"@brains/doc",private:!0,version:"0.2.0-alpha.125",description:"Documentation entity type \u2014 markdown docs as first-class brain content",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","bun-types":"latest",typescript:"^5.3.3"}};class FcA extends _Q{entityType=W7A.entityType;schema=Ny;adapter=W7A;constructor(){super("docs",qM1,{},void 0)}getTemplates(){return zM1()}getDataSources(){return[new H7A(this.logger.child("DocDataSource"))]}}function ZcA(){return new FcA}aA();WA();WA();t$();var LM1=H.object({label:H.string(),href:H.string()}),VM1=H.object({label:H.string(),title:H.string(),detail:H.string()}),eyQ=H.object({eyebrow:H.string(),name:H.string(),sub:H.string()}),ATQ=H.object({tone:H.enum(["capture","synthesis","share"]),title:H.string(),text:H.string()}),NcA=H.object({captures:H.number(),links:H.number(),topics:H.number(),summaries:H.number(),peers:H.number()}),Vy=H.object({eyebrow:H.string(),headline:H.string(),intro:H.string(),primaryCta:LM1,secondaryCta:LM1,inputs:H.array(VM1).min(1),outputs:H.array(VM1).min(1),core:eyQ,legend:H.array(ATQ).min(1)}),zcA=Vy.extend({counts:NcA}),EM1={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."}]},MM1=new lB(Vy,{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 Z7A(A){return MM1.parse(A)}function CM1(A){return MM1.format(A)}WA();var QTQ=H.object({query:H.object({routeId:H.string().default("home"),sectionId:H.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}).passthrough(),BTQ={captures:"note",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class qcA{id="relay-site:home-counts";name="Relay homepage counts";description="Fetches Relay homepage content and live entity counts for the system diagram";async fetch(A,Q,B){let w=QTQ.parse(A??{}),$=await this.fetchContent(B,w.query.routeId,w.query.sectionId),f=await this.fetchCounts(B);return Q.parse({...$,counts:f})}async fetchContent(A,Q,B){let w=await A.entityService.getEntity({entityType:"site-content",id:`${Q}:${B}`});if(!w?.content)return EM1;return Vy.parse(Z7A(w.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries(BTQ).map(async([B,w])=>[B,await this.countOrZero(A,w)]));return NcA.parse(Object.fromEntries(Q))}async countOrZero(A,Q){if(!A.entityService.hasEntityType(Q))return 0;try{return await A.entityService.countEntities({entityType:Q})}catch{return 0}}}import{jsxDEV as Q1}from"preact/jsx-dev-runtime";var OM1=H.object({label:H.string(),href:H.string()}),wTQ=H.object({eyebrow:H.string(),headline:H.string(),intro:H.string(),primaryCta:OM1,secondaryCta:OM1,signals:H.array(H.object({label:H.string(),value:H.string(),note:H.string()}))}),$TQ=H.object({eyebrow:H.string(),title:H.string(),intro:H.string(),steps:H.array(H.object({phase:H.string(),title:H.string(),text:H.string()}))}),fTQ=H.object({title:H.string(),intro:H.string(),cards:H.array(H.object({label:H.string(),title:H.string(),text:H.string()}))}),ITQ=H.object({title:H.string(),intro:H.string(),points:H.array(H.string())}),DTQ={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."]},UTQ="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function RM1({href:A,label:Q}){return Q1("a",{href:A,className:UTQ,children:Q},void 0,!1,void 0,this)}function YTQ({siteInfo:A,children:Q}){let B=[...A.navigation.primary,...A.navigation.secondary],w=A.cta??{buttonText:"Start here",buttonLink:"/about"};return Q1(Dy,{children:[Q1("nav",{className:"fixed left-0 right-0 top-0 z-[100] flex items-center justify-between border-b border-theme-light bg-nav-fade px-6 py-4 backdrop-blur-[12px] md:px-10 xl:px-20",children:[Q1("a",{href:"/",className:"font-nav text-[20px]","aria-label":"Relay home",children:[Q1("span",{className:"font-bold text-theme",children:"relay"},void 0,!1,void 0,this),Q1("span",{className:"font-bold text-accent",children:"."},void 0,!1,void 0,this),Q1("span",{className:"text-theme-muted",children:"brain"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"flex items-center gap-5 md:gap-8",children:[Q1("div",{className:"hidden items-center gap-6 md:flex",children:B.map(($)=>Q1(RM1,{...$},`${$.href}-${$.label}`,!1,void 0,this))},void 0,!1,void 0,this),Q1("a",{href:w.buttonLink,className:"rounded-[999px] border border-theme px-4 py-2 font-body text-[13px] font-semibold text-theme transition-colors hover:border-accent hover:text-accent md:px-5",children:w.buttonText},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1("main",{children:Q},void 0,!1,void 0,this),Q1("footer",{className:"relative z-[1] border-t border-theme-light px-6 py-8 md:px-10 xl:px-20",children:Q1("div",{className:"flex flex-col gap-4 md:flex-row md:items-center md:justify-between",children:[Q1("div",{children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.22em] text-theme-light",children:A.copyright},void 0,!1,void 0,this),Q1("p",{className:"mt-2 max-w-[560px] font-body text-body-xs text-theme-muted",children:A.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"flex flex-wrap items-center gap-5",children:[B.map(($)=>Q1(RM1,{...$},`footer-${$.href}-${$.label}`,!1,void 0,this)),Q1("button",{id:"themeToggle","aria-label":"Toggle light mode",className:"rounded-md border border-theme-light bg-transparent px-2.5 py-1.5 font-body text-label-md text-theme-light transition-colors hover:border-theme hover:text-theme",children:"\u2600 Light"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var JTQ=({sections:A,siteInfo:Q})=>Q1(YTQ,{siteInfo:Q,children:A},void 0,!1,void 0,this);function XTQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,signals:f}){return Q1(Uq,{className:"min-h-[92vh] pt-[152px] pb-20 md:pt-[190px]",children:Q1("div",{className:"grid gap-10 lg:grid-cols-[minmax(0,1fr)_420px] lg:items-end",children:[Q1("div",{children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),Q1("h1",{className:"mt-7 max-w-[980px] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),Q1("p",{className:"mt-7 max-w-[720px] font-body text-body-lg text-theme-muted",children:B},void 0,!1,void 0,this),Q1("div",{className:"mt-10 flex flex-col gap-3 sm:flex-row",children:[Q1(jC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),Q1(jC,{href:$.href,size:"lg",variant:"secondary",children:$.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"rounded-[32px] border border-card-relay-border bg-card-relay-bg p-5 shadow-[0_24px_90px_var(--color-glow-relay)] backdrop-blur-sm",children:[Q1("p",{className:"font-label text-label-xs uppercase tracking-[0.24em] text-theme-light",children:"Live relay signals"},void 0,!1,void 0,this),Q1("div",{className:"mt-5 grid gap-3",children:f.map((I)=>Q1("div",{className:"rounded-[22px] border border-card-divider bg-bg-muted p-5",children:[Q1("div",{className:"flex items-center justify-between gap-4",children:[Q1("p",{className:"font-label text-label-xs uppercase tracking-[0.18em] text-secondary",children:I.label},void 0,!1,void 0,this),Q1("span",{className:"h-2 w-2 rounded-full bg-accent shadow-[0_0_22px_var(--color-accent)]"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("p",{className:"mt-4 font-display text-display-sm text-theme",children:I.value},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-body text-body-xs text-theme-muted",children:I.note},void 0,!1,void 0,this)]},I.label,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}function WTQ({eyebrow:A,title:Q,intro:B,steps:w}){return Q1(Uq,{id:"operating-loop",className:"py-section",children:[Q1("div",{className:"max-w-[840px]",children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-secondary",children:A},void 0,!1,void 0,this),Q1("h2",{className:"mt-5 font-display text-display-md text-theme",children:Q},void 0,!1,void 0,this),Q1("p",{className:"mt-5 font-body text-body-md text-theme-muted",children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:w.map(($)=>Q1("article",{className:"min-h-[300px] rounded-[28px] border border-card-panel-border bg-card-panel-bg p-6",children:[Q1("p",{className:"font-label text-label-sm text-accent",children:$.phase},void 0,!1,void 0,this),Q1("h3",{className:"mt-16 font-display text-display-sm text-theme",children:$.title},void 0,!1,void 0,this),Q1("p",{className:"mt-4 font-body text-body-sm text-theme-muted",children:$.text},void 0,!1,void 0,this)]},$.phase,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function HTQ({title:A,intro:Q,cards:B}){return Q1(Uq,{className:"py-section",children:Q1("div",{className:"rounded-[36px] border border-theme-light bg-bg-muted p-6 md:p-10",children:Q1("div",{className:"grid gap-8 lg:grid-cols-[360px_1fr]",children:[Q1("div",{children:[Q1("h2",{className:"font-display text-display-md text-theme",children:A},void 0,!1,void 0,this),Q1("p",{className:"mt-5 font-body text-body-md text-theme-muted",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"grid gap-4",children:B.map((w)=>Q1("article",{className:"rounded-[24px] border border-card-divider bg-bg-subtle/70 p-5",children:[Q1("p",{className:"font-label text-label-xs uppercase tracking-[0.22em] text-accent",children:w.label},void 0,!1,void 0,this),Q1("h3",{className:"mt-3 font-nav text-heading-lg text-theme",children:w.title},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-body text-body-sm text-theme-muted",children:w.text},void 0,!1,void 0,this)]},w.title,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function GTQ({title:A,intro:Q,points:B}){return Q1(Uq,{className:"min-h-[78vh] pt-[150px] pb-section md:pt-[190px]",children:[Q1("div",{className:"max-w-[920px]",children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:"Relay model"},void 0,!1,void 0,this),Q1("h1",{className:"mt-6 font-display text-display-lg text-theme",children:A},void 0,!1,void 0,this),Q1("p",{className:"mt-7 font-body text-body-lg text-theme-muted",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:B.map((w)=>Q1("div",{className:"rounded-[24px] border border-card-panel-current-border bg-card-panel-current-bg p-6 font-body text-body-md text-theme",children:w},w,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var KTQ=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},FTQ=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),hr=(A,Q,B=`${Q}s`)=>`${FTQ(A)} ${A===1?Q:B}`;function ZTQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,inputs:f,outputs:I,core:D,legend:U,counts:Y}){let J=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:hr(Y.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:hr(Y.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:hr(Y.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:hr(Y.summaries,"summary","summaries")}];return Q1(Uq,{className:"pt-[150px] pb-section md:pt-[190px]",id:"diagram",children:[Q1("div",{className:"mx-auto max-w-[1040px] text-center",children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),Q1("h1",{className:"mx-auto mt-7 max-w-[22ch] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),Q1("p",{className:"mx-auto mt-7 max-w-[64ch] font-body text-body-lg text-theme-muted",children:B},void 0,!1,void 0,this),Q1("div",{className:"mt-10 flex flex-col justify-center gap-3 sm:flex-row",children:[Q1(jC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),Q1(jC,{href:$.href,size:"lg",variant:"secondary",children:$.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"mx-auto mt-20 max-w-[1020px] rounded-[32px] border border-theme-light bg-[radial-gradient(circle_at_1px_1px,rgb(255_255_255_/_0.05)_1px,transparent_0),linear-gradient(180deg,rgb(255_255_255_/_0.02),transparent)] bg-[length:24px_24px,100%_100%] px-6 py-14",children:[Q1("div",{className:"grid items-center gap-8 lg:grid-cols-[1fr_1.4fr_1fr]",children:[Q1("div",{className:"flex flex-col gap-3.5",children:f.map((X)=>Q1("div",{className:"rounded-2xl border border-card-panel-border border-l-2 border-l-accent bg-card-panel-bg px-4 py-4 text-left backdrop-blur-sm",children:[Q1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:X.label},void 0,!1,void 0,this),Q1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:X.title},void 0,!1,void 0,this),Q1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:X.detail},void 0,!1,void 0,this)]},`${X.label}-${X.title}`,!0,void 0,this))},void 0,!1,void 0,this),Q1("div",{className:"relative mx-auto grid aspect-square w-full max-w-[320px] place-items-center rounded-full bg-[radial-gradient(circle_at_center,rgb(232_119_34_/_0.25),transparent_65%)]",children:[Q1("div",{className:"absolute inset-0 rounded-full border border-dashed border-accent/30"},void 0,!1,void 0,this),Q1("div",{className:"absolute inset-6 animate-spin rounded-full border border-dashed border-secondary/40 [animation-duration:28s]"},void 0,!1,void 0,this),J.map((X)=>Q1("span",{className:`absolute whitespace-nowrap rounded-full border border-theme bg-bg px-2.5 py-1 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light ${X.className}`,children:X.label},X.key,!1,void 0,this)),Q1("div",{className:"relative z-[1] px-6 text-center",children:[Q1("p",{className:"font-label text-[10px] uppercase tracking-[0.28em] text-accent",children:D.eyebrow},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-display text-[36px] leading-none text-theme",children:D.name},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-body text-[13px] text-theme-muted",children:D.sub},void 0,!1,void 0,this),Q1("p",{className:"mt-4 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light",children:[hr(Y.links,"link")," indexed"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"flex flex-col gap-3.5",children:I.map((X)=>Q1("div",{className:"rounded-2xl border border-card-panel-border border-r-2 border-r-secondary bg-card-panel-bg px-4 py-4 text-left backdrop-blur-sm",children:[Q1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:X.label},void 0,!1,void 0,this),Q1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:X.title},void 0,!1,void 0,this),Q1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:X.detail},void 0,!1,void 0,this)]},`${X.label}-${X.title}`,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"mt-14 grid gap-4 border-t border-theme-light pt-8 md:grid-cols-3",children:U.map((X)=>Q1("div",{className:"text-left",children:[Q1("h2",{className:"font-display text-[16px] font-medium text-theme",children:[Q1("span",{className:`mr-2.5 inline-block h-3 w-3 rounded-[3px] align-middle ${KTQ(X.tone)}`},void 0,!1,void 0,this),X.title]},void 0,!0,void 0,this),Q1("p",{className:"mt-1.5 font-body text-[13px] leading-[1.6] text-theme-muted",children:X.text},void 0,!1,void 0,this)]},X.title,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var NTQ=P1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:zcA,formatter:{parse:(A)=>zcA.parse({...Z7A(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>CM1(Vy.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:ZTQ}}),zTQ=(A)=>XTQ(wTQ.parse(A)),qTQ=(A)=>WTQ($TQ.parse(A)),LTQ=(A)=>HTQ(fTQ.parse(A)),VTQ=(A)=>GTQ(ITQ.parse(A)),bM1={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},PM1={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:zTQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...bM1,label:"Primary CTA"},secondaryCta:{...bM1,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:qTQ,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:LTQ,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:VTQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},ETQ=[{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:DTQ}]}],kM1=tuA({packageName:"@brains/relay/site",contentNamespace:"relay-site",themeProfile:"studio",layout:JTQ,routes:ETQ,templates:{"home-diagram":NTQ},dataSources:[new qcA]});var jM1={name:"@brains/relay",private:!0,version:"0.2.0-alpha.125",description:"Relay brain model \u2014 collaborative knowledge management",type:"module",files:["src","brain.eval.yaml","env.schema.template"],exports:{".":"./src/index.ts"},scripts:{"build:web-chat":"turbo run build --filter=@brains/web-chat","start:core":"bun run build:web-chat && cd test-apps/core && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:default":"bun run build:web-chat && cd test-apps/default && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:full":"bun run build:web-chat && cd test-apps/full && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:docs":"bun run build:web-chat && cd test-apps/docs && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start",typecheck:"tsc --noEmit",test:"bun test",eval:"brain-eval",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/a2a":"workspace:*","@brains/agent-discovery":"workspace:*","@brains/app":"workspace:*","@brains/assessment":"workspace:*","@brains/auth-service":"workspace:*","@brains/cms":"workspace:*","@brains/content-formatters":"workspace:*","@brains/conversation-memory":"workspace:*","@brains/dashboard":"workspace:*","@brains/decks":"workspace:*","@brains/directory-sync":"workspace:*","@brains/discord":"workspace:*","@brains/doc":"workspace:*","@brains/email-resend":"workspace:*","@brains/image-plugin":"workspace:*","@brains/link":"workspace:*","@brains/mcp":"workspace:*","@brains/note":"workspace:*","@brains/notifications":"workspace:*","@brains/plugins":"workspace:*","@brains/prompt":"workspace:*","@brains/rizom-ecosystem":"workspace:*","@brains/site-builder-plugin":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-content":"workspace:*","@brains/site-info":"workspace:*","@brains/site-rizom":"workspace:*","@brains/theme-rizom":"workspace:*","@brains/topics":"workspace:*","@brains/utils":"workspace:*","@brains/web-chat":"workspace:*","@brains/webserver":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/ai-evaluation":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*",typescript:"^5.3.3"}};var _M1=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","notifications","email-resend","cms","dashboard","mcp","webserver","web-chat","discord","a2a"],vM1=[..._M1,"image","site-info","site-content","site-builder"],OTQ=[...vM1,"docs","decks"],RTQ=["Relay is a collaborative team-memory and synthesis brain. Optimize for capturing shared context, finding what the team already knows, summarizing cross-source evidence, and coordinating with peer brains.","Relay is not Rover-for-teams: do not default to personal branding, blog publishing, newsletters, social media, portfolio, or marketing workflows unless the installed plugins and user request explicitly support them.",'Relay entity mappings: "memo", "note", "team note", "capture" \u2192 entityType: note; "summary", "sync", "team digest" \u2192 entityType: summary; "decision" \u2192 entityType: decision; "action item", "todo" \u2192 entityType: action-item; "handbook", "doc", "documentation" \u2192 entityType: doc; "deck", "walkthrough", "presentation" \u2192 entityType: deck; "agent", "peer brain", "contact" \u2192 entityType: agent.'],yM1=nN({name:"relay",version:jM1.version,model:"gpt-5.4-mini",site:kM1,theme:Uy,presets:{core:_M1,default:vM1,full:OTQ},evalDisable:["webserver","web-chat","mcp","discord"],agentInstructions:RTQ,capabilities:[["prompt",RC,void 0],["note",NC,{}],["link",qC,{}],["image",zh,void 0],["topics",v$A,{includeEntityTypes:["note","link","summary","agent","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",XcA,{memoryVisibility:"shared"}],["docs",ZcA,void 0],["decks",Zi,void 0],["agents",q9A,void 0],["assessment",k9A,void 0],["auth-service",Ju,void 0],["notifications",A1A,void 0],["email-resend",vwA,void 0],["cms",OC,{}],["dashboard",fq,void 0],["directory-sync",LM,{seedContent:!0,seedContentPath:CTQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",kr,{definitions:PM1}],["rizom-ecosystem",bC,void 0],["site-info",IC,void 0],["site-builder",fC,{}]],interfaces:[["mcp",P3,()=>({})],["discord",Jz,()=>({captureUrls:!0})],["a2a",I_,()=>({})],["webserver",Xz,()=>({})],["web-chat",f_,()=>({})]],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"}}});import{readFileSync as IhQ}from"fs";import{join as DhQ}from"path";import{execSync as UhQ}from"child_process";import{parseArgs as kTQ}from"util";var jTQ={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 qX(A,Q){let B=A[Q];return typeof B==="string"?B:void 0}function Xq(A,Q){let B=A[Q];return typeof B==="boolean"?B:void 0}function TM1(A){let{values:Q,positionals:B}=kTQ({args:A,options:jTQ,allowPositionals:!0,strict:!1});if(Q.help)return{command:"help",args:[],flags:{help:!0}};if(Q.version)return{command:"version",args:[],flags:{version:!0}};return{command:B[0]??"help",args:B.slice(1),flags:{model:qX(Q,"model"),domain:qX(Q,"domain"),"content-repo":qX(Q,"content-repo"),backend:qX(Q,"backend"),"push-to":qX(Q,"push-to"),"ai-api-key":qX(Q,"ai-api-key"),"no-interactive":Xq(Q,"no-interactive"),preview:Xq(Q,"preview"),deploy:Xq(Q,"deploy"),regen:Xq(Q,"regen"),all:Xq(Q,"all"),only:qX(Q,"only"),"dry-run":Xq(Q,"dry-run"),"startup-check":Xq(Q,"startup-check"),"storage-dir":qX(Q,"storage-dir"),yes:Xq(Q,"yes"),remote:qX(Q,"remote"),token:qX(Q,"token"),outputDir:qX(Q,"outputDir")}}}mr();import{mkdirSync as sgQ}from"fs";import{join as agQ}from"path";import{execSync as tgQ}from"child_process";var z7A={name:"@rizom/brain",version:"0.2.0-alpha.125",description:"Brain runtime + CLI \u2014 scaffold, run, and manage AI brain instances",type:"module",bin:{brain:"./dist/brain.js"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./cli":"./dist/brain.js","./plugins":{types:"./dist/plugins.d.ts",import:"./dist/plugins.js"},"./entities":{types:"./dist/entities.d.ts",import:"./dist/entities.js"},"./services":{types:"./dist/services.d.ts",import:"./dist/services.js"},"./interfaces":{types:"./dist/interfaces.d.ts",import:"./dist/interfaces.js"},"./templates":{types:"./dist/templates.d.ts",import:"./dist/templates.js"},"./site":{types:"./dist/site.d.ts",import:"./dist/site.js"},"./themes":{types:"./dist/themes.d.ts",import:"./dist/themes.js"},"./deploy":{types:"./dist/deploy.d.ts",import:"./dist/deploy.js"},"./tsconfig.instance.json":"./tsconfig.instance.json"},files:["dist","templates","tsconfig.instance.json"],scripts:{build:"bun scripts/build.ts",prepublishOnly:"bun scripts/build.ts","dev:start":"bun scripts/build.ts && bun dist/brain.js start",typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts"},dependencies:{"@clack/prompts":"^0.11.0","@modelcontextprotocol/sdk":"^1.24.0","@tailwindcss/postcss":"^4.1.13","@tailwindcss/typography":"^0.5.19",postcss:"^8.5.6",preact:"^10.27.2","preact-render-to-string":"^6.3.1",tailwindcss:"^4.1.11"},optionalDependencies:{"@bitwarden/sdk-napi":"^1.0.0","@libsql/client":"^0.15.7","@tailwindcss/oxide":"^4.1.4","better-sqlite3":"^11.8.1",lightningcss:"^1.29.2","playwright-core":"^1.56.0","react-devtools-core":"^6.1.1",sharp:"^0.34.5"},devDependencies:{"@brains/app":"workspace:*","@brains/content-formatters":"workspace:*","@brains/deploy-support":"workspace:*","@brains/eslint-config":"workspace:*","@brains/mcp-service":"workspace:*","@brains/plugins":"workspace:*","@brains/ranger":"workspace:*","@brains/relay":"workspace:*","@brains/rover":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-default":"workspace:*","@brains/site-personal":"workspace:*","@brains/site-professional":"workspace:*","@brains/theme-default":"workspace:*","@brains/theme-rizom":"workspace:*","@brains/typescript-config":"workspace:*","@brains/utils":"workspace:*","@types/bun":"latest",rollup:"^4.60.2","rollup-plugin-dts":"^6.4.1",typescript:"^5.3.3"},publishConfig:{access:"public"},repository:{type:"git",url:"https://github.com/rizom-ai/brains.git",directory:"packages/brain-cli"},license:"Apache-2.0",author:"Yeehaa <yeehaa@rizom.ai> (https://rizom.ai)",homepage:"https://github.com/rizom-ai/brains/tree/main/packages/brain-cli#readme",bugs:"https://github.com/rizom-ai/brains/issues",engines:{bun:">=1.3.3"},keywords:["brain","ai","cli","mcp","agent","personal-ai","knowledge-management"]};import{mkdirSync as sM1,writeFileSync as cr,chmodSync as lr,existsSync as kcA,readFileSync as jcA}from"fs";import{basename as _cA,dirname as vcA,join as D6,resolve as XxQ}from"path";import{fileURLToPath as WxQ}from"url";var xM1=`ARG BUN_VERSION=1.3.10
|
|
11667
|
+
`,WM1=()=>$$("style",{children:nyQ},void 0,!1,void 0,this);import{jsxDEV as K2,Fragment as oyQ}from"preact/jsx-dev-runtime";var F7A=({title:A,description:Q,children:B,detail:w=!1,footer:$=!1,contentClassName:f=""})=>K2(oyQ,{children:[K2(ZQ,{title:A,description:Q},void 0,!1,void 0,this),K2(WM1,{},void 0,!1,void 0,this),K2("div",{className:`docs-handbook${w?" docs-handbook--detail":""}`,children:[K2(JM1,{},void 0,!1,void 0,this),K2("div",{className:`${iH.wrap} ${f}`.trim(),children:[B,$&&K2(XM1,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),HM1=({docsCount:A,sectionsCount:Q,startDoc:B})=>K2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[K2("p",{className:`${iH.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),K2("h1",{className:`${iH.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",K2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("p",{className:"mt-8 max-w-[52ch] text-lg leading-[1.65] text-[var(--docs-text-muted)]",children:"Documentation for composing brain models, managing markdown entities, wiring interfaces, and shipping generated sites."},void 0,!1,void 0,this),K2("dl",{className:"mt-10 flex flex-wrap gap-7 docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)] md:mt-14 md:gap-12",children:[K2("div",{children:[K2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:A},void 0,!1,void 0,this),"Documents"]},void 0,!0,void 0,this),K2("div",{children:[K2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:Q},void 0,!1,void 0,this),"Sections"]},void 0,!0,void 0,this),K2("div",{children:[K2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:"April 2026"},void 0,!1,void 0,this),"Updated"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[B&&K2("a",{className:iH.primaryButton,href:zy(B),children:"Start reading"},void 0,!1,void 0,this),K2("a",{className:iH.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),GM1=({groups:A})=>K2("aside",{className:"docs-rail sticky top-8 hidden docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)] min-[861px]:block","aria-label":"Documentation sections",children:[K2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),K2("ol",{className:"m-0 list-none p-0",children:A.map((Q,B)=>K2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[K2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[qy(B),"."]},void 0,!0,void 0,this),K2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${K7A(B)}`,children:Q.section},void 0,!1,void 0,this)]},Q.section,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),KM1=({group:A,index:Q})=>K2("article",{className:"mb-16 last:mb-0",id:K7A(Q),children:[K2("header",{className:"mb-2 grid grid-cols-[36px_auto_1fr] items-baseline gap-x-3 border-b border-[var(--docs-border)] pb-3.5 md:grid-cols-[48px_auto_1fr] md:gap-x-5",children:[K2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[qy(Q),"."]},void 0,!0,void 0,this),K2("h2",{className:`${iH.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),K2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("ol",{className:"m-0 list-none p-0",children:A.docs.map((B)=>K2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:K2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:zy(B),children:[K2("p",{className:"m-0 text-[22px] leading-[1.2] tracking-[-0.005em] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:B.metadata.title},void 0,!1,void 0,this),B.metadata.description&&K2("p",{className:"mt-1.5 mb-0 max-w-[70ch] text-sm leading-[1.55] text-[var(--docs-text-muted)]",children:B.metadata.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},B.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),FM1=({title:A})=>K2("nav",{className:"mb-8 flex flex-wrap items-baseline gap-2.5 docs-font-label text-[11px] uppercase tracking-[0.06em] text-[var(--docs-text-light)]","aria-label":"Breadcrumb",children:[K2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),K2("span",{children:"/"},void 0,!1,void 0,this),K2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),K2("span",{children:"/"},void 0,!1,void 0,this),K2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),ZM1=({groups:A,activeGroupIndex:Q,activeSlug:B})=>K2("aside",{className:"docs-detail-rail sticky top-24 hidden max-h-[calc(100vh-120px)] overflow-auto pr-2 min-[861px]:block","aria-label":"Documentation navigation",children:K2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[K2("p",{className:"m-0 mb-4 border-b border-[var(--docs-text)] pb-3 text-[11px] uppercase tracking-[0.08em] text-[var(--docs-text-light)]",children:"Documentation"},void 0,!1,void 0,this),K2("ol",{className:"m-0 list-none p-0",children:A.map((w,$)=>{let f=$===Q;return K2("li",{className:f?"mb-[22px]":"mb-3.5",children:[K2("a",{className:`mb-2 flex items-baseline gap-2.5 docs-font-label text-[11px] uppercase leading-[1.4] tracking-[0.06em] transition-colors duration-150 hover:text-[var(--docs-text)] ${f?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${K7A($)}`,children:[K2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[qy($),"."]},void 0,!0,void 0,this)," ",w.section]},void 0,!0,void 0,this),f&&K2("ol",{className:"mt-0.5 list-none p-0",children:w.docs.map((I)=>{let D=I.metadata.slug===B;return K2("li",{children:K2("a",{className:`docs-rail__doc relative block py-1.5 docs-font-body text-sm leading-[1.4] tracking-normal transition-[color,padding-left] duration-150 hover:text-[var(--docs-text)] ${D?"pl-3.5 font-medium text-[var(--docs-accent)]":"text-[var(--docs-text-muted)]"}`,href:zy(I),"aria-current":D?"page":void 0,children:I.metadata.title},void 0,!1,void 0,this)},I.id,!1,void 0,this)})},void 0,!1,void 0,this)]},w.section,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),NM1=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return K2("nav",{className:"mt-12 grid grid-cols-1 gap-5 border-t border-[var(--docs-border)] pt-7 md:grid-cols-2","aria-label":"Previous and next docs",children:[A?K2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:zy(A),children:[K2("span",{className:"block docs-font-label text-[10.5px] uppercase tracking-[0.22em] text-[var(--docs-text-light)]",children:"Previous"},void 0,!1,void 0,this),K2("span",{className:"mt-2 block docs-font-display text-[22px] leading-[1.2] text-[var(--docs-heading)] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:["\u2190 ",A.metadata.title]},void 0,!0,void 0,this)]},void 0,!0,void 0,this):K2("span",{},void 0,!1,void 0,this),Q&&K2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] text-left transition-colors duration-150 hover:border-[var(--docs-accent)] md:text-right",href:zy(Q),children:[K2("span",{className:"block docs-font-label text-[10.5px] uppercase tracking-[0.22em] text-[var(--docs-text-light)]",children:"Next"},void 0,!1,void 0,this),K2("span",{className:"mt-2 block docs-font-display text-[22px] leading-[1.2] text-[var(--docs-heading)] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:[Q.metadata.title," \u2192"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as Ly}from"preact/jsx-dev-runtime";var GcA=({docs:A})=>{let Q=gr(A),B=G7A(Q),$=Q.filter((f)=>f.metadata.slug!=="index")[0]??Q[0];return Ly(F7A,{title:"Documentation",description:"Brains documentation",children:[Ly(HM1,{docsCount:A.length,sectionsCount:B.length,startDoc:$},void 0,!1,void 0,this),Ly("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:[Ly(GM1,{groups:B},void 0,!1,void 0,this),Ly("div",{children:B.map((f,I)=>Ly(KM1,{group:f,index:I},f.section,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as vD}from"preact/jsx-dev-runtime";var KcA=({doc:A,docs:Q,prevDoc:B,nextDoc:w})=>{let $=G7A(Q.length>0?Q:[A]),f=gr(Q.length>0?Q:[A]),I=f.findIndex((U)=>U.metadata.slug===A.metadata.slug),D=Math.max($.findIndex((U)=>U.docs.some((Y)=>Y.metadata.slug===A.metadata.slug)),0);return vD(F7A,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[vD(FM1,{title:A.metadata.title},void 0,!1,void 0,this),vD("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[vD(ZM1,{groups:$,activeGroupIndex:D,activeSlug:A.metadata.slug},void 0,!1,void 0,this),vD("article",{className:"min-w-0",children:[vD("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[vD("p",{className:`${iH.label} m-0 mb-6 flex items-baseline gap-3`,children:[vD("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[qy(D),"."]},void 0,!0,void 0,this)," ",A.metadata.section,I>=0?` \xB7 ${I+1}/${f.length}`:""]},void 0,!0,void 0,this),vD("h1",{className:`${iH.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&&vD("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),vD("div",{className:"docs-article__body",children:vD(M$,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),vD(NM1,{prevDoc:B,nextDoc:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};var syQ=H.object({docs:H.array($Z),pagination:z7.nullable(),baseUrl:H.string().optional()}),ayQ=H.object({doc:$Z,docs:H.array($Z),prevDoc:$Z.nullable(),nextDoc:$Z.nullable()});function zM1(){return{"doc-list":P1({name:"doc-list",description:"Documentation index template",schema:syQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:GcA}}),"doc-detail":P1({name:"doc-detail",description:"Documentation page template",schema:ayQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:KcA}})}}var qM1={name:"@brains/doc",private:!0,version:"0.2.0-alpha.127",description:"Documentation entity type \u2014 markdown docs as first-class brain content",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","bun-types":"latest",typescript:"^5.3.3"}};class FcA extends _Q{entityType=W7A.entityType;schema=Ny;adapter=W7A;constructor(){super("docs",qM1,{},void 0)}getTemplates(){return zM1()}getDataSources(){return[new H7A(this.logger.child("DocDataSource"))]}}function ZcA(){return new FcA}aA();WA();WA();t$();var LM1=H.object({label:H.string(),href:H.string()}),VM1=H.object({label:H.string(),title:H.string(),detail:H.string()}),eyQ=H.object({eyebrow:H.string(),name:H.string(),sub:H.string()}),ATQ=H.object({tone:H.enum(["capture","synthesis","share"]),title:H.string(),text:H.string()}),NcA=H.object({captures:H.number(),links:H.number(),topics:H.number(),summaries:H.number(),peers:H.number()}),Vy=H.object({eyebrow:H.string(),headline:H.string(),intro:H.string(),primaryCta:LM1,secondaryCta:LM1,inputs:H.array(VM1).min(1),outputs:H.array(VM1).min(1),core:eyQ,legend:H.array(ATQ).min(1)}),zcA=Vy.extend({counts:NcA}),EM1={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."}]},MM1=new lB(Vy,{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 Z7A(A){return MM1.parse(A)}function CM1(A){return MM1.format(A)}WA();var QTQ=H.object({query:H.object({routeId:H.string().default("home"),sectionId:H.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}).passthrough(),BTQ={captures:"note",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class qcA{id="relay-site:home-counts";name="Relay homepage counts";description="Fetches Relay homepage content and live entity counts for the system diagram";async fetch(A,Q,B){let w=QTQ.parse(A??{}),$=await this.fetchContent(B,w.query.routeId,w.query.sectionId),f=await this.fetchCounts(B);return Q.parse({...$,counts:f})}async fetchContent(A,Q,B){let w=await A.entityService.getEntity({entityType:"site-content",id:`${Q}:${B}`});if(!w?.content)return EM1;return Vy.parse(Z7A(w.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries(BTQ).map(async([B,w])=>[B,await this.countOrZero(A,w)]));return NcA.parse(Object.fromEntries(Q))}async countOrZero(A,Q){if(!A.entityService.hasEntityType(Q))return 0;try{return await A.entityService.countEntities({entityType:Q})}catch{return 0}}}import{jsxDEV as Q1}from"preact/jsx-dev-runtime";var OM1=H.object({label:H.string(),href:H.string()}),wTQ=H.object({eyebrow:H.string(),headline:H.string(),intro:H.string(),primaryCta:OM1,secondaryCta:OM1,signals:H.array(H.object({label:H.string(),value:H.string(),note:H.string()}))}),$TQ=H.object({eyebrow:H.string(),title:H.string(),intro:H.string(),steps:H.array(H.object({phase:H.string(),title:H.string(),text:H.string()}))}),fTQ=H.object({title:H.string(),intro:H.string(),cards:H.array(H.object({label:H.string(),title:H.string(),text:H.string()}))}),ITQ=H.object({title:H.string(),intro:H.string(),points:H.array(H.string())}),DTQ={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."]},UTQ="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function RM1({href:A,label:Q}){return Q1("a",{href:A,className:UTQ,children:Q},void 0,!1,void 0,this)}function YTQ({siteInfo:A,children:Q}){let B=[...A.navigation.primary,...A.navigation.secondary],w=A.cta??{buttonText:"Start here",buttonLink:"/about"};return Q1(Dy,{children:[Q1("nav",{className:"fixed left-0 right-0 top-0 z-[100] flex items-center justify-between border-b border-theme-light bg-nav-fade px-6 py-4 backdrop-blur-[12px] md:px-10 xl:px-20",children:[Q1("a",{href:"/",className:"font-nav text-[20px]","aria-label":"Relay home",children:[Q1("span",{className:"font-bold text-theme",children:"relay"},void 0,!1,void 0,this),Q1("span",{className:"font-bold text-accent",children:"."},void 0,!1,void 0,this),Q1("span",{className:"text-theme-muted",children:"brain"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"flex items-center gap-5 md:gap-8",children:[Q1("div",{className:"hidden items-center gap-6 md:flex",children:B.map(($)=>Q1(RM1,{...$},`${$.href}-${$.label}`,!1,void 0,this))},void 0,!1,void 0,this),Q1("a",{href:w.buttonLink,className:"rounded-[999px] border border-theme px-4 py-2 font-body text-[13px] font-semibold text-theme transition-colors hover:border-accent hover:text-accent md:px-5",children:w.buttonText},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1("main",{children:Q},void 0,!1,void 0,this),Q1("footer",{className:"relative z-[1] border-t border-theme-light px-6 py-8 md:px-10 xl:px-20",children:Q1("div",{className:"flex flex-col gap-4 md:flex-row md:items-center md:justify-between",children:[Q1("div",{children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.22em] text-theme-light",children:A.copyright},void 0,!1,void 0,this),Q1("p",{className:"mt-2 max-w-[560px] font-body text-body-xs text-theme-muted",children:A.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"flex flex-wrap items-center gap-5",children:[B.map(($)=>Q1(RM1,{...$},`footer-${$.href}-${$.label}`,!1,void 0,this)),Q1("button",{id:"themeToggle","aria-label":"Toggle light mode",className:"rounded-md border border-theme-light bg-transparent px-2.5 py-1.5 font-body text-label-md text-theme-light transition-colors hover:border-theme hover:text-theme",children:"\u2600 Light"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var JTQ=({sections:A,siteInfo:Q})=>Q1(YTQ,{siteInfo:Q,children:A},void 0,!1,void 0,this);function XTQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,signals:f}){return Q1(Uq,{className:"min-h-[92vh] pt-[152px] pb-20 md:pt-[190px]",children:Q1("div",{className:"grid gap-10 lg:grid-cols-[minmax(0,1fr)_420px] lg:items-end",children:[Q1("div",{children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),Q1("h1",{className:"mt-7 max-w-[980px] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),Q1("p",{className:"mt-7 max-w-[720px] font-body text-body-lg text-theme-muted",children:B},void 0,!1,void 0,this),Q1("div",{className:"mt-10 flex flex-col gap-3 sm:flex-row",children:[Q1(jC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),Q1(jC,{href:$.href,size:"lg",variant:"secondary",children:$.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"rounded-[32px] border border-card-relay-border bg-card-relay-bg p-5 shadow-[0_24px_90px_var(--color-glow-relay)] backdrop-blur-sm",children:[Q1("p",{className:"font-label text-label-xs uppercase tracking-[0.24em] text-theme-light",children:"Live relay signals"},void 0,!1,void 0,this),Q1("div",{className:"mt-5 grid gap-3",children:f.map((I)=>Q1("div",{className:"rounded-[22px] border border-card-divider bg-bg-muted p-5",children:[Q1("div",{className:"flex items-center justify-between gap-4",children:[Q1("p",{className:"font-label text-label-xs uppercase tracking-[0.18em] text-secondary",children:I.label},void 0,!1,void 0,this),Q1("span",{className:"h-2 w-2 rounded-full bg-accent shadow-[0_0_22px_var(--color-accent)]"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("p",{className:"mt-4 font-display text-display-sm text-theme",children:I.value},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-body text-body-xs text-theme-muted",children:I.note},void 0,!1,void 0,this)]},I.label,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}function WTQ({eyebrow:A,title:Q,intro:B,steps:w}){return Q1(Uq,{id:"operating-loop",className:"py-section",children:[Q1("div",{className:"max-w-[840px]",children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-secondary",children:A},void 0,!1,void 0,this),Q1("h2",{className:"mt-5 font-display text-display-md text-theme",children:Q},void 0,!1,void 0,this),Q1("p",{className:"mt-5 font-body text-body-md text-theme-muted",children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:w.map(($)=>Q1("article",{className:"min-h-[300px] rounded-[28px] border border-card-panel-border bg-card-panel-bg p-6",children:[Q1("p",{className:"font-label text-label-sm text-accent",children:$.phase},void 0,!1,void 0,this),Q1("h3",{className:"mt-16 font-display text-display-sm text-theme",children:$.title},void 0,!1,void 0,this),Q1("p",{className:"mt-4 font-body text-body-sm text-theme-muted",children:$.text},void 0,!1,void 0,this)]},$.phase,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function HTQ({title:A,intro:Q,cards:B}){return Q1(Uq,{className:"py-section",children:Q1("div",{className:"rounded-[36px] border border-theme-light bg-bg-muted p-6 md:p-10",children:Q1("div",{className:"grid gap-8 lg:grid-cols-[360px_1fr]",children:[Q1("div",{children:[Q1("h2",{className:"font-display text-display-md text-theme",children:A},void 0,!1,void 0,this),Q1("p",{className:"mt-5 font-body text-body-md text-theme-muted",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"grid gap-4",children:B.map((w)=>Q1("article",{className:"rounded-[24px] border border-card-divider bg-bg-subtle/70 p-5",children:[Q1("p",{className:"font-label text-label-xs uppercase tracking-[0.22em] text-accent",children:w.label},void 0,!1,void 0,this),Q1("h3",{className:"mt-3 font-nav text-heading-lg text-theme",children:w.title},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-body text-body-sm text-theme-muted",children:w.text},void 0,!1,void 0,this)]},w.title,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function GTQ({title:A,intro:Q,points:B}){return Q1(Uq,{className:"min-h-[78vh] pt-[150px] pb-section md:pt-[190px]",children:[Q1("div",{className:"max-w-[920px]",children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:"Relay model"},void 0,!1,void 0,this),Q1("h1",{className:"mt-6 font-display text-display-lg text-theme",children:A},void 0,!1,void 0,this),Q1("p",{className:"mt-7 font-body text-body-lg text-theme-muted",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:B.map((w)=>Q1("div",{className:"rounded-[24px] border border-card-panel-current-border bg-card-panel-current-bg p-6 font-body text-body-md text-theme",children:w},w,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var KTQ=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},FTQ=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),hr=(A,Q,B=`${Q}s`)=>`${FTQ(A)} ${A===1?Q:B}`;function ZTQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,inputs:f,outputs:I,core:D,legend:U,counts:Y}){let J=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:hr(Y.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:hr(Y.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:hr(Y.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:hr(Y.summaries,"summary","summaries")}];return Q1(Uq,{className:"pt-[150px] pb-section md:pt-[190px]",id:"diagram",children:[Q1("div",{className:"mx-auto max-w-[1040px] text-center",children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),Q1("h1",{className:"mx-auto mt-7 max-w-[22ch] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),Q1("p",{className:"mx-auto mt-7 max-w-[64ch] font-body text-body-lg text-theme-muted",children:B},void 0,!1,void 0,this),Q1("div",{className:"mt-10 flex flex-col justify-center gap-3 sm:flex-row",children:[Q1(jC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),Q1(jC,{href:$.href,size:"lg",variant:"secondary",children:$.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"mx-auto mt-20 max-w-[1020px] rounded-[32px] border border-theme-light bg-[radial-gradient(circle_at_1px_1px,rgb(255_255_255_/_0.05)_1px,transparent_0),linear-gradient(180deg,rgb(255_255_255_/_0.02),transparent)] bg-[length:24px_24px,100%_100%] px-6 py-14",children:[Q1("div",{className:"grid items-center gap-8 lg:grid-cols-[1fr_1.4fr_1fr]",children:[Q1("div",{className:"flex flex-col gap-3.5",children:f.map((X)=>Q1("div",{className:"rounded-2xl border border-card-panel-border border-l-2 border-l-accent bg-card-panel-bg px-4 py-4 text-left backdrop-blur-sm",children:[Q1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:X.label},void 0,!1,void 0,this),Q1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:X.title},void 0,!1,void 0,this),Q1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:X.detail},void 0,!1,void 0,this)]},`${X.label}-${X.title}`,!0,void 0,this))},void 0,!1,void 0,this),Q1("div",{className:"relative mx-auto grid aspect-square w-full max-w-[320px] place-items-center rounded-full bg-[radial-gradient(circle_at_center,rgb(232_119_34_/_0.25),transparent_65%)]",children:[Q1("div",{className:"absolute inset-0 rounded-full border border-dashed border-accent/30"},void 0,!1,void 0,this),Q1("div",{className:"absolute inset-6 animate-spin rounded-full border border-dashed border-secondary/40 [animation-duration:28s]"},void 0,!1,void 0,this),J.map((X)=>Q1("span",{className:`absolute whitespace-nowrap rounded-full border border-theme bg-bg px-2.5 py-1 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light ${X.className}`,children:X.label},X.key,!1,void 0,this)),Q1("div",{className:"relative z-[1] px-6 text-center",children:[Q1("p",{className:"font-label text-[10px] uppercase tracking-[0.28em] text-accent",children:D.eyebrow},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-display text-[36px] leading-none text-theme",children:D.name},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-body text-[13px] text-theme-muted",children:D.sub},void 0,!1,void 0,this),Q1("p",{className:"mt-4 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light",children:[hr(Y.links,"link")," indexed"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"flex flex-col gap-3.5",children:I.map((X)=>Q1("div",{className:"rounded-2xl border border-card-panel-border border-r-2 border-r-secondary bg-card-panel-bg px-4 py-4 text-left backdrop-blur-sm",children:[Q1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:X.label},void 0,!1,void 0,this),Q1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:X.title},void 0,!1,void 0,this),Q1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:X.detail},void 0,!1,void 0,this)]},`${X.label}-${X.title}`,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"mt-14 grid gap-4 border-t border-theme-light pt-8 md:grid-cols-3",children:U.map((X)=>Q1("div",{className:"text-left",children:[Q1("h2",{className:"font-display text-[16px] font-medium text-theme",children:[Q1("span",{className:`mr-2.5 inline-block h-3 w-3 rounded-[3px] align-middle ${KTQ(X.tone)}`},void 0,!1,void 0,this),X.title]},void 0,!0,void 0,this),Q1("p",{className:"mt-1.5 font-body text-[13px] leading-[1.6] text-theme-muted",children:X.text},void 0,!1,void 0,this)]},X.title,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var NTQ=P1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:zcA,formatter:{parse:(A)=>zcA.parse({...Z7A(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>CM1(Vy.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:ZTQ}}),zTQ=(A)=>XTQ(wTQ.parse(A)),qTQ=(A)=>WTQ($TQ.parse(A)),LTQ=(A)=>HTQ(fTQ.parse(A)),VTQ=(A)=>GTQ(ITQ.parse(A)),bM1={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},PM1={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:zTQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...bM1,label:"Primary CTA"},secondaryCta:{...bM1,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:qTQ,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:LTQ,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:VTQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},ETQ=[{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:DTQ}]}],kM1=tuA({packageName:"@brains/relay/site",contentNamespace:"relay-site",themeProfile:"studio",layout:JTQ,routes:ETQ,templates:{"home-diagram":NTQ},dataSources:[new qcA]});var jM1={name:"@brains/relay",private:!0,version:"0.2.0-alpha.127",description:"Relay brain model \u2014 collaborative knowledge management",type:"module",files:["src","brain.eval.yaml","env.schema.template"],exports:{".":"./src/index.ts"},scripts:{"build:web-chat":"turbo run build --filter=@brains/web-chat","start:core":"bun run build:web-chat && cd test-apps/core && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:default":"bun run build:web-chat && cd test-apps/default && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:full":"bun run build:web-chat && cd test-apps/full && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:docs":"bun run build:web-chat && cd test-apps/docs && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start",typecheck:"tsc --noEmit",test:"bun test",eval:"brain-eval",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/a2a":"workspace:*","@brains/agent-discovery":"workspace:*","@brains/app":"workspace:*","@brains/assessment":"workspace:*","@brains/auth-service":"workspace:*","@brains/cms":"workspace:*","@brains/content-formatters":"workspace:*","@brains/conversation-memory":"workspace:*","@brains/dashboard":"workspace:*","@brains/decks":"workspace:*","@brains/directory-sync":"workspace:*","@brains/discord":"workspace:*","@brains/doc":"workspace:*","@brains/email-resend":"workspace:*","@brains/image-plugin":"workspace:*","@brains/link":"workspace:*","@brains/mcp":"workspace:*","@brains/note":"workspace:*","@brains/notifications":"workspace:*","@brains/plugins":"workspace:*","@brains/prompt":"workspace:*","@brains/rizom-ecosystem":"workspace:*","@brains/site-builder-plugin":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-content":"workspace:*","@brains/site-info":"workspace:*","@brains/site-rizom":"workspace:*","@brains/theme-rizom":"workspace:*","@brains/topics":"workspace:*","@brains/utils":"workspace:*","@brains/web-chat":"workspace:*","@brains/webserver":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/ai-evaluation":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*",typescript:"^5.3.3"}};var _M1=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","notifications","email-resend","cms","dashboard","mcp","webserver","web-chat","discord","a2a"],vM1=[..._M1,"image","site-info","site-content","site-builder"],OTQ=[...vM1,"docs","decks"],RTQ=["Relay is a collaborative team-memory and synthesis brain. Optimize for capturing shared context, finding what the team already knows, summarizing cross-source evidence, and coordinating with peer brains.","Relay is not Rover-for-teams: do not default to personal branding, blog publishing, newsletters, social media, portfolio, or marketing workflows unless the installed plugins and user request explicitly support them.",'Relay entity mappings: "memo", "note", "team note", "capture" \u2192 entityType: note; "summary", "sync", "team digest" \u2192 entityType: summary; "decision" \u2192 entityType: decision; "action item", "todo" \u2192 entityType: action-item; "handbook", "doc", "documentation" \u2192 entityType: doc; "deck", "walkthrough", "presentation" \u2192 entityType: deck; "agent", "peer brain", "contact" \u2192 entityType: agent.'],yM1=nN({name:"relay",version:jM1.version,model:"gpt-5.4-mini",site:kM1,theme:Uy,presets:{core:_M1,default:vM1,full:OTQ},evalDisable:["webserver","web-chat","mcp","discord"],agentInstructions:RTQ,capabilities:[["prompt",RC,void 0],["note",NC,{}],["link",qC,{}],["image",zh,void 0],["topics",v$A,{includeEntityTypes:["note","link","summary","agent","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",XcA,{memoryVisibility:"shared"}],["docs",ZcA,void 0],["decks",Zi,void 0],["agents",q9A,void 0],["assessment",k9A,void 0],["auth-service",Ju,void 0],["notifications",A1A,void 0],["email-resend",vwA,void 0],["cms",OC,{}],["dashboard",fq,void 0],["directory-sync",LM,{seedContent:!0,seedContentPath:CTQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",kr,{definitions:PM1}],["rizom-ecosystem",bC,void 0],["site-info",IC,void 0],["site-builder",fC,{}]],interfaces:[["mcp",P3,()=>({})],["discord",Jz,()=>({captureUrls:!0})],["a2a",I_,()=>({})],["webserver",Xz,()=>({})],["web-chat",f_,()=>({})]],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"}}});import{readFileSync as IhQ}from"fs";import{join as DhQ}from"path";import{execSync as UhQ}from"child_process";import{parseArgs as kTQ}from"util";var jTQ={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 qX(A,Q){let B=A[Q];return typeof B==="string"?B:void 0}function Xq(A,Q){let B=A[Q];return typeof B==="boolean"?B:void 0}function TM1(A){let{values:Q,positionals:B}=kTQ({args:A,options:jTQ,allowPositionals:!0,strict:!1});if(Q.help)return{command:"help",args:[],flags:{help:!0}};if(Q.version)return{command:"version",args:[],flags:{version:!0}};return{command:B[0]??"help",args:B.slice(1),flags:{model:qX(Q,"model"),domain:qX(Q,"domain"),"content-repo":qX(Q,"content-repo"),backend:qX(Q,"backend"),"push-to":qX(Q,"push-to"),"ai-api-key":qX(Q,"ai-api-key"),"no-interactive":Xq(Q,"no-interactive"),preview:Xq(Q,"preview"),deploy:Xq(Q,"deploy"),regen:Xq(Q,"regen"),all:Xq(Q,"all"),only:qX(Q,"only"),"dry-run":Xq(Q,"dry-run"),"startup-check":Xq(Q,"startup-check"),"storage-dir":qX(Q,"storage-dir"),yes:Xq(Q,"yes"),remote:qX(Q,"remote"),token:qX(Q,"token"),outputDir:qX(Q,"outputDir")}}}mr();import{mkdirSync as sgQ}from"fs";import{join as agQ}from"path";import{execSync as tgQ}from"child_process";var z7A={name:"@rizom/brain",version:"0.2.0-alpha.127",description:"Brain runtime + CLI \u2014 scaffold, run, and manage AI brain instances",type:"module",bin:{brain:"./dist/brain.js"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./cli":"./dist/brain.js","./plugins":{types:"./dist/plugins.d.ts",import:"./dist/plugins.js"},"./entities":{types:"./dist/entities.d.ts",import:"./dist/entities.js"},"./services":{types:"./dist/services.d.ts",import:"./dist/services.js"},"./interfaces":{types:"./dist/interfaces.d.ts",import:"./dist/interfaces.js"},"./templates":{types:"./dist/templates.d.ts",import:"./dist/templates.js"},"./site":{types:"./dist/site.d.ts",import:"./dist/site.js"},"./themes":{types:"./dist/themes.d.ts",import:"./dist/themes.js"},"./deploy":{types:"./dist/deploy.d.ts",import:"./dist/deploy.js"},"./tsconfig.instance.json":"./tsconfig.instance.json"},files:["dist","templates","tsconfig.instance.json"],scripts:{build:"bun scripts/build.ts",prepublishOnly:"bun scripts/build.ts","dev:start":"bun scripts/build.ts && bun dist/brain.js start",typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts"},dependencies:{"@clack/prompts":"^0.11.0","@modelcontextprotocol/sdk":"^1.24.0","@tailwindcss/postcss":"^4.1.13","@tailwindcss/typography":"^0.5.19",postcss:"^8.5.6",preact:"^10.27.2","preact-render-to-string":"^6.3.1",tailwindcss:"^4.1.11"},optionalDependencies:{"@bitwarden/sdk-napi":"^1.0.0","@libsql/client":"^0.15.7","@tailwindcss/oxide":"^4.1.4","better-sqlite3":"^11.8.1",lightningcss:"^1.29.2","playwright-core":"^1.56.0","react-devtools-core":"^6.1.1",sharp:"^0.34.5"},devDependencies:{"@brains/app":"workspace:*","@brains/content-formatters":"workspace:*","@brains/deploy-support":"workspace:*","@brains/eslint-config":"workspace:*","@brains/mcp-service":"workspace:*","@brains/plugins":"workspace:*","@brains/ranger":"workspace:*","@brains/relay":"workspace:*","@brains/rover":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-default":"workspace:*","@brains/site-personal":"workspace:*","@brains/site-professional":"workspace:*","@brains/theme-default":"workspace:*","@brains/theme-rizom":"workspace:*","@brains/typescript-config":"workspace:*","@brains/utils":"workspace:*","@types/bun":"latest",rollup:"^4.60.2","rollup-plugin-dts":"^6.4.1",typescript:"^5.3.3"},publishConfig:{access:"public"},repository:{type:"git",url:"https://github.com/rizom-ai/brains.git",directory:"packages/brain-cli"},license:"Apache-2.0",author:"Yeehaa <yeehaa@rizom.ai> (https://rizom.ai)",homepage:"https://github.com/rizom-ai/brains/tree/main/packages/brain-cli#readme",bugs:"https://github.com/rizom-ai/brains/issues",engines:{bun:">=1.3.3"},keywords:["brain","ai","cli","mcp","agent","personal-ai","knowledge-management"]};import{mkdirSync as sM1,writeFileSync as cr,chmodSync as lr,existsSync as kcA,readFileSync as jcA}from"fs";import{basename as _cA,dirname as vcA,join as D6,resolve as XxQ}from"path";import{fileURLToPath as WxQ}from"url";var xM1=`ARG BUN_VERSION=1.3.10
|
|
11668
11668
|
FROM oven/bun:\${BUN_VERSION}-slim AS runtime
|
|
11669
11669
|
|
|
11670
11670
|
WORKDIR /app
|