@rizom/brain 0.2.0-alpha.154 → 0.2.0-alpha.155

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.
@@ -376,7 +376,7 @@
376
376
  "import { ServicePlugin as RuntimeServicePlugin } from \"../service/service-plugin\";\nimport type { ServicePluginContext as RuntimeServicePluginContext } from \"../service/context\";\nimport type { PluginConfigSchema } from \"../config\";\nimport type {\n IShell,\n PluginCapabilities,\n PluginRegistrationContext,\n} from \"../interfaces\";\nimport type { Plugin, Resource, ServicePluginContext, Tool } from \"./types\";\n\ninterface ServicePluginHooks {\n onRegister(context: ServicePluginContext): Promise<void>;\n onReady(context: ServicePluginContext): Promise<void>;\n onShutdown(): Promise<void>;\n getTools(): Promise<Tool[]>;\n getResources(): Promise<Resource[]>;\n getInstructions(): Promise<string | undefined>;\n}\n\nclass ServicePluginDelegate<TConfig, TConfigInput> extends RuntimeServicePlugin<\n TConfig,\n TConfigInput\n> {\n private readonly hooks: ServicePluginHooks;\n constructor(\n id: string,\n packageJson: { name: string; version: string; description?: string },\n config: TConfigInput,\n configSchema: PluginConfigSchema<TConfig>,\n hooks: ServicePluginHooks,\n ) {\n super(id, packageJson, config, configSchema);\n this.hooks = hooks;\n }\n\n protected override onRegister(\n context: RuntimeServicePluginContext,\n ): Promise<void> {\n return this.hooks.onRegister(context);\n }\n\n protected override onReady(\n context: RuntimeServicePluginContext,\n ): Promise<void> {\n return this.hooks.onReady(context);\n }\n\n protected override onShutdown(): Promise<void> {\n return this.hooks.onShutdown();\n }\n\n protected override getTools(): Promise<never[]> {\n return this.hooks.getTools() as Promise<never[]>;\n }\n\n protected override getResources(): Promise<never[]> {\n return this.hooks.getResources() as Promise<never[]>;\n }\n\n protected override getInstructions(): Promise<string | undefined> {\n return this.hooks.getInstructions();\n }\n}\n\nexport abstract class ServicePlugin<TConfig, TConfigInput> implements Plugin {\n public readonly type = \"service\" as const;\n public readonly id: string;\n public readonly version: string;\n public readonly packageName: string;\n public readonly description?: string;\n private readonly delegate: ServicePluginDelegate<TConfig, TConfigInput>;\n\n protected constructor(\n id: string,\n packageJson: { name: string; version: string; description?: string },\n config: TConfigInput,\n configSchema: PluginConfigSchema<TConfig>,\n ) {\n this.id = id;\n this.version = packageJson.version;\n this.packageName = packageJson.name;\n if (packageJson.description !== undefined) {\n this.description = packageJson.description;\n }\n this.delegate = new ServicePluginDelegate(\n id,\n packageJson,\n config,\n configSchema,\n {\n onRegister: (context): Promise<void> => this.onRegister(context),\n onReady: (context): Promise<void> => this.onReady(context),\n onShutdown: (): Promise<void> => this.onShutdown(),\n getTools: (): Promise<Tool[]> => this.getTools(),\n getResources: (): Promise<Resource[]> => this.getResources(),\n getInstructions: (): Promise<string | undefined> =>\n this.getInstructions(),\n },\n );\n }\n\n /** @internal */\n register(\n shell: IShell,\n context?: PluginRegistrationContext,\n ): Promise<PluginCapabilities> {\n return this.delegate.register(shell, context);\n }\n\n protected async onRegister(_context: ServicePluginContext): Promise<void> {}\n protected async onReady(_context: ServicePluginContext): Promise<void> {}\n protected async onShutdown(): Promise<void> {}\n protected async getTools(): Promise<Tool[]> {\n return [];\n }\n protected async getResources(): Promise<Resource[]> {\n return [];\n }\n protected async getInstructions(): Promise<string | undefined> {\n return undefined;\n }\n\n ready(): Promise<void> {\n return this.delegate.ready();\n }\n\n shutdown(): Promise<void> {\n return this.delegate.shutdown?.() ?? Promise.resolve();\n }\n}\n",
377
377
  "import { z } from \"@brains/utils/zod\";\nimport {\n conversationMessageActorSchema,\n conversationMessageSourceSchema,\n} from \"@brains/conversation-service\";\nimport type { AgentResponse } from \"@brains/contracts\";\nexport {\n ActionsCardSchema,\n AgentResponseSchema,\n AttachmentCardDataSchema,\n AttachmentCardSchema,\n AttachmentCardSourceSchema,\n ChatActionSchema,\n EventChatActionSchema,\n PendingConfirmationSchema,\n PromptChatActionSchema,\n SourceCitationSchema,\n SourcesCardSchema,\n StructuredChatCardSchema,\n ToolApprovalCardSchema,\n ToolApprovalCardStateSchema,\n ToolResultDataSchema,\n} from \"@brains/contracts\";\nexport type {\n ActionsCard,\n AgentResponse,\n AttachmentCard,\n AttachmentCardData,\n AttachmentCardSource,\n ChatAction,\n EventChatAction,\n PendingConfirmation,\n PromptChatAction,\n SourceCitation,\n SourcesCard,\n StructuredChatCard,\n ToolApprovalCard,\n ToolApprovalCardState,\n ToolResultData,\n} from \"@brains/contracts\";\n\nexport const ChatAttachmentSourceSchema: z.ZodObject<{\n kind: z.ZodString;\n id: z.ZodString;\n}> = z.object({\n kind: z.string().min(1),\n id: z.string().min(1),\n});\n\nexport const TextChatAttachmentSchema: z.ZodObject<{\n kind: z.ZodLiteral<\"text\">;\n filename: z.ZodString;\n mediaType: z.ZodString;\n content: z.ZodString;\n sizeBytes: z.ZodOptional<z.ZodNumber>;\n source: z.ZodOptional<typeof ChatAttachmentSourceSchema>;\n}> = z.object({\n kind: z.literal(\"text\"),\n filename: z.string().min(1),\n mediaType: z.string().min(1),\n content: z.string(),\n sizeBytes: z.number().nonnegative().optional(),\n source: ChatAttachmentSourceSchema.optional(),\n});\n\nconst fileAttachmentDataSchema: z.ZodType<Uint8Array, unknown> =\n z.custom<Uint8Array>((value) => value instanceof Uint8Array);\n\nexport const FileChatAttachmentSchema: z.ZodObject<{\n kind: z.ZodLiteral<\"file\">;\n filename: z.ZodString;\n mediaType: z.ZodString;\n data: typeof fileAttachmentDataSchema;\n sizeBytes: z.ZodOptional<z.ZodNumber>;\n source: z.ZodOptional<typeof ChatAttachmentSourceSchema>;\n}> = z.object({\n kind: z.literal(\"file\"),\n filename: z.string().min(1),\n mediaType: z.string().min(1),\n data: fileAttachmentDataSchema,\n sizeBytes: z.number().nonnegative().optional(),\n source: ChatAttachmentSourceSchema.optional(),\n});\n\nexport const ChatAttachmentSchema: z.ZodDiscriminatedUnion<\n [typeof TextChatAttachmentSchema, typeof FileChatAttachmentSchema],\n \"kind\"\n> = z.discriminatedUnion(\"kind\", [\n TextChatAttachmentSchema,\n FileChatAttachmentSchema,\n]);\n\nexport type ChatAttachment = z.output<typeof ChatAttachmentSchema>;\n\nexport interface ChatContext {\n userPermissionLevel?: \"anchor\" | \"trusted\" | \"public\" | undefined;\n interfaceType?: string | undefined;\n channelId?: string | undefined;\n channelName?: string | undefined;\n actor?:\n | {\n actorId: string;\n canonicalId?: string | undefined;\n interfaceType: string;\n role: \"user\" | \"assistant\";\n displayName?: string | undefined;\n username?: string | undefined;\n isBot?: boolean | undefined;\n }\n | undefined;\n source?:\n | {\n messageId?: string | undefined;\n channelId?: string | undefined;\n channelName?: string | undefined;\n threadId?: string | undefined;\n metadata?: Record<string, unknown> | undefined;\n }\n | undefined;\n attachments?: ChatAttachment[] | undefined;\n}\n\nexport const ChatContextSchema: z.ZodType<ChatContext, unknown> = z.object({\n userPermissionLevel: z.enum([\"anchor\", \"trusted\", \"public\"]).optional(),\n interfaceType: z.string().optional(),\n channelId: z.string().optional(),\n channelName: z.string().optional(),\n actor: conversationMessageActorSchema.optional(),\n source: conversationMessageSourceSchema.optional(),\n attachments: z.array(ChatAttachmentSchema).optional(),\n});\n\nexport interface AgentNamespace {\n chat(\n message: string,\n conversationId: string,\n context?: ChatContext,\n ): Promise<AgentResponse>;\n confirmPendingAction(\n conversationId: string,\n confirmed: boolean,\n approvalId: string,\n context: ChatContext,\n ): Promise<AgentResponse>;\n invalidate(): void;\n}\n",
378
378
  "import { z } from \"@brains/utils/zod\";\n\n/**\n * Daemon health status schema\n */\nexport const DaemonHealthSchema: z.ZodObject<{\n status: z.ZodEnum<{\n healthy: \"healthy\";\n warning: \"warning\";\n error: \"error\";\n unknown: \"unknown\";\n }>;\n message: z.ZodOptional<z.ZodString>;\n lastCheck: z.ZodOptional<z.ZodDate>;\n details: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;\n}> = z.object({\n status: z.enum([\"healthy\", \"warning\", \"error\", \"unknown\"]),\n message: z.string().optional(),\n lastCheck: z.date().optional(),\n details: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type DaemonHealth = z.output<typeof DaemonHealthSchema>;\n\n/**\n * Daemon status info schema for validation\n */\nexport const DaemonStatusInfoSchema: z.ZodObject<{\n name: z.ZodString;\n pluginId: z.ZodString;\n status: z.ZodString;\n health: z.ZodOptional<typeof DaemonHealthSchema>;\n}> = z.object({\n name: z.string(),\n pluginId: z.string(),\n status: z.string(),\n health: DaemonHealthSchema.optional(),\n});\n\nexport type DaemonStatusInfo = z.output<typeof DaemonStatusInfoSchema>;\n\n/**\n * Daemon interface for long-running interface processes\n */\nexport interface Daemon {\n /**\n * Start the daemon - called when plugin is initialized\n */\n start: () => Promise<void>;\n\n /**\n * Stop the daemon - called when plugin is unloaded/shutdown\n */\n stop: () => Promise<void>;\n\n /**\n * Optional health check - called periodically to monitor daemon health\n */\n healthCheck?: () => Promise<DaemonHealth>;\n}\n\n/**\n * Information about a registered daemon\n */\nexport interface DaemonInfo {\n name: string;\n daemon: Daemon;\n pluginId: string;\n status: \"stopped\" | \"starting\" | \"running\" | \"stopping\" | \"error\";\n health?: DaemonHealth;\n error?: Error;\n startedAt?: Date;\n stoppedAt?: Date;\n}\n\n/**\n * Interface for DaemonRegistry — used by plugins to avoid circular dep with core\n */\nexport interface IDaemonRegistry {\n register(name: string, daemon: Daemon, pluginId: string): void;\n has(name: string): boolean;\n get(name: string): DaemonInfo | undefined;\n start(name: string): Promise<void>;\n stop(name: string): Promise<void>;\n checkHealth(name: string): Promise<DaemonHealth | undefined>;\n getByPlugin(pluginId: string): DaemonInfo[];\n getAll(): string[];\n getAllInfo(): DaemonInfo[];\n getStatuses(): Promise<DaemonStatusInfo[]>;\n unregister(name: string): Promise<void>;\n startPlugin(pluginId: string): Promise<void>;\n stopPlugin(pluginId: string): Promise<void>;\n clear(): Promise<void>;\n}\n",
379
- "import type { IMessageBus, MessageResponse } from \"@brains/messaging-service\";\nimport { PermissionService, type UserPermissionLevel } from \"@brains/templates\";\nimport { type Logger } from \"@brains/utils/logger\";\nimport { z } from \"@brains/utils/zod\";\nimport {\n McpServer,\n ResourceTemplate as MCPResourceTemplate,\n} from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ToolAnnotations } from \"@modelcontextprotocol/sdk/types.js\";\nimport type {\n MCPProtocolMode,\n Prompt,\n Resource,\n ResourceTemplate,\n Tool,\n} from \"./types\";\nimport { normalizeToolExecutionMessageResponse } from \"./tool-response-validation\";\n\nconst MCP_SERVER_INFO = {\n name: \"brain-mcp\",\n version: \"1.0.0\",\n};\n\nconst DEFAULT_TOOL_VISIBILITY: UserPermissionLevel = \"anchor\";\nconst RESOURCE_VISIBILITY: UserPermissionLevel = \"anchor\";\nconst DEFAULT_PROMPT_VISIBILITY: UserPermissionLevel = \"anchor\";\n\nexport interface RegisteredTool {\n pluginId: string;\n tool: Tool;\n}\n\nexport interface RegisteredResource {\n pluginId: string;\n resource: Resource;\n}\n\nexport interface RegisteredTemplate {\n pluginId: string;\n template: ResourceTemplate;\n}\n\nexport interface RegisteredPrompt {\n pluginId: string;\n prompt: Prompt;\n}\n\nexport function createMcpServerInstance(): McpServer {\n return new McpServer(MCP_SERVER_INFO);\n}\n\nexport function canExposeTool(\n permissionLevel: UserPermissionLevel,\n tool: Tool,\n): boolean {\n return PermissionService.hasPermission(\n permissionLevel,\n tool.visibility ?? DEFAULT_TOOL_VISIBILITY,\n );\n}\n\nexport function canExposeToolOnProtocol(\n permissionLevel: UserPermissionLevel,\n tool: Tool,\n mode: MCPProtocolMode,\n): boolean {\n if (!canExposeTool(permissionLevel, tool)) {\n return false;\n }\n\n if (mode === \"debug\") {\n return true;\n }\n\n return (\n isReadOnlyTool(tool) || tool.name === \"chat\" || tool.name === \"confirm\"\n );\n}\n\nexport function canExposeResource(\n permissionLevel: UserPermissionLevel,\n): boolean {\n return PermissionService.hasPermission(permissionLevel, RESOURCE_VISIBILITY);\n}\n\n/**\n * Resource templates expose entity listing/completion that can leak entity\n * existence even when handler output is filtered by visibility. Pin them to\n * the same anchor-only policy as plain resources.\n */\nexport function canExposeResourceTemplate(\n permissionLevel: UserPermissionLevel,\n): boolean {\n return PermissionService.hasPermission(permissionLevel, RESOURCE_VISIBILITY);\n}\n\n/**\n * Prompts ship as anchor-only by default because their bodies can reference\n * restricted workflows, entity names, or operator instructions. Plugins can\n * opt a prompt down to \"trusted\" / \"public\" if its template is safe to share.\n */\nexport function canExposePrompt(\n permissionLevel: UserPermissionLevel,\n prompt: Prompt,\n): boolean {\n return PermissionService.hasPermission(\n permissionLevel,\n prompt.visibility ?? DEFAULT_PROMPT_VISIBILITY,\n );\n}\n\nexport function filterToolsForPermission(\n tools: RegisteredTool[],\n userLevel: UserPermissionLevel,\n): RegisteredTool[] {\n return tools.filter(({ tool }) => canExposeTool(userLevel, tool));\n}\n\nexport function getToolAnnotations(tool: Tool): ToolAnnotations | undefined {\n if (tool.annotations) {\n return tool.annotations;\n }\n\n if (tool.sideEffects === \"none\") {\n return {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n };\n }\n\n if (tool.sideEffects === \"writes\") {\n return {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n };\n }\n\n if (tool.sideEffects === \"external\") {\n return {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n };\n }\n\n return undefined;\n}\n\nexport function isReadOnlyTool(tool: Tool): boolean {\n return getToolAnnotations(tool)?.readOnlyHint === true;\n}\n\nexport function serializeMessageResponse(response: MessageResponse): string {\n if (\"success\" in response && !response.success) {\n throw new Error(response.error ?? \"Operation failed\");\n }\n return JSON.stringify(\"data\" in response ? response.data : response, null, 2);\n}\n\nexport function registerToolOnServer(\n server: McpServer,\n pluginId: string,\n tool: Tool,\n messageBus: IMessageBus,\n logger: Logger,\n permissionLevel: UserPermissionLevel,\n): void {\n server.tool(\n tool.name,\n tool.description,\n tool.inputSchema,\n getToolAnnotations(tool) ?? {},\n async (params, extra) => {\n const interfaceType = extra._meta?.[\"interfaceType\"] ?? \"mcp\";\n const userId = extra._meta?.[\"userId\"] ?? \"mcp-user\";\n const conversationId = extra._meta?.[\"conversationId\"];\n const channelId = extra._meta?.[\"channelId\"];\n const channelName = extra._meta?.[\"channelName\"];\n const progressToken = extra._meta?.progressToken;\n\n logger.debug(\"MCP client metadata\", {\n tool: tool.name,\n pluginId,\n interfaceType,\n userId,\n conversationId,\n channelId,\n channelName,\n progressToken,\n userPermissionLevel: permissionLevel,\n });\n\n try {\n const response = await messageBus.send({\n type: `plugin:${pluginId}:tool:execute`,\n payload: {\n toolName: tool.name,\n args: params,\n progressToken,\n hasProgress: progressToken !== undefined,\n interfaceType,\n userId,\n conversationId,\n channelId,\n channelName,\n userPermissionLevel: permissionLevel,\n },\n sender: \"MCPService\",\n });\n const normalizedResponse = normalizeToolExecutionMessageResponse(\n response,\n {\n pluginId,\n toolName: tool.name,\n logger,\n },\n );\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: serializeMessageResponse(normalizedResponse),\n },\n ],\n };\n } catch (error) {\n logger.error(`Tool execution error for ${tool.name}`, error);\n throw error;\n }\n },\n );\n}\n\nexport function registerResourceOnServer(\n server: McpServer,\n resource: Resource,\n): void {\n server.resource(\n resource.name,\n resource.uri,\n { description: resource.description, mimeType: resource.mimeType },\n async () => resource.handler(),\n );\n}\n\nexport function registerResourceTemplateOnServer(\n server: McpServer,\n template: ResourceTemplate,\n): void {\n const listFn = template.list;\n\n const sdkTemplate = new MCPResourceTemplate(template.uriTemplate, {\n list: listFn\n ? async (): Promise<{\n resources: Array<{ uri: string; name: string }>;\n }> => ({\n resources: (await listFn()).map((r) => ({\n uri: r.uri,\n name: r.name,\n })),\n })\n : undefined,\n ...(template.complete && {\n complete: Object.fromEntries(\n Object.entries(template.complete).map(([k, fn]) => [\n k,\n (\n value: string,\n context?: { arguments?: Record<string, string> },\n ): string[] | Promise<string[]> => fn(value, context),\n ]),\n ),\n }),\n });\n\n server.registerResource(\n template.name,\n sdkTemplate,\n { description: template.description, mimeType: template.mimeType },\n async (_uri, vars) => {\n const flatVars: Record<string, string> = {};\n for (const [k, v] of Object.entries(vars)) {\n flatVars[k] = Array.isArray(v) ? (v[0] ?? \"\") : v;\n }\n return template.handler(flatVars);\n },\n );\n}\n\nexport function registerPromptOnServer(\n server: McpServer,\n prompt: Prompt,\n): void {\n const argsSchema = Object.fromEntries(\n Object.entries(prompt.args).map(([key, arg]) => [\n key,\n arg.required\n ? z.string().describe(arg.description)\n : z.string().optional().describe(arg.description),\n ]),\n );\n\n server.prompt(\n prompt.name,\n prompt.description ?? \"Prompt\",\n argsSchema,\n async (args) => prompt.handler(args as Record<string, string>),\n );\n}\n",
379
+ "import type { IMessageBus, MessageResponse } from \"@brains/messaging-service\";\nimport { PermissionService, type UserPermissionLevel } from \"@brains/templates\";\nimport { type Logger } from \"@brains/utils/logger\";\nimport { z } from \"@brains/utils/zod\";\nimport {\n McpServer,\n ResourceTemplate as MCPResourceTemplate,\n} from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ToolAnnotations } from \"@modelcontextprotocol/sdk/types.js\";\nimport type {\n MCPProtocolMode,\n Prompt,\n Resource,\n ResourceTemplate,\n Tool,\n} from \"./types\";\nimport { normalizeToolExecutionMessageResponse } from \"./tool-response-validation\";\n\nconst MCP_SERVER_INFO = {\n name: \"brain-mcp\",\n version: \"1.0.0\",\n};\n\nconst DEFAULT_TOOL_VISIBILITY: UserPermissionLevel = \"anchor\";\nconst RESOURCE_VISIBILITY: UserPermissionLevel = \"anchor\";\nconst DEFAULT_PROMPT_VISIBILITY: UserPermissionLevel = \"anchor\";\n\nexport interface RegisteredTool {\n pluginId: string;\n tool: Tool;\n}\n\nexport interface RegisteredResource {\n pluginId: string;\n resource: Resource;\n}\n\nexport interface RegisteredTemplate {\n pluginId: string;\n template: ResourceTemplate;\n}\n\nexport interface RegisteredPrompt {\n pluginId: string;\n prompt: Prompt;\n}\n\nexport function createMcpServerInstance(): McpServer {\n return new McpServer(MCP_SERVER_INFO);\n}\n\nexport function canExposeTool(\n permissionLevel: UserPermissionLevel,\n tool: Tool,\n): boolean {\n return PermissionService.hasPermission(\n permissionLevel,\n tool.visibility ?? DEFAULT_TOOL_VISIBILITY,\n );\n}\n\nexport function canExposeToolOnProtocol(\n permissionLevel: UserPermissionLevel,\n tool: Tool,\n mode: MCPProtocolMode,\n): boolean {\n if (!canExposeTool(permissionLevel, tool)) {\n return false;\n }\n\n if (mode === \"debug\") {\n return true;\n }\n\n return (\n isReadOnlyTool(tool) || tool.name === \"chat\" || tool.name === \"confirm\"\n );\n}\n\nexport function canExposeResource(\n permissionLevel: UserPermissionLevel,\n): boolean {\n return PermissionService.hasPermission(permissionLevel, RESOURCE_VISIBILITY);\n}\n\n/**\n * Resource templates expose entity listing/completion that can leak entity\n * existence even when handler output is filtered by visibility. Pin them to\n * the same anchor-only policy as plain resources.\n */\nexport function canExposeResourceTemplate(\n permissionLevel: UserPermissionLevel,\n): boolean {\n return PermissionService.hasPermission(permissionLevel, RESOURCE_VISIBILITY);\n}\n\n/**\n * Prompts ship as anchor-only by default because their bodies can reference\n * restricted workflows, entity names, or operator instructions. Plugins can\n * opt a prompt down to \"trusted\" / \"public\" if its template is safe to share.\n */\nexport function canExposePrompt(\n permissionLevel: UserPermissionLevel,\n prompt: Prompt,\n): boolean {\n return PermissionService.hasPermission(\n permissionLevel,\n prompt.visibility ?? DEFAULT_PROMPT_VISIBILITY,\n );\n}\n\nexport function filterToolsForPermission(\n tools: RegisteredTool[],\n userLevel: UserPermissionLevel,\n): RegisteredTool[] {\n return tools.filter(({ tool }) => canExposeTool(userLevel, tool));\n}\n\nexport function getToolAnnotations(tool: Tool): ToolAnnotations | undefined {\n if (tool.annotations) {\n return tool.annotations;\n }\n\n if (tool.sideEffects === \"none\") {\n return {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n };\n }\n\n if (tool.sideEffects === \"writes\") {\n return {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n };\n }\n\n if (tool.sideEffects === \"external\") {\n return {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n };\n }\n\n return undefined;\n}\n\nexport function isReadOnlyTool(tool: Tool): boolean {\n return getToolAnnotations(tool)?.readOnlyHint === true;\n}\n\nexport function serializeMessageResponse(response: MessageResponse): string {\n if (\"success\" in response && !response.success) {\n throw new Error(response.error ?? \"Operation failed\");\n }\n return JSON.stringify(\"data\" in response ? response.data : response, null, 2);\n}\n\nexport function registerToolOnServer(\n server: McpServer,\n pluginId: string,\n tool: Tool,\n messageBus: IMessageBus,\n logger: Logger,\n permissionLevel: UserPermissionLevel,\n): void {\n server.tool(\n tool.name,\n tool.description,\n tool.inputSchema,\n getToolAnnotations(tool) ?? {},\n async (params, extra) => {\n const interfaceType = extra._meta?.[\"interfaceType\"] ?? \"mcp\";\n const verifiedSubject = extra.authInfo?.extra?.[\"subject\"];\n const userId =\n (typeof verifiedSubject === \"string\" && verifiedSubject.length > 0\n ? verifiedSubject\n : undefined) ??\n extra._meta?.[\"userId\"] ??\n \"mcp-user\";\n const conversationId = extra._meta?.[\"conversationId\"];\n const channelId = extra._meta?.[\"channelId\"];\n const channelName = extra._meta?.[\"channelName\"];\n const progressToken = extra._meta?.progressToken;\n\n logger.debug(\"MCP client metadata\", {\n tool: tool.name,\n pluginId,\n interfaceType,\n userId,\n conversationId,\n channelId,\n channelName,\n progressToken,\n userPermissionLevel: permissionLevel,\n });\n\n try {\n const response = await messageBus.send({\n type: `plugin:${pluginId}:tool:execute`,\n payload: {\n toolName: tool.name,\n args: params,\n progressToken,\n hasProgress: progressToken !== undefined,\n interfaceType,\n userId,\n conversationId,\n channelId,\n channelName,\n userPermissionLevel: permissionLevel,\n },\n sender: \"MCPService\",\n });\n const normalizedResponse = normalizeToolExecutionMessageResponse(\n response,\n {\n pluginId,\n toolName: tool.name,\n logger,\n },\n );\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: serializeMessageResponse(normalizedResponse),\n },\n ],\n };\n } catch (error) {\n logger.error(`Tool execution error for ${tool.name}`, error);\n throw error;\n }\n },\n );\n}\n\nexport function registerResourceOnServer(\n server: McpServer,\n resource: Resource,\n): void {\n server.resource(\n resource.name,\n resource.uri,\n { description: resource.description, mimeType: resource.mimeType },\n async () => resource.handler(),\n );\n}\n\nexport function registerResourceTemplateOnServer(\n server: McpServer,\n template: ResourceTemplate,\n): void {\n const listFn = template.list;\n\n const sdkTemplate = new MCPResourceTemplate(template.uriTemplate, {\n list: listFn\n ? async (): Promise<{\n resources: Array<{ uri: string; name: string }>;\n }> => ({\n resources: (await listFn()).map((r) => ({\n uri: r.uri,\n name: r.name,\n })),\n })\n : undefined,\n ...(template.complete && {\n complete: Object.fromEntries(\n Object.entries(template.complete).map(([k, fn]) => [\n k,\n (\n value: string,\n context?: { arguments?: Record<string, string> },\n ): string[] | Promise<string[]> => fn(value, context),\n ]),\n ),\n }),\n });\n\n server.registerResource(\n template.name,\n sdkTemplate,\n { description: template.description, mimeType: template.mimeType },\n async (_uri, vars) => {\n const flatVars: Record<string, string> = {};\n for (const [k, v] of Object.entries(vars)) {\n flatVars[k] = Array.isArray(v) ? (v[0] ?? \"\") : v;\n }\n return template.handler(flatVars);\n },\n );\n}\n\nexport function registerPromptOnServer(\n server: McpServer,\n prompt: Prompt,\n): void {\n const argsSchema = Object.fromEntries(\n Object.entries(prompt.args).map(([key, arg]) => [\n key,\n arg.required\n ? z.string().describe(arg.description)\n : z.string().optional().describe(arg.description),\n ]),\n );\n\n server.prompt(\n prompt.name,\n prompt.description ?? \"Prompt\",\n argsSchema,\n async (args) => prompt.handler(args as Record<string, string>),\n );\n}\n",
380
380
  "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ToolAnnotations } from \"@modelcontextprotocol/sdk/types.js\";\nimport { type ProgressNotification } from \"@brains/utils/progress\";\nimport { z, type ZodRawShape } from \"@brains/utils/zod\";\nimport type { UserPermissionLevel } from \"@brains/templates\";\n\n/**\n * Tool visibility levels for permission control\n * Uses the same levels as UserPermissionLevel for consistency\n */\nexport type ToolVisibility = UserPermissionLevel;\n\n/**\n * Tool execution context\n * Provides progress reporting and routing metadata\n */\nexport interface ToolContext {\n // Progress reporting\n progressToken?: string | number;\n sendProgress?: (notification: ProgressNotification) => Promise<void>;\n\n // Routing metadata for job creation (required for proper context propagation)\n interfaceType: string; // Which interface called the tool (e.g., \"mcp\", \"cli\", \"matrix\")\n userId: string; // User who invoked the tool\n conversationId?: string; // Durable conversation/session id for conversation-scoped tools when available\n channelId?: string; // Transport channel/room context (for Matrix, etc.)\n channelName?: string; // Human-readable channel name (for display)\n runId?: string; // Runtime workflow/playbook run context when available\n toolCallId?: string; // AI SDK tool call id when invoked by an agent\n /** Caller's permission level. Tools that read/write entities use this to derive\n * the content-visibility scope they are allowed to see. */\n userPermissionLevel?: UserPermissionLevel;\n}\n\nexport interface ToolContextRouting {\n interfaceType: string;\n userId: string;\n conversationId?: string | undefined;\n channelId?: string | undefined;\n channelName?: string | undefined;\n runId?: string | undefined;\n toolCallId?: string | undefined;\n userPermissionLevel?: UserPermissionLevel | undefined;\n}\n\ninterface ToolContextRoutingSchemaShape extends ZodRawShape {\n interfaceType: z.ZodString;\n userId: z.ZodString;\n conversationId: z.ZodOptional<z.ZodString>;\n channelId: z.ZodOptional<z.ZodString>;\n channelName: z.ZodOptional<z.ZodString>;\n runId: z.ZodOptional<z.ZodString>;\n toolCallId: z.ZodOptional<z.ZodString>;\n userPermissionLevel: z.ZodOptional<\n z.ZodEnum<{\n anchor: \"anchor\";\n trusted: \"trusted\";\n public: \"public\";\n }>\n >;\n}\n\n/**\n * Schema for ToolContext routing metadata\n * Used to validate routing information in tool execution requests\n */\nexport const ToolContextRoutingSchema: z.ZodObject<ToolContextRoutingSchemaShape> =\n z.object({\n interfaceType: z.string(),\n userId: z.string(),\n conversationId: z.string().optional(),\n channelId: z.string().optional(),\n channelName: z.string().optional(),\n runId: z.string().optional(),\n toolCallId: z.string().optional(),\n userPermissionLevel: z.enum([\"anchor\", \"trusted\", \"public\"]).optional(),\n });\n\nexport interface ToolSuccessResponse {\n success: true;\n data?: unknown;\n message?: string | undefined;\n cached?: true | undefined;\n}\n\n/**\n * Success response schema\n */\nexport const toolSuccessSchema: z.ZodType<ToolSuccessResponse> = z.strictObject(\n {\n success: z.literal(true),\n data: z.unknown().optional(),\n message: z.string().optional(),\n cached: z.literal(true).optional(),\n },\n);\n\nexport interface ToolErrorResponse {\n success: false;\n error: string;\n code?: string | undefined;\n}\n\n/**\n * Error response schema\n */\nexport const toolErrorSchema: z.ZodType<ToolErrorResponse> = z.strictObject({\n success: z.literal(false),\n error: z.string(),\n code: z.string().optional(),\n});\n\n/**\n * Confirmation response schema\n * Tools return this when an operation needs user approval.\n * The agent service detects this shape and enters the confirmation flow.\n */\nexport interface ToolConfirmation {\n needsConfirmation: true;\n toolName: string;\n summary: string;\n completionSummary?: string | undefined;\n preview?: string | undefined;\n args: unknown;\n}\n\nexport const toolConfirmationSchema: z.ZodType<ToolConfirmation> =\n z.strictObject({\n needsConfirmation: z.literal(true),\n toolName: z.string(),\n summary: z.string(),\n completionSummary: z.string().optional(),\n preview: z.string().optional(),\n args: z.unknown(),\n });\n\n/**\n * Standardized tool response schema\n * All tools return one of: success, error, or confirmation request.\n */\nexport type ToolResponse =\n ToolSuccessResponse | ToolErrorResponse | ToolConfirmation;\n\nexport const toolResponseSchema: z.ZodType<ToolResponse> = z.union([\n toolSuccessSchema,\n toolErrorSchema,\n toolConfirmationSchema,\n]);\n\nexport type ToolSideEffects = \"none\" | \"writes\" | \"external\";\nexport type ToolInputSchema = ZodRawShape;\nexport type ToolOutputSchema = z.ZodType;\nexport type MCPProtocolMode = \"basic\" | \"debug\";\n\n/**\n * Tool definition\n * @template TOutput - The output type, defaults to ToolResponse for backward compatibility\n */\nexport interface Tool<TOutput = ToolResponse> {\n name: string;\n description: string;\n inputSchema: ToolInputSchema;\n outputSchema?: ToolOutputSchema; // Optional: Zod schema for type-safe outputs\n handler: (input: unknown, context: ToolContext) => Promise<TOutput>;\n visibility?: ToolVisibility; // Default: \"anchor\" for safety - only explicitly marked tools are public\n /** Declares whether this tool is safe to repeat/cache within one model turn. Undefined defaults to not cacheable. */\n sideEffects?: ToolSideEffects;\n /** MCP protocol annotations advertised to external clients. Derived from sideEffects when omitted. */\n annotations?: ToolAnnotations;\n /** Optional CLI metadata — makes this tool invocable as a brain CLI command */\n cli?: {\n /** CLI command name (e.g. \"list\", \"sync\", \"build\") */\n name: string;\n };\n}\n\n/**\n * Resource definition\n */\nexport interface Resource {\n uri: string;\n name: string;\n description?: string;\n mimeType?: string;\n handler: () => Promise<{\n contents: Array<{\n text: string;\n uri: string;\n mimeType?: string;\n }>;\n }>;\n}\n\n/**\n * Variables extracted from a URI template.\n * Generic parameter ensures handlers receive typed vars, not loose index signatures.\n */\nexport type ResourceVars<K extends string = string> = { [P in K]: string };\n\n/**\n * A parameterized resource with URI template (e.g. \"entity://{type}/{id}\")\n */\nexport interface ResourceTemplate<K extends string = string> {\n name: string;\n uriTemplate: string;\n description?: string;\n mimeType?: string;\n /** List all concrete resources matching this template (for resources/list) */\n list?: () => Promise<Array<{ uri: string; name: string }>>;\n /** Autocomplete values for template variables (populates client selectors) */\n complete?: Record<\n K,\n (\n value: string,\n context?: { arguments?: Partial<ResourceVars<K>> },\n ) => string[] | Promise<string[]>\n >;\n /** Read a single resource by resolved template variables */\n handler: (vars: ResourceVars<K>) => Promise<{\n contents: Array<{ text: string; uri: string; mimeType?: string }>;\n }>;\n}\n\n/**\n * An MCP prompt — parameterized message template for client prompt pickers\n */\nexport interface Prompt {\n name: string;\n description?: string;\n args: Record<string, { description: string; required?: boolean }>;\n handler: (args: Record<string, string>) => Promise<{\n messages: Array<{\n role: \"user\" | \"assistant\";\n content: { type: \"text\"; text: string };\n }>;\n }>;\n /** Default: \"anchor\" — prompt bodies can reference restricted workflows,\n * so they ship as anchor-only unless explicitly marked. */\n visibility?: ToolVisibility;\n}\n\n/**\n * Minimal interface exposed to transport layers\n * Only provides what's needed to connect transports to the MCP server\n */\nexport interface IMCPTransport {\n /**\n * Get the underlying MCP server for transport layers to connect to\n * Transport layers should import McpServer type from @modelcontextprotocol/sdk directly\n */\n getMcpServer(): McpServer;\n\n /**\n * Create a fresh MCP server instance with all registered tools/resources.\n * Required for Streamable HTTP where each session needs its own server.\n */\n createMcpServer(permissionLevel?: UserPermissionLevel): McpServer;\n\n /**\n * Set the permission level for this transport\n */\n setPermissionLevel(level: UserPermissionLevel): void;\n\n /** Select which registered tools are exposed on the external MCP protocol server. */\n setProtocolMode(mode: MCPProtocolMode): void;\n}\n\n/**\n * Full MCP Service interface for managing tool and resource registration\n * Extends the transport interface with registration capabilities\n */\nexport interface IMCPService extends IMCPTransport {\n /**\n * Register a tool with the MCP server\n */\n registerTool(pluginId: string, tool: Tool): void;\n\n /**\n * Register a resource with the MCP server\n */\n registerResource(pluginId: string, resource: Resource): void;\n\n /**\n * Register a resource template with parameterized URI\n */\n registerResourceTemplate<K extends string = string>(\n pluginId: string,\n template: ResourceTemplate<K>,\n ): void;\n\n /**\n * Register an MCP prompt\n */\n registerPrompt(pluginId: string, prompt: Prompt): void;\n\n /**\n * List all registered tools\n */\n listTools(): Array<{ pluginId: string; tool: Tool }>;\n\n /**\n * List tools that have CLI metadata (invocable as brain CLI commands)\n */\n getCliTools(): Array<{ pluginId: string; tool: Tool }>;\n\n /**\n * List tools filtered by user permission level\n */\n listToolsForPermissionLevel(\n userLevel: UserPermissionLevel,\n ): Array<{ pluginId: string; tool: Tool }>;\n\n /**\n * List all registered resources\n */\n listResources(): Array<{ pluginId: string; resource: Resource }>;\n\n /**\n * Register behavioral instructions from a plugin for the agent system prompt\n */\n registerInstructions(pluginId: string, instructions: string): void;\n\n /**\n * Get all registered plugin instructions\n */\n getInstructions(): string[];\n}\n\n/**\n * Tool registration info\n */\nexport interface ToolInfo {\n name: string;\n description: string;\n pluginId: string;\n}\n",
381
381
  "import type { MessageResponse } from \"@brains/messaging-service\";\nimport { type Logger } from \"@brains/utils/logger\";\nimport { z } from \"@brains/utils/zod\";\nimport { toolResponseSchema, type Tool, type ToolResponse } from \"./types\";\n\ninterface ToolResponseValidationContext {\n pluginId: string;\n toolName: string;\n logger: Logger;\n}\n\nfunction invalidToolResponse(toolName: string): ToolResponse {\n return {\n success: false,\n error: `Tool ${toolName} returned an invalid response shape`,\n };\n}\n\nfunction invalidEnvelopeResponse(\n toolName: string,\n): MessageResponse<ToolResponse> {\n return {\n success: false,\n error: `Tool ${toolName} returned an invalid message response envelope`,\n };\n}\n\n/**\n * Envelope shape returned by message-bus handlers for `plugin:*:tool:execute`.\n * Success branch carries the raw tool response in `data`; error branch is the\n * bus-level failure (e.g. tool not found, payload invalid). Anything else\n * (missing `success`, `noop`, wrong types) is rejected by the union.\n */\nconst toolExecutionEnvelopeSchema = z.union([\n z.looseObject({ success: z.literal(true) }),\n z.object({ success: z.literal(false), error: z.string() }),\n]);\n\nfunction hasEnvelopeData(value: {\n success: true;\n}): value is { success: true; data: unknown } {\n return Object.prototype.hasOwnProperty.call(value, \"data\");\n}\n\nexport function normalizeToolResponse(\n raw: unknown,\n context: ToolResponseValidationContext,\n): ToolResponse {\n const parsed = toolResponseSchema.safeParse(raw);\n\n if (\n parsed.success &&\n \"success\" in parsed.data &&\n parsed.data.success === true &&\n !Object.prototype.hasOwnProperty.call(parsed.data, \"data\")\n ) {\n context.logger.error(\"Tool returned non-compliant response\", {\n pluginId: context.pluginId,\n toolName: context.toolName,\n issues: [{ path: [\"data\"], message: \"Required\" }],\n });\n return invalidToolResponse(context.toolName);\n }\n\n if (parsed.success) {\n return parsed.data;\n }\n\n context.logger.error(\"Tool returned non-compliant response\", {\n pluginId: context.pluginId,\n toolName: context.toolName,\n issues: parsed.error.issues,\n });\n\n return invalidToolResponse(context.toolName);\n}\n\nexport function normalizeToolExecutionMessageResponse(\n response: unknown,\n context: ToolResponseValidationContext,\n): MessageResponse<ToolResponse> {\n const parsed = toolExecutionEnvelopeSchema.safeParse(response);\n\n if (!parsed.success) {\n context.logger.error(\"Tool returned non-compliant message response\", {\n pluginId: context.pluginId,\n toolName: context.toolName,\n response,\n });\n return invalidEnvelopeResponse(context.toolName);\n }\n\n if (!parsed.data.success) {\n return { success: false, error: parsed.data.error };\n }\n\n if (!hasEnvelopeData(parsed.data)) {\n context.logger.error(\"Tool returned non-compliant message response\", {\n pluginId: context.pluginId,\n toolName: context.toolName,\n response,\n });\n return invalidEnvelopeResponse(context.toolName);\n }\n\n return {\n success: true,\n data: normalizeToolResponse(parsed.data.data, context),\n };\n}\n\nexport function wrapToolWithResponseValidation(\n pluginId: string,\n tool: Tool,\n logger: Logger,\n): Tool {\n return {\n ...tool,\n handler: async (input, context): Promise<ToolResponse> => {\n const raw = await tool.handler(input, context);\n return normalizeToolResponse(raw, {\n pluginId,\n toolName: tool.name,\n logger,\n });\n },\n };\n}\n",
382
382
  "import type { Tool, Resource, ToolResponse, ToolContext } from \"./types\";\nimport { getErrorMessage } from \"@brains/utils/error\";\nimport { Logger } from \"@brains/utils/logger\";\nimport { z, type ZodRawShape } from \"@brains/utils/zod\";\n\nexport interface ToolSuccessResult<T = unknown> {\n success: true;\n data: T;\n message?: string | undefined;\n}\n\nexport interface ToolErrorResult {\n success: false;\n error: string;\n code?: string | undefined;\n}\n\n/**\n * Zod schema for tool result validation\n * Use this to parse/validate tool results at runtime\n */\nexport const toolResultSchema: z.ZodType<ToolSuccessResult | ToolErrorResult> =\n z.union([\n z.object({\n success: z.literal(true),\n data: z.unknown(),\n message: z.string().optional(),\n }),\n z.object({\n success: z.literal(false),\n error: z.string(),\n code: z.string().optional(),\n }),\n ]);\n\n/**\n * Standardized tool result type derived from schema\n * All tools should return this format for consistent handling\n *\n * @template T - The type of data returned on success (defaults to unknown)\n */\nexport type ToolResult<T = unknown> = ToolSuccessResult<T> | ToolErrorResult;\n\n/**\n * Helper to create a success result\n */\nexport function toolSuccess<T>(data: T, message?: string): ToolResult<T> {\n return message ? { success: true, data, message } : { success: true, data };\n}\n\n/**\n * Helper to create an error result\n */\nexport function toolError(error: string, code?: string): ToolResult<never> {\n return code ? { success: false, error, code } : { success: false, error };\n}\n\n/**\n * Create a tool with auto-validation and consistent response format.\n *\n * - Input is automatically validated against the schema\n * - Handler receives typed input (no manual parsing needed)\n * - Must return `ToolResult<T>` for consistent response format\n * - Validation errors are automatically caught and formatted\n *\n * @example\n * ```typescript\n * const captureSchema = z.object({\n * url: z.string().url(),\n * title: z.string().optional(),\n * });\n *\n * createTool(\n * pluginId,\n * \"capture\",\n * \"Capture a link\",\n * captureSchema,\n * async (input, ctx) => {\n * // input is typed as { url: string; title?: string }\n * const link = await captureLink(input.url);\n * return toolSuccess({ linkId: link.id });\n * }\n * );\n * ```\n */\nfunction formatZodError(error: z.ZodError): string {\n return error.issues\n .map((issue) => {\n const path = issue.path.length > 0 ? issue.path.join(\".\") : \"(root)\";\n return `${path}: ${issue.message}`;\n })\n .join(\", \");\n}\n\nexport function createTool<\n TSchema extends z.ZodObject<ZodRawShape>,\n TOutput = unknown,\n>(\n pluginId: string,\n name: string,\n description: string,\n inputSchema: TSchema,\n handler: (\n input: z.output<TSchema>,\n context: ToolContext,\n ) => Promise<ToolResult<TOutput>>,\n options: {\n visibility?: Tool[\"visibility\"];\n sideEffects?: Tool[\"sideEffects\"];\n annotations?: Tool[\"annotations\"];\n debug?: boolean;\n cli?: Tool[\"cli\"];\n } = {},\n): Tool {\n const {\n visibility = \"anchor\",\n sideEffects,\n annotations,\n debug = false,\n cli,\n } = options;\n const logger = debug ? Logger.createFresh({ context: pluginId }) : null;\n const inputShape = inputSchema.shape;\n\n return {\n name: `${pluginId}_${name}`,\n description,\n inputSchema: inputShape,\n handler: async (input, context): Promise<ToolResponse> => {\n logger?.debug(`Tool ${name} started`);\n try {\n // Auto-validate input\n const parseResult = inputSchema.safeParse(input);\n if (!parseResult.success) {\n const errorMessage = formatZodError(parseResult.error);\n logger?.debug(`Tool ${name} validation failed: ${errorMessage}`);\n return {\n success: false,\n error: `Invalid input: ${errorMessage}`,\n };\n }\n\n // Call handler with validated, typed input\n const result = await handler(parseResult.data, context);\n logger?.debug(`Tool ${name} completed`);\n return result;\n } catch (error) {\n logger?.error(`Tool ${name} failed`, error);\n const errorMessage = getErrorMessage(error);\n return {\n success: false,\n error: errorMessage,\n };\n }\n },\n visibility,\n ...(sideEffects ? { sideEffects } : {}),\n ...(annotations ? { annotations } : {}),\n ...(cli ? { cli } : {}),\n };\n}\n\n/**\n * Create a resource with consistent structure and optional debug logging.\n *\n * Use this in resource factory functions instead of building resource objects manually.\n */\nexport function createResource(\n pluginId: string,\n uri: string,\n name: string,\n description: string,\n handler: Resource[\"handler\"],\n options: {\n mimeType?: string;\n debug?: boolean;\n } = {},\n): Resource {\n const { mimeType = \"text/plain\", debug = false } = options;\n const logger = debug ? Logger.createFresh({ context: pluginId }) : null;\n\n return {\n uri: `${pluginId}_${uri}`,\n name,\n description,\n mimeType,\n handler: async (): Promise<{\n contents: Array<{\n text: string;\n uri: string;\n mimeType?: string;\n }>;\n }> => {\n logger?.debug(`Resource ${uri} started`);\n try {\n const result = await handler();\n logger?.debug(`Resource ${uri} completed`);\n return result;\n } catch (error) {\n logger?.error(`Resource ${uri} failed`, error);\n throw error;\n }\n },\n };\n}\n",
package/dist/site.js CHANGED
@@ -1582,7 +1582,7 @@ ${w.join(`
1582
1582
  letter-spacing: 0.02em;
1583
1583
  }
1584
1584
  .printable-footer a { color: inherit; text-decoration: none; overflow-wrap: anywhere; }
1585
- `}},void 0,!1,void 0,this),N$("header",{className:"printable-hero",children:[N$("div",{className:"printable-masthead",children:w.brandLabel&&N$("p",{className:"printable-kicker",children:w.brandLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this),N$("div",{children:[N$("h1",{className:"printable-title",children:w.title},void 0,!1,void 0,this),w.excerpt&&N$("p",{className:"printable-excerpt",children:w.excerpt},void 0,!1,void 0,this),N$("div",{className:"printable-meta",children:[w.author&&N$("span",{children:["By ",w.author]},void 0,!0,void 0,this),f&&N$("span",{children:f},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),w.coverImageUrl&&N$("figure",{className:"printable-cover-wrap",children:N$("img",{className:"printable-cover",src:w.coverImageUrl,alt:""},void 0,!1,void 0,this)},void 0,!1,void 0,this),N$(h4,{markdown:w.body,className:"printable-body"},void 0,!1,void 0,this),(Boolean(w.canonicalUrl)||Boolean(w.brandLabel))&&N$("footer",{className:"printable-footer",children:[N$("span",{children:w.brandLabel??"Printable PDF"},void 0,!1,void 0,this),w.canonicalUrl&&N$("a",{href:w.canonicalUrl,children:w.canonicalUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var Z_0=26214400,J_0=60000;class LD{metadata={outputEntityType:"document"};context;renderPdf;constructor($,w={}){this.context=$,this.renderPdf=w.renderPdf??iv}async resolve($){if($.sourceEntityType!=="post"||$.attachmentType!==TA)return;let w=await this.context.entityService.getEntity({entityType:"post",id:$.sourceEntityId});if(!w)return;let f=Y_0(w,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(w)}),v=await v_0(X_0(W_0(),"brain-blog-printable-"));try{let U=await R4({outputDir:v,mediaPath:`/_media/printable/post/${w.id}`,template:y00,format:"pdf",content:f,siteConfig:{title:f.title,themeMode:"light"},themeCSS:this.context.themeCSS}),W=await P4({rootDir:v});try{return{type:"document",data:await this.renderPdf(W.urlFor(U.urlPath),{maxBytes:Z_0,timeoutMs:J_0,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${A_0(w)}-printable.pdf`}}finally{await W.close()}}finally{await U_0(v,{recursive:!0,force:!0})}}resolveBrandLabel(){let $=this.context.domain?.trim();if($&&$.length>0)return $;let w=this.context.identity.getProfile().name.trim();return w.length>0?w:void 0}async resolveCoverImageUrl($){let{frontmatter:w}=J6($.content),f=P2.parse(w);if(!f.coverImageId)return;let v=await this.context.entityService.getEntity({entityType:"image",id:f.coverImageId});return v?.content.startsWith("data:image/")?v.content:void 0}}function Y_0($,w={}){let{frontmatter:f,content:v}=J6($.content),U=P2.parse(f);return{title:U.title,body:v,...U.excerpt?{excerpt:U.excerpt}:{},...U.author?{author:U.author}:{},...U.publishedAt?{publishedAt:U.publishedAt}:{},...U.canonicalUrl?{canonicalUrl:U.canonicalUrl}:{},...w.coverImageUrl?{coverImageUrl:w.coverImageUrl}:{},...w.brandLabel?{brandLabel:w.brandLabel}:{}}}function A_0($){let w=$.metadata.slug;return w.length>0?w:p2($.metadata.title)}import{mkdtemp as k_0,rm as r_0}from"fs/promises";import{tmpdir as F_0}from"os";import{join as u_0}from"path";Z3();U6();i6();D0();import{jsxDEV as O_0}from"preact/jsx-dev-runtime";var PU="og-image",K_0="blog:og-image",l00=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()}),i00={name:K_0,pluginId:"blog",schema:l00,renderers:{image:H_0}};function G_0($){if(!$)return;let w=new Date($);if(Number.isNaN(w.getTime()))return;return w.toLocaleDateString("en-GB",{year:"numeric",month:"short",day:"2-digit"})}function H_0($){let w=l00.parse($);return O_0(Ev,{brandLabel:w.brandLabel??w.title,eyebrow:"Journal",title:w.title,subtitle:w.excerpt,meta:[w.author],tag:G_0(w.publishedAt)},void 0,!1,void 0,this)}var h_0={width:1200,height:630},Q_0=60000;class TD{metadata={outputEntityType:"image",targetField:"ogImageId"};context;screenshotPng;constructor($,w={}){this.context=$,this.screenshotPng=w.screenshotPng??lv}async resolve($){if($.sourceEntityType!=="post"||$.attachmentType!==PU)return;let w=await this.context.entityService.getEntity({entityType:"post",id:$.sourceEntityId});if(!w)return;let f=N_0(w,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(w)}),v=await k_0(u_0(F_0(),"brain-blog-og-image-"));try{let U=await R4({outputDir:v,mediaPath:`/_media/og/post/${w.id}`,template:i00,format:"image",content:f,siteConfig:{title:f.title,themeMode:"light"},themeCSS:this.context.themeCSS}),W=await P4({rootDir:v});try{return{type:"image",data:await this.screenshotPng(W.urlFor(U.urlPath),h_0,{timeoutMs:Q_0,fullPage:!1,omitBackground:!1}),mimeType:"image/png",filename:`${V_0(w)}-og.png`}}finally{await W.close()}}finally{await r_0(v,{recursive:!0,force:!0})}}resolveBrandLabel(){let $=this.context.domain?.trim();if($&&$.length>0)return $;let w=this.context.identity.getProfile().name.trim();return w.length>0?w:void 0}async resolveCoverImageUrl($){let{frontmatter:w}=J6($.content),f=P2.parse(w);if(!f.coverImageId)return;let v=await this.context.entityService.getEntity({entityType:"image",id:f.coverImageId});return v?.content.startsWith("data:image/")?v.content:void 0}}function N_0($,w={}){let{frontmatter:f}=J6($.content),v=P2.parse(f);return{title:v.title,...v.excerpt?{excerpt:v.excerpt}:{},...v.author?{author:v.author}:{},...v.publishedAt?{publishedAt:v.publishedAt}:{},...w.coverImageUrl?{coverImageUrl:w.coverImageUrl}:{},...w.brandLabel?{brandLabel:w.brandLabel}:{}}}function V_0($){let w=$.metadata.slug;return w.length>0?w:p2($.metadata.title)}var n00={name:"@brains/blog",version:"0.2.0-alpha.154",description:"AI-powered blog post generation from existing brain content",dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/contracts":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};class d00 extends J3{entityType=Y4.entityType;schema=D8;adapter=Y4;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor($={}){super("blog",n00,$,BN)}getEntityTypeConfig(){return{weight:2,publish:{publishStatuses:["queued","published"]}}}createGenerationHandler($){return new DN(this.logger.child("BlogGenerationJobHandler"),$)}getTemplates(){return Ho()}getDataSources(){return[new _N(this.logger.child("BlogDataSource"))]}async onRegister($){let{RSSDataSource:w}=await Promise.resolve().then(() => (c00(),o00));$.entities.registerDataSource(new w(this.logger.child("RSSDataSource"))),Oo($,this.logger),ko($,this.logger),Fo($,this.logger),uo($),this.unregisterPrintableAttachmentProvider=$.attachments.register("post",TA,new LD($)),this.unregisterOgImageAttachmentProvider=$.attachments.register("post",PU,new TD($)),this.deferPublishAssetRegistration($),this.unregisterAtprotoProjection=K3.getInstance().register(Ez()),this.logger.info("Blog plugin registered (routes auto-generated at /posts/)")}deferPublishAssetRegistration($){$.messaging.subscribe("system:plugins:ready",async()=>{return await $.messaging.send({type:"publish-assets:register",payload:{entityType:"post",attachmentType:PU,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}}i6();M8();class gA{postsListUrl;id="personal:homepage";name="Personal Homepage DataSource";description="Fetches profile and blog posts for a personal homepage";constructor($){this.postsListUrl=$}async fetch($,w,f){let v=f.entityService,[U,W,X]=await Promise.all([E5(v,vv),B8(v,{entityType:"post",count:6,parse:zw}),Vw(v)]),Z={profile:U,posts:W,postsListUrl:this.postsListUrl,cta:Uv(X.cta)};return w.parse(Z)}}$2();class bA{id="personal:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch($,w,f){let U={profile:await E5(f.entityService,vv)};return w.parse(U)}}import{jsxDEV as C1,Fragment as a00}from"preact/jsx-dev-runtime";function D_0($){return new Date($).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"})}function M_0($){return $.split(/(\*[^*]+\*)/).map((w,f)=>{if(w.startsWith("*")&&w.endsWith("*")&&w.length>2)return C1("em",{className:"font-sans italic font-medium text-theme-inverse tracking-[-0.015em] [font-variation-settings:'opsz'_72]",children:w.slice(1,-1)},f,!1,void 0,this);return w})}var gD=({profile:$,posts:w,postsListUrl:f,cta:v})=>{let U=$.tagline??$.description,W=$.name.split(" ")[0];return C1(a00,{children:[C1(a2,{title:$.name,description:$.description??U??"Personal site",ogType:"website"},void 0,!1,void 0,this),C1("header",{className:"hero-decor bg-brand text-theme-inverse relative flex flex-col items-center justify-center px-6 md:px-12 pt-32 pb-24 gap-7",children:C1("div",{className:"w-full max-w-[1100px] mx-auto text-center flex flex-col items-center gap-7",children:[U&&C1("h1",{className:"font-heading font-bold text-[clamp(2.5rem,6vw,5rem)] leading-[1.05] tracking-[-0.035em] text-theme-inverse text-balance m-0 [font-variation-settings:'wdth'_90,'opsz'_96]",children:M_0(U)},void 0,!1,void 0,this),$.description&&C1("p",{className:"text-[clamp(1.0625rem,1.4vw,1.3125rem)] leading-[1.5] text-theme-inverse opacity-95 max-w-[600px] mx-auto m-0",children:$.description},void 0,!1,void 0,this),C1("div",{className:"flex flex-wrap justify-center gap-3.5 mt-2",children:[C1("a",{href:f,className:"inline-flex items-center gap-2 rounded-full py-3.5 px-7 bg-theme text-brand border-2 border-theme font-heading font-semibold text-[15px] hover:bg-theme-subtle hover:-translate-y-0.5 transition-all [font-variation-settings:'wdth'_92,'opsz'_18]",children:["Read the Blog ",C1("span",{"aria-hidden":"true",children:"\u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C1("a",{href:"/about",className:"rounded-full py-3.5 px-7 border-2 border-theme-light text-theme-inverse font-heading font-semibold text-[15px] hover:bg-brand-dark hover:border-theme hover:-translate-y-0.5 transition-all [font-variation-settings:'wdth'_92,'opsz'_18]",children:["About ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),w.length>0&&C1("section",{className:"flex flex-col py-24 px-6 md:px-12 gap-11 bg-theme-subtle",children:[C1("div",{className:"flex justify-between items-end max-w-layout mx-auto w-full gap-6 flex-wrap",children:[C1("div",{children:[C1("span",{className:"block font-heading font-semibold text-[13px] uppercase tracking-[0.22em] text-brand mb-3 [font-variation-settings:'wdth'_85,'opsz'_12]",children:"The Archive"},void 0,!1,void 0,this),C1("h2",{className:"font-heading font-bold text-[clamp(2.25rem,5vw,3.75rem)] leading-none tracking-[-0.03em] text-heading m-0 [font-variation-settings:'wdth'_92,'opsz'_64]",children:["Recent"," ",C1("em",{className:"font-sans italic font-medium text-brand [font-variation-settings:'opsz'_60]",children:"posts"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),C1("a",{href:f,className:"font-heading font-semibold text-[15px] text-brand inline-flex items-center gap-1.5 pb-1.5 border-b-2 border-current hover:text-brand-dark transition-colors [font-variation-settings:'wdth'_88,'opsz'_16]",children:["View the whole archive ",C1("span",{"aria-hidden":"true",children:"\u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),C1("div",{className:"grid grid-cols-[repeat(auto-fit,minmax(min(100%,320px),1fr))] gap-8 max-w-layout mx-auto w-full",children:w.map((X)=>C1("a",{href:X.url,className:"group flex flex-col bg-theme border border-theme rounded-md overflow-hidden hover:-translate-y-1 hover:border-brand/50 transition-all no-underline shadow-sm hover:shadow-lg",children:[X.coverImageUrl?C1("img",{src:X.coverImageUrl,alt:X.metadata.title,className:"w-full aspect-[16/10] object-cover bg-theme-muted"},void 0,!1,void 0,this):C1("div",{className:"w-full aspect-[16/10] bg-gradient-to-br from-brand to-accent","aria-hidden":"true"},void 0,!1,void 0,this),C1("div",{className:"flex flex-col gap-4 p-7 flex-1",children:[C1("div",{className:"flex flex-wrap items-center gap-3.5 font-heading text-[11px] font-semibold uppercase tracking-[0.18em] text-theme-muted [font-variation-settings:'wdth'_85,'opsz'_11]",children:[X.frontmatter.seriesName&&C1(a00,{children:[C1("span",{className:"text-brand",children:X.frontmatter.seriesName},void 0,!1,void 0,this),C1("span",{className:"w-[3px] h-[3px] rounded-full bg-current opacity-50","aria-hidden":"true"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C1("time",{children:D_0(X.metadata.publishedAt??X.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C1("h3",{className:"font-sans font-semibold text-[clamp(1.375rem,1.8vw,1.625rem)] leading-[1.18] tracking-[-0.012em] text-heading m-0 text-balance",children:X.metadata.title},void 0,!1,void 0,this),X.frontmatter.excerpt&&C1("p",{className:"text-base leading-[1.55] text-theme-muted m-0 flex-1",children:X.frontmatter.excerpt},void 0,!1,void 0,this),C1("span",{className:"inline-flex items-center gap-1.5 font-heading font-semibold text-[13px] uppercase tracking-[0.14em] text-brand mt-1 [font-variation-settings:'wdth'_88,'opsz'_14]",children:["Read the post"," ",C1("span",{"aria-hidden":"true",className:"transition-transform group-hover:translate-x-1",children:"\u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},X.id,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C1("section",{className:"cta-decor bg-theme-dark text-theme-on-dark flex-grow flex flex-col items-center justify-center py-24 px-6 md:px-12 gap-5",children:[C1("span",{className:"font-heading font-medium text-xs uppercase tracking-[0.24em] text-accent [font-variation-settings:'wdth'_85,'opsz'_12]",children:"Get in touch"},void 0,!1,void 0,this),C1("h2",{className:"text-center font-heading font-bold text-[clamp(2rem,4vw,3rem)] leading-none tracking-[-0.03em] text-theme-on-dark m-0 [font-variation-settings:'wdth'_90,'opsz'_64]",children:v.heading},void 0,!1,void 0,this),v.subtitle&&C1("p",{className:"text-center text-base leading-[1.55] text-theme-on-dark opacity-80 max-w-[480px] m-0",children:v.subtitle},void 0,!1,void 0,this),C1("a",{href:v.buttonLink,className:"inline-flex items-center gap-2 rounded-full py-3.5 px-7 bg-brand text-theme-inverse border-2 border-brand font-heading font-semibold text-[15px] hover:bg-brand-dark hover:-translate-y-0.5 transition-all mt-2 [font-variation-settings:'wdth'_92,'opsz'_18]",children:[v.buttonText," ",C1("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,!0,void 0,this)};import{jsxDEV as V$,Fragment as __0}from"preact/jsx-dev-runtime";var bD=({profile:$})=>{let w=`About ${$.name}`,f=$.description??$.intro??"About page",v=Boolean($.email??$.website);return V$(__0,{children:[V$(a2,{title:w,description:f,ogType:"profile"},void 0,!1,void 0,this),V$("section",{className:"hero-decor bg-brand text-theme-inverse relative flex flex-col px-6 md:px-12 pt-32 pb-24",children:V$("div",{className:"w-full max-w-3xl mx-auto flex flex-col gap-6",children:[V$("h1",{className:"font-heading font-bold text-[clamp(2.5rem,6vw,4.5rem)] leading-[1.05] tracking-[-0.035em] text-theme-inverse text-balance m-0 [font-variation-settings:'wdth'_90,'opsz'_96]",children:$.name},void 0,!1,void 0,this),$.description&&V$("p",{className:"text-[clamp(1.0625rem,1.4vw,1.25rem)] leading-[1.55] text-theme-inverse opacity-95 max-w-2xl m-0",children:$.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),$.story&&V$("section",{className:`py-24 px-6 md:px-12 bg-theme-subtle${v?"":" flex-grow"}`,children:V$("div",{className:"max-w-3xl mx-auto",children:V$(h4,{markdown:$.story},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),v&&V$("section",{className:"cta-decor bg-theme-dark text-theme-on-dark flex-grow flex flex-col items-center justify-center py-24 px-6 md:px-12 gap-5",children:[V$("span",{className:"font-heading font-medium text-xs uppercase tracking-[0.24em] text-accent [font-variation-settings:'wdth'_85,'opsz'_12]",children:"Get in touch"},void 0,!1,void 0,this),V$("h2",{className:"text-center font-heading font-bold text-[clamp(2rem,4vw,3rem)] leading-none tracking-[-0.03em] text-theme-on-dark m-0 [font-variation-settings:'wdth'_90,'opsz'_64]",children:["Say"," ",V$("em",{className:"font-sans italic font-medium text-accent [font-variation-settings:'opsz'_72]",children:"hi."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),V$("div",{className:"flex flex-wrap justify-center gap-3.5 mt-2",children:[$.email&&V$("a",{href:`mailto:${$.email}`,className:"inline-flex items-center gap-2 rounded-full py-3.5 px-7 bg-brand text-theme-inverse border-2 border-brand font-heading font-semibold text-[15px] hover:bg-brand-dark hover:-translate-y-0.5 transition-all [font-variation-settings:'wdth'_92,'opsz'_18]",children:["Get in Touch ",V$("span",{"aria-hidden":"true",children:"\u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.website&&V$("a",{href:$.website,className:"rounded-full py-3.5 px-7 border-2 border-theme-light text-theme-on-dark font-heading font-semibold text-[15px] hover:bg-brand-dark hover:border-theme hover:-translate-y-0.5 transition-all [font-variation-settings:'wdth'_92,'opsz'_18]",children:"Website"},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 t00={name:"@brains/site-personal",version:"0.2.0-alpha.154",description:"Personal site composition package",dependencies:{"@brains/blog":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-engine":"workspace:*","@brains/site-info":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},files:["src"],private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",typecheck:"tsc --noEmit"},type:"module"};var P_0=H.object({entityDisplay:H.object({post:H.object({label:H.string().default("Post"),pluralName:H.string().optional()}).default({label:"Post"})}).default({post:{label:"Post"}})}),L_0=H.object({heading:H.string(),buttonText:H.string(),buttonLink:H.string(),subtitle:H.string().optional()}),s00=H.looseObject({name:H.string(),kind:H.enum(["professional","team","collective"]),organization:H.string().optional(),description:H.string().optional(),avatar:H.string().optional(),website:H.string().optional(),email:H.string().optional(),socialLinks:H.array(H.object({platform:H.enum(["github","instagram","linkedin","email","website"]),url:H.string(),label:H.string().optional()})).optional(),tagline:H.string().optional(),intro:H.string().optional(),story:H.string().optional()}),T_0=H.looseObject({id:H.string(),entityType:H.literal("post"),content:H.string(),created:H.string(),updated:H.string(),contentHash:H.string(),metadata:H.looseObject({title:H.string(),publishedAt:H.string().optional()}),frontmatter:H.looseObject({excerpt:H.string(),seriesName:H.string().optional(),seriesIndex:H.number().optional()}),body:H.string(),url:H.string().optional(),typeLabel:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),seriesUrl:H.string().optional(),coverImageUrl:H.string().optional(),ogImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional(),coverImageSrcset:H.string().optional(),coverImageSizes:H.string().optional()});class qD extends u8{dependencies=["blog"];constructor($={}){super("personal-site",t00,$,P_0)}async onRegister($){$.entities.extendFrontmatterSchema("anchor-profile",KJ);let w=this.config.entityDisplay.post,f=`/${w.pluralName??w.label.toLowerCase()+"s"}`,v=new gA(f);$.entities.registerDataSource(v);let U=new bA;$.entities.registerDataSource(U);let W=H.object({profile:s00,posts:H.array(T_0),postsListUrl:H.string(),cta:L_0}),X=H.object({profile:s00});$.templates.register({homepage:D2({name:"homepage",description:"Personal homepage with recent blog posts",schema:W,dataSourceId:"personal:homepage",requiredPermission:"public",layout:{component:gD}}),about:D2({name:"about",description:"About page with profile",schema:X,dataSourceId:"personal:about",requiredPermission:"public",layout:{component:bD}})}),this.logger.info("Personal site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function ID($){return new qD($??{})}var ED=[{id:"home",path:"/",title:"Home",description:"Personal site homepage",layout:"default",navigation:{show:!0,label:"Home",slot:"secondary",priority:10},sections:[{id:"homepage",template:"personal-site:homepage",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:"personal-site:about",dataQuery:{}}]}];import{jsxDEV as q6}from"preact/jsx-dev-runtime";function jD({sections:$,siteInfo:w}){let f=[...w.navigation.primary,...w.navigation.secondary].filter((v)=>v.label!=="Home");return q6("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[q6(Iv,{title:w.title,titleClassName:"font-heading font-bold text-2xl",navigation:w.navigation.primary,showThemeToggle:!0,themeToggleClassName:"bg-theme-toggle text-theme-toggle-icon hover:bg-theme-toggle-hover rounded-[10px]",...w.logo!==void 0?{logo:w.logo}:{}},void 0,!1,void 0,this),q6("main",{className:"flex-grow flex flex-col",children:$},void 0,!1,void 0,this),q6("footer",{className:"bg-footer text-footer border-t border-theme",children:q6("div",{className:"max-w-layout mx-auto flex flex-col md:flex-row justify-between items-center py-8 px-6 md:px-8",children:[q6("div",{className:"flex flex-col gap-1 mb-4 md:mb-0",children:[q6("span",{className:"text-brand font-heading font-bold text-lg",children:w.title},void 0,!1,void 0,this),w.description&&q6("span",{className:"text-theme-muted text-xs",children:w.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q6("nav",{className:"flex flex-wrap justify-center gap-x-6 gap-y-2 mb-4 md:mb-0",children:f.map((v)=>q6("a",{href:v.href,className:"text-theme-muted text-[13px] hover:text-brand transition-colors",children:v.label},v.href,!1,void 0,this))},void 0,!1,void 0,this),q6("div",{className:"flex items-center gap-4",children:[w.copyright&&q6("span",{className:"text-theme-light text-[11px]",children:w.copyright},void 0,!1,void 0,this),q6(O3,{variant:"footer",size:"sm"},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)}$2();D0();q5();$2();$2();var LU=I5.extend(wv.shape);$2();D0();$2();U6();D0();$2();var e00=H.enum(["generating","draft","queued","published","failed"]),$10=H.enum(["generating","draft","queued","published","failed"]),SD="publishedAt is required when deck status is published",mD=($)=>$.status==="published"&&!$.publishedAt,xD=($)=>{if(mD($))throw Error(SD)},t5=H.object({title:H.string(),slug:H.string().optional(),description:H.string().optional(),author:H.string().optional(),status:e00,publishedAt:H.string().datetime().optional(),event:H.string().optional(),coverImageId:H.string().optional(),ogImageId:H.string().optional()}),UG1=H.object({title:H.string(),description:H.string().optional(),status:e00,publishedAt:H.string().datetime().optional(),coverImageId:H.string().optional(),slug:H.string(),error:H.string().optional()}).superRefine(($,w)=>{if(!mD($))return;w.addIssue({code:H.ZodIssueCode.custom,path:["publishedAt"],message:SD})}),g_0=H.object({title:H.string(),description:H.string().optional(),status:$10,publishedAt:H.string().datetime().optional(),coverImageId:H.string().optional(),slug:H.string(),error:H.string().optional()}).superRefine(($,w)=>{if(!mD($))return;w.addIssue({code:"custom",path:["publishedAt"],message:SD})}),b_0=H.object({title:H.string(),slug:H.string().optional(),description:H.string().optional(),author:H.string().optional(),status:$10,publishedAt:H.string().datetime().optional(),event:H.string().optional(),coverImageId:H.string().optional(),ogImageId:H.string().optional()}),H7=g5.extend({entityType:H.literal("deck"),metadata:g_0}),qA=H7.extend({frontmatter:b_0,body:H.string(),ogImageUrl:H.string().optional()}),TU=qA.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 CD extends d${constructor(){super({entityType:"deck",purpose:"A slide-deck presentation.",schema:H7,frontmatterSchema:t5,supportsCoverImage:!0})}validateSlideStructure($){if(!/^---$/gm.test($))throw Error("Invalid deck: markdown must contain slide separators (---) to be a valid presentation")}toMarkdown($){let w=this.extractBody($.content);this.validateSlideStructure(w);let f=this.parseFrontMatter($.content,t5);xD(f);let v={...f,slug:f.slug??$.metadata.slug};return this.buildMarkdown(w,v)}fromMarkdown($){let w=this.parseFrontmatter($),f=this.extractBody($);xD(w),this.validateSlideStructure(f);let v=w.slug??p2(w.title),U=w.status;return{entityType:"deck",content:$,metadata:{slug:v,title:w.title,description:w.description,status:U,publishedAt:w.publishedAt,coverImageId:w.coverImageId}}}generateTitle($){return $.metadata.title}generateSummary($){if($.metadata.description)return $.metadata.description;return`Presentation: ${$.metadata.title}`}generateFrontMatter($){return this.toMarkdown($)}buildStub($){let w={title:$.title,slug:$.id,status:"generating"};return{content:this.buildMarkdown(`---
1585
+ `}},void 0,!1,void 0,this),N$("header",{className:"printable-hero",children:[N$("div",{className:"printable-masthead",children:w.brandLabel&&N$("p",{className:"printable-kicker",children:w.brandLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this),N$("div",{children:[N$("h1",{className:"printable-title",children:w.title},void 0,!1,void 0,this),w.excerpt&&N$("p",{className:"printable-excerpt",children:w.excerpt},void 0,!1,void 0,this),N$("div",{className:"printable-meta",children:[w.author&&N$("span",{children:["By ",w.author]},void 0,!0,void 0,this),f&&N$("span",{children:f},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),w.coverImageUrl&&N$("figure",{className:"printable-cover-wrap",children:N$("img",{className:"printable-cover",src:w.coverImageUrl,alt:""},void 0,!1,void 0,this)},void 0,!1,void 0,this),N$(h4,{markdown:w.body,className:"printable-body"},void 0,!1,void 0,this),(Boolean(w.canonicalUrl)||Boolean(w.brandLabel))&&N$("footer",{className:"printable-footer",children:[N$("span",{children:w.brandLabel??"Printable PDF"},void 0,!1,void 0,this),w.canonicalUrl&&N$("a",{href:w.canonicalUrl,children:w.canonicalUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var Z_0=26214400,J_0=60000;class LD{metadata={outputEntityType:"document"};context;renderPdf;constructor($,w={}){this.context=$,this.renderPdf=w.renderPdf??iv}async resolve($){if($.sourceEntityType!=="post"||$.attachmentType!==TA)return;let w=await this.context.entityService.getEntity({entityType:"post",id:$.sourceEntityId});if(!w)return;let f=Y_0(w,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(w)}),v=await v_0(X_0(W_0(),"brain-blog-printable-"));try{let U=await R4({outputDir:v,mediaPath:`/_media/printable/post/${w.id}`,template:y00,format:"pdf",content:f,siteConfig:{title:f.title,themeMode:"light"},themeCSS:this.context.themeCSS}),W=await P4({rootDir:v});try{return{type:"document",data:await this.renderPdf(W.urlFor(U.urlPath),{maxBytes:Z_0,timeoutMs:J_0,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${A_0(w)}-printable.pdf`}}finally{await W.close()}}finally{await U_0(v,{recursive:!0,force:!0})}}resolveBrandLabel(){let $=this.context.domain?.trim();if($&&$.length>0)return $;let w=this.context.identity.getProfile().name.trim();return w.length>0?w:void 0}async resolveCoverImageUrl($){let{frontmatter:w}=J6($.content),f=P2.parse(w);if(!f.coverImageId)return;let v=await this.context.entityService.getEntity({entityType:"image",id:f.coverImageId});return v?.content.startsWith("data:image/")?v.content:void 0}}function Y_0($,w={}){let{frontmatter:f,content:v}=J6($.content),U=P2.parse(f);return{title:U.title,body:v,...U.excerpt?{excerpt:U.excerpt}:{},...U.author?{author:U.author}:{},...U.publishedAt?{publishedAt:U.publishedAt}:{},...U.canonicalUrl?{canonicalUrl:U.canonicalUrl}:{},...w.coverImageUrl?{coverImageUrl:w.coverImageUrl}:{},...w.brandLabel?{brandLabel:w.brandLabel}:{}}}function A_0($){let w=$.metadata.slug;return w.length>0?w:p2($.metadata.title)}import{mkdtemp as k_0,rm as r_0}from"fs/promises";import{tmpdir as F_0}from"os";import{join as u_0}from"path";Z3();U6();i6();D0();import{jsxDEV as O_0}from"preact/jsx-dev-runtime";var PU="og-image",K_0="blog:og-image",l00=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()}),i00={name:K_0,pluginId:"blog",schema:l00,renderers:{image:H_0}};function G_0($){if(!$)return;let w=new Date($);if(Number.isNaN(w.getTime()))return;return w.toLocaleDateString("en-GB",{year:"numeric",month:"short",day:"2-digit"})}function H_0($){let w=l00.parse($);return O_0(Ev,{brandLabel:w.brandLabel??w.title,eyebrow:"Journal",title:w.title,subtitle:w.excerpt,meta:[w.author],tag:G_0(w.publishedAt)},void 0,!1,void 0,this)}var h_0={width:1200,height:630},Q_0=60000;class TD{metadata={outputEntityType:"image",targetField:"ogImageId"};context;screenshotPng;constructor($,w={}){this.context=$,this.screenshotPng=w.screenshotPng??lv}async resolve($){if($.sourceEntityType!=="post"||$.attachmentType!==PU)return;let w=await this.context.entityService.getEntity({entityType:"post",id:$.sourceEntityId});if(!w)return;let f=N_0(w,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(w)}),v=await k_0(u_0(F_0(),"brain-blog-og-image-"));try{let U=await R4({outputDir:v,mediaPath:`/_media/og/post/${w.id}`,template:i00,format:"image",content:f,siteConfig:{title:f.title,themeMode:"light"},themeCSS:this.context.themeCSS}),W=await P4({rootDir:v});try{return{type:"image",data:await this.screenshotPng(W.urlFor(U.urlPath),h_0,{timeoutMs:Q_0,fullPage:!1,omitBackground:!1}),mimeType:"image/png",filename:`${V_0(w)}-og.png`}}finally{await W.close()}}finally{await r_0(v,{recursive:!0,force:!0})}}resolveBrandLabel(){let $=this.context.domain?.trim();if($&&$.length>0)return $;let w=this.context.identity.getProfile().name.trim();return w.length>0?w:void 0}async resolveCoverImageUrl($){let{frontmatter:w}=J6($.content),f=P2.parse(w);if(!f.coverImageId)return;let v=await this.context.entityService.getEntity({entityType:"image",id:f.coverImageId});return v?.content.startsWith("data:image/")?v.content:void 0}}function N_0($,w={}){let{frontmatter:f}=J6($.content),v=P2.parse(f);return{title:v.title,...v.excerpt?{excerpt:v.excerpt}:{},...v.author?{author:v.author}:{},...v.publishedAt?{publishedAt:v.publishedAt}:{},...w.coverImageUrl?{coverImageUrl:w.coverImageUrl}:{},...w.brandLabel?{brandLabel:w.brandLabel}:{}}}function V_0($){let w=$.metadata.slug;return w.length>0?w:p2($.metadata.title)}var n00={name:"@brains/blog",version:"0.2.0-alpha.155",description:"AI-powered blog post generation from existing brain content",dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/contracts":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};class d00 extends J3{entityType=Y4.entityType;schema=D8;adapter=Y4;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor($={}){super("blog",n00,$,BN)}getEntityTypeConfig(){return{weight:2,publish:{publishStatuses:["queued","published"]}}}createGenerationHandler($){return new DN(this.logger.child("BlogGenerationJobHandler"),$)}getTemplates(){return Ho()}getDataSources(){return[new _N(this.logger.child("BlogDataSource"))]}async onRegister($){let{RSSDataSource:w}=await Promise.resolve().then(() => (c00(),o00));$.entities.registerDataSource(new w(this.logger.child("RSSDataSource"))),Oo($,this.logger),ko($,this.logger),Fo($,this.logger),uo($),this.unregisterPrintableAttachmentProvider=$.attachments.register("post",TA,new LD($)),this.unregisterOgImageAttachmentProvider=$.attachments.register("post",PU,new TD($)),this.deferPublishAssetRegistration($),this.unregisterAtprotoProjection=K3.getInstance().register(Ez()),this.logger.info("Blog plugin registered (routes auto-generated at /posts/)")}deferPublishAssetRegistration($){$.messaging.subscribe("system:plugins:ready",async()=>{return await $.messaging.send({type:"publish-assets:register",payload:{entityType:"post",attachmentType:PU,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}}i6();M8();class gA{postsListUrl;id="personal:homepage";name="Personal Homepage DataSource";description="Fetches profile and blog posts for a personal homepage";constructor($){this.postsListUrl=$}async fetch($,w,f){let v=f.entityService,[U,W,X]=await Promise.all([E5(v,vv),B8(v,{entityType:"post",count:6,parse:zw}),Vw(v)]),Z={profile:U,posts:W,postsListUrl:this.postsListUrl,cta:Uv(X.cta)};return w.parse(Z)}}$2();class bA{id="personal:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch($,w,f){let U={profile:await E5(f.entityService,vv)};return w.parse(U)}}import{jsxDEV as C1,Fragment as a00}from"preact/jsx-dev-runtime";function D_0($){return new Date($).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"})}function M_0($){return $.split(/(\*[^*]+\*)/).map((w,f)=>{if(w.startsWith("*")&&w.endsWith("*")&&w.length>2)return C1("em",{className:"font-sans italic font-medium text-theme-inverse tracking-[-0.015em] [font-variation-settings:'opsz'_72]",children:w.slice(1,-1)},f,!1,void 0,this);return w})}var gD=({profile:$,posts:w,postsListUrl:f,cta:v})=>{let U=$.tagline??$.description,W=$.name.split(" ")[0];return C1(a00,{children:[C1(a2,{title:$.name,description:$.description??U??"Personal site",ogType:"website"},void 0,!1,void 0,this),C1("header",{className:"hero-decor bg-brand text-theme-inverse relative flex flex-col items-center justify-center px-6 md:px-12 pt-32 pb-24 gap-7",children:C1("div",{className:"w-full max-w-[1100px] mx-auto text-center flex flex-col items-center gap-7",children:[U&&C1("h1",{className:"font-heading font-bold text-[clamp(2.5rem,6vw,5rem)] leading-[1.05] tracking-[-0.035em] text-theme-inverse text-balance m-0 [font-variation-settings:'wdth'_90,'opsz'_96]",children:M_0(U)},void 0,!1,void 0,this),$.description&&C1("p",{className:"text-[clamp(1.0625rem,1.4vw,1.3125rem)] leading-[1.5] text-theme-inverse opacity-95 max-w-[600px] mx-auto m-0",children:$.description},void 0,!1,void 0,this),C1("div",{className:"flex flex-wrap justify-center gap-3.5 mt-2",children:[C1("a",{href:f,className:"inline-flex items-center gap-2 rounded-full py-3.5 px-7 bg-theme text-brand border-2 border-theme font-heading font-semibold text-[15px] hover:bg-theme-subtle hover:-translate-y-0.5 transition-all [font-variation-settings:'wdth'_92,'opsz'_18]",children:["Read the Blog ",C1("span",{"aria-hidden":"true",children:"\u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C1("a",{href:"/about",className:"rounded-full py-3.5 px-7 border-2 border-theme-light text-theme-inverse font-heading font-semibold text-[15px] hover:bg-brand-dark hover:border-theme hover:-translate-y-0.5 transition-all [font-variation-settings:'wdth'_92,'opsz'_18]",children:["About ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),w.length>0&&C1("section",{className:"flex flex-col py-24 px-6 md:px-12 gap-11 bg-theme-subtle",children:[C1("div",{className:"flex justify-between items-end max-w-layout mx-auto w-full gap-6 flex-wrap",children:[C1("div",{children:[C1("span",{className:"block font-heading font-semibold text-[13px] uppercase tracking-[0.22em] text-brand mb-3 [font-variation-settings:'wdth'_85,'opsz'_12]",children:"The Archive"},void 0,!1,void 0,this),C1("h2",{className:"font-heading font-bold text-[clamp(2.25rem,5vw,3.75rem)] leading-none tracking-[-0.03em] text-heading m-0 [font-variation-settings:'wdth'_92,'opsz'_64]",children:["Recent"," ",C1("em",{className:"font-sans italic font-medium text-brand [font-variation-settings:'opsz'_60]",children:"posts"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),C1("a",{href:f,className:"font-heading font-semibold text-[15px] text-brand inline-flex items-center gap-1.5 pb-1.5 border-b-2 border-current hover:text-brand-dark transition-colors [font-variation-settings:'wdth'_88,'opsz'_16]",children:["View the whole archive ",C1("span",{"aria-hidden":"true",children:"\u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),C1("div",{className:"grid grid-cols-[repeat(auto-fit,minmax(min(100%,320px),1fr))] gap-8 max-w-layout mx-auto w-full",children:w.map((X)=>C1("a",{href:X.url,className:"group flex flex-col bg-theme border border-theme rounded-md overflow-hidden hover:-translate-y-1 hover:border-brand/50 transition-all no-underline shadow-sm hover:shadow-lg",children:[X.coverImageUrl?C1("img",{src:X.coverImageUrl,alt:X.metadata.title,className:"w-full aspect-[16/10] object-cover bg-theme-muted"},void 0,!1,void 0,this):C1("div",{className:"w-full aspect-[16/10] bg-gradient-to-br from-brand to-accent","aria-hidden":"true"},void 0,!1,void 0,this),C1("div",{className:"flex flex-col gap-4 p-7 flex-1",children:[C1("div",{className:"flex flex-wrap items-center gap-3.5 font-heading text-[11px] font-semibold uppercase tracking-[0.18em] text-theme-muted [font-variation-settings:'wdth'_85,'opsz'_11]",children:[X.frontmatter.seriesName&&C1(a00,{children:[C1("span",{className:"text-brand",children:X.frontmatter.seriesName},void 0,!1,void 0,this),C1("span",{className:"w-[3px] h-[3px] rounded-full bg-current opacity-50","aria-hidden":"true"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C1("time",{children:D_0(X.metadata.publishedAt??X.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C1("h3",{className:"font-sans font-semibold text-[clamp(1.375rem,1.8vw,1.625rem)] leading-[1.18] tracking-[-0.012em] text-heading m-0 text-balance",children:X.metadata.title},void 0,!1,void 0,this),X.frontmatter.excerpt&&C1("p",{className:"text-base leading-[1.55] text-theme-muted m-0 flex-1",children:X.frontmatter.excerpt},void 0,!1,void 0,this),C1("span",{className:"inline-flex items-center gap-1.5 font-heading font-semibold text-[13px] uppercase tracking-[0.14em] text-brand mt-1 [font-variation-settings:'wdth'_88,'opsz'_14]",children:["Read the post"," ",C1("span",{"aria-hidden":"true",className:"transition-transform group-hover:translate-x-1",children:"\u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},X.id,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C1("section",{className:"cta-decor bg-theme-dark text-theme-on-dark flex-grow flex flex-col items-center justify-center py-24 px-6 md:px-12 gap-5",children:[C1("span",{className:"font-heading font-medium text-xs uppercase tracking-[0.24em] text-accent [font-variation-settings:'wdth'_85,'opsz'_12]",children:"Get in touch"},void 0,!1,void 0,this),C1("h2",{className:"text-center font-heading font-bold text-[clamp(2rem,4vw,3rem)] leading-none tracking-[-0.03em] text-theme-on-dark m-0 [font-variation-settings:'wdth'_90,'opsz'_64]",children:v.heading},void 0,!1,void 0,this),v.subtitle&&C1("p",{className:"text-center text-base leading-[1.55] text-theme-on-dark opacity-80 max-w-[480px] m-0",children:v.subtitle},void 0,!1,void 0,this),C1("a",{href:v.buttonLink,className:"inline-flex items-center gap-2 rounded-full py-3.5 px-7 bg-brand text-theme-inverse border-2 border-brand font-heading font-semibold text-[15px] hover:bg-brand-dark hover:-translate-y-0.5 transition-all mt-2 [font-variation-settings:'wdth'_92,'opsz'_18]",children:[v.buttonText," ",C1("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,!0,void 0,this)};import{jsxDEV as V$,Fragment as __0}from"preact/jsx-dev-runtime";var bD=({profile:$})=>{let w=`About ${$.name}`,f=$.description??$.intro??"About page",v=Boolean($.email??$.website);return V$(__0,{children:[V$(a2,{title:w,description:f,ogType:"profile"},void 0,!1,void 0,this),V$("section",{className:"hero-decor bg-brand text-theme-inverse relative flex flex-col px-6 md:px-12 pt-32 pb-24",children:V$("div",{className:"w-full max-w-3xl mx-auto flex flex-col gap-6",children:[V$("h1",{className:"font-heading font-bold text-[clamp(2.5rem,6vw,4.5rem)] leading-[1.05] tracking-[-0.035em] text-theme-inverse text-balance m-0 [font-variation-settings:'wdth'_90,'opsz'_96]",children:$.name},void 0,!1,void 0,this),$.description&&V$("p",{className:"text-[clamp(1.0625rem,1.4vw,1.25rem)] leading-[1.55] text-theme-inverse opacity-95 max-w-2xl m-0",children:$.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),$.story&&V$("section",{className:`py-24 px-6 md:px-12 bg-theme-subtle${v?"":" flex-grow"}`,children:V$("div",{className:"max-w-3xl mx-auto",children:V$(h4,{markdown:$.story},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),v&&V$("section",{className:"cta-decor bg-theme-dark text-theme-on-dark flex-grow flex flex-col items-center justify-center py-24 px-6 md:px-12 gap-5",children:[V$("span",{className:"font-heading font-medium text-xs uppercase tracking-[0.24em] text-accent [font-variation-settings:'wdth'_85,'opsz'_12]",children:"Get in touch"},void 0,!1,void 0,this),V$("h2",{className:"text-center font-heading font-bold text-[clamp(2rem,4vw,3rem)] leading-none tracking-[-0.03em] text-theme-on-dark m-0 [font-variation-settings:'wdth'_90,'opsz'_64]",children:["Say"," ",V$("em",{className:"font-sans italic font-medium text-accent [font-variation-settings:'opsz'_72]",children:"hi."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),V$("div",{className:"flex flex-wrap justify-center gap-3.5 mt-2",children:[$.email&&V$("a",{href:`mailto:${$.email}`,className:"inline-flex items-center gap-2 rounded-full py-3.5 px-7 bg-brand text-theme-inverse border-2 border-brand font-heading font-semibold text-[15px] hover:bg-brand-dark hover:-translate-y-0.5 transition-all [font-variation-settings:'wdth'_92,'opsz'_18]",children:["Get in Touch ",V$("span",{"aria-hidden":"true",children:"\u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.website&&V$("a",{href:$.website,className:"rounded-full py-3.5 px-7 border-2 border-theme-light text-theme-on-dark font-heading font-semibold text-[15px] hover:bg-brand-dark hover:border-theme hover:-translate-y-0.5 transition-all [font-variation-settings:'wdth'_92,'opsz'_18]",children:"Website"},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 t00={name:"@brains/site-personal",version:"0.2.0-alpha.155",description:"Personal site composition package",dependencies:{"@brains/blog":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-engine":"workspace:*","@brains/site-info":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},files:["src"],private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",typecheck:"tsc --noEmit"},type:"module"};var P_0=H.object({entityDisplay:H.object({post:H.object({label:H.string().default("Post"),pluralName:H.string().optional()}).default({label:"Post"})}).default({post:{label:"Post"}})}),L_0=H.object({heading:H.string(),buttonText:H.string(),buttonLink:H.string(),subtitle:H.string().optional()}),s00=H.looseObject({name:H.string(),kind:H.enum(["professional","team","collective"]),organization:H.string().optional(),description:H.string().optional(),avatar:H.string().optional(),website:H.string().optional(),email:H.string().optional(),socialLinks:H.array(H.object({platform:H.enum(["github","instagram","linkedin","email","website"]),url:H.string(),label:H.string().optional()})).optional(),tagline:H.string().optional(),intro:H.string().optional(),story:H.string().optional()}),T_0=H.looseObject({id:H.string(),entityType:H.literal("post"),content:H.string(),created:H.string(),updated:H.string(),contentHash:H.string(),metadata:H.looseObject({title:H.string(),publishedAt:H.string().optional()}),frontmatter:H.looseObject({excerpt:H.string(),seriesName:H.string().optional(),seriesIndex:H.number().optional()}),body:H.string(),url:H.string().optional(),typeLabel:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),seriesUrl:H.string().optional(),coverImageUrl:H.string().optional(),ogImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional(),coverImageSrcset:H.string().optional(),coverImageSizes:H.string().optional()});class qD extends u8{dependencies=["blog"];constructor($={}){super("personal-site",t00,$,P_0)}async onRegister($){$.entities.extendFrontmatterSchema("anchor-profile",KJ);let w=this.config.entityDisplay.post,f=`/${w.pluralName??w.label.toLowerCase()+"s"}`,v=new gA(f);$.entities.registerDataSource(v);let U=new bA;$.entities.registerDataSource(U);let W=H.object({profile:s00,posts:H.array(T_0),postsListUrl:H.string(),cta:L_0}),X=H.object({profile:s00});$.templates.register({homepage:D2({name:"homepage",description:"Personal homepage with recent blog posts",schema:W,dataSourceId:"personal:homepage",requiredPermission:"public",layout:{component:gD}}),about:D2({name:"about",description:"About page with profile",schema:X,dataSourceId:"personal:about",requiredPermission:"public",layout:{component:bD}})}),this.logger.info("Personal site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function ID($){return new qD($??{})}var ED=[{id:"home",path:"/",title:"Home",description:"Personal site homepage",layout:"default",navigation:{show:!0,label:"Home",slot:"secondary",priority:10},sections:[{id:"homepage",template:"personal-site:homepage",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:"personal-site:about",dataQuery:{}}]}];import{jsxDEV as q6}from"preact/jsx-dev-runtime";function jD({sections:$,siteInfo:w}){let f=[...w.navigation.primary,...w.navigation.secondary].filter((v)=>v.label!=="Home");return q6("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[q6(Iv,{title:w.title,titleClassName:"font-heading font-bold text-2xl",navigation:w.navigation.primary,showThemeToggle:!0,themeToggleClassName:"bg-theme-toggle text-theme-toggle-icon hover:bg-theme-toggle-hover rounded-[10px]",...w.logo!==void 0?{logo:w.logo}:{}},void 0,!1,void 0,this),q6("main",{className:"flex-grow flex flex-col",children:$},void 0,!1,void 0,this),q6("footer",{className:"bg-footer text-footer border-t border-theme",children:q6("div",{className:"max-w-layout mx-auto flex flex-col md:flex-row justify-between items-center py-8 px-6 md:px-8",children:[q6("div",{className:"flex flex-col gap-1 mb-4 md:mb-0",children:[q6("span",{className:"text-brand font-heading font-bold text-lg",children:w.title},void 0,!1,void 0,this),w.description&&q6("span",{className:"text-theme-muted text-xs",children:w.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q6("nav",{className:"flex flex-wrap justify-center gap-x-6 gap-y-2 mb-4 md:mb-0",children:f.map((v)=>q6("a",{href:v.href,className:"text-theme-muted text-[13px] hover:text-brand transition-colors",children:v.label},v.href,!1,void 0,this))},void 0,!1,void 0,this),q6("div",{className:"flex items-center gap-4",children:[w.copyright&&q6("span",{className:"text-theme-light text-[11px]",children:w.copyright},void 0,!1,void 0,this),q6(O3,{variant:"footer",size:"sm"},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)}$2();D0();q5();$2();$2();var LU=I5.extend(wv.shape);$2();D0();$2();U6();D0();$2();var e00=H.enum(["generating","draft","queued","published","failed"]),$10=H.enum(["generating","draft","queued","published","failed"]),SD="publishedAt is required when deck status is published",mD=($)=>$.status==="published"&&!$.publishedAt,xD=($)=>{if(mD($))throw Error(SD)},t5=H.object({title:H.string(),slug:H.string().optional(),description:H.string().optional(),author:H.string().optional(),status:e00,publishedAt:H.string().datetime().optional(),event:H.string().optional(),coverImageId:H.string().optional(),ogImageId:H.string().optional()}),UG1=H.object({title:H.string(),description:H.string().optional(),status:e00,publishedAt:H.string().datetime().optional(),coverImageId:H.string().optional(),slug:H.string(),error:H.string().optional()}).superRefine(($,w)=>{if(!mD($))return;w.addIssue({code:H.ZodIssueCode.custom,path:["publishedAt"],message:SD})}),g_0=H.object({title:H.string(),description:H.string().optional(),status:$10,publishedAt:H.string().datetime().optional(),coverImageId:H.string().optional(),slug:H.string(),error:H.string().optional()}).superRefine(($,w)=>{if(!mD($))return;w.addIssue({code:"custom",path:["publishedAt"],message:SD})}),b_0=H.object({title:H.string(),slug:H.string().optional(),description:H.string().optional(),author:H.string().optional(),status:$10,publishedAt:H.string().datetime().optional(),event:H.string().optional(),coverImageId:H.string().optional(),ogImageId:H.string().optional()}),H7=g5.extend({entityType:H.literal("deck"),metadata:g_0}),qA=H7.extend({frontmatter:b_0,body:H.string(),ogImageUrl:H.string().optional()}),TU=qA.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 CD extends d${constructor(){super({entityType:"deck",purpose:"A slide-deck presentation.",schema:H7,frontmatterSchema:t5,supportsCoverImage:!0})}validateSlideStructure($){if(!/^---$/gm.test($))throw Error("Invalid deck: markdown must contain slide separators (---) to be a valid presentation")}toMarkdown($){let w=this.extractBody($.content);this.validateSlideStructure(w);let f=this.parseFrontMatter($.content,t5);xD(f);let v={...f,slug:f.slug??$.metadata.slug};return this.buildMarkdown(w,v)}fromMarkdown($){let w=this.parseFrontmatter($),f=this.extractBody($);xD(w),this.validateSlideStructure(f);let v=w.slug??p2(w.title),U=w.status;return{entityType:"deck",content:$,metadata:{slug:v,title:w.title,description:w.description,status:U,publishedAt:w.publishedAt,coverImageId:w.coverImageId}}}generateTitle($){return $.metadata.title}generateSummary($){if($.metadata.description)return $.metadata.description;return`Presentation: ${$.metadata.title}`}generateFrontMatter($){return this.toMarkdown($)}buildStub($){let w={title:$.title,slug:$.id,status:"generating"};return{content:this.buildMarkdown(`---
1586
1586
  `,w),metadata:{title:$.title,slug:$.id,status:"generating"}}}}var gU=new CD;D0();q5();var q_0=H.object({markdown:H.string().describe("Markdown content with slide separators (---)"),deck:TU.optional()}),yD=D2({name:"deck-detail",description:"Render a presentation deck as Reveal.js slides",schema:q_0,dataSourceId:"decks:entities",requiredPermission:"public",layout:{component:uz,fullscreen:!0}});q5();D0();var lD=H.object({decks:H.array(qA)}),iD=H.object({decks:H.array(TU),pageTitle:H.string().optional(),pageLabel:H.string().optional()});import{jsxDEV as nD}from"preact/jsx-dev-runtime";var I_0="Presentations",pD=({decks:$,pageLabel:w})=>{let f=$.map((U)=>({id:U.id,url:U.url,title:U.frontmatter.title,date:U.frontmatter.publishedAt??U.created,description:U.frontmatter.description}));return nD("div",{className:"deck-list bg-theme",children:nD("div",{className:"container mx-auto max-w-[1100px] px-6 py-16 md:px-12 md:py-24",children:nD(jv,{label:w&&w!=="Decks"?w:I_0,items:f},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)};Jh();class IA extends Nf{constructor(){super(lD,{title:"Deck List",mappings:[{key:"decks",label:"Decks",type:"array",itemType:"object"}]})}}var oD=D2({name:"deck-list",description:"List view of all presentation decks",schema:iD,dataSourceId:"decks:entities",requiredPermission:"public",formatter:new IA,layout:{component:pD}});D0();$2();var E_0=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")}),w10=D2({name:"decks:generation",description:"Template for AI to generate complete slide decks from prompts",schema:E_0,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are creating slide decks in a distinctive voice that blends philosophy, technology, and culture.
1587
1587
 
1588
1588
  Your task is to generate a complete slide deck based on the user's prompt.
@@ -1890,12 +1890,12 @@ ${Z}`,templateName:"decks:description"})).description,await this.reportProgress(
1890
1890
  color: var(--carousel-accent);
1891
1891
  font-weight: 600;
1892
1892
  }
1893
- `}},void 0,!1,void 0,this),U.map((Y,K)=>I$("section",{className:`deck-carousel-slide${K===0?" is-cover":""}`,children:[I$("header",{className:"deck-carousel-header",children:I$("span",{className:"deck-carousel-wordmark","aria-label":f??w,children:[I$("span",{className:"wm-primary",children:W.primary},void 0,!1,void 0,this),W.secondary!==void 0&&I$(d_0,{children:[I$("span",{className:"wm-dot",children:"."},void 0,!1,void 0,this),I$("span",{className:"wm-secondary",children:W.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),I$("div",{className:"deck-carousel-body",children:I$("div",{className:"deck-carousel-content",dangerouslySetInnerHTML:{__html:J(Y.markdown)}},void 0,!1,void 0,this)},void 0,!1,void 0,this),I$("footer",{className:"deck-carousel-footer",children:[I$("span",{className:"deck-carousel-footer-meta",children:v??w},void 0,!1,void 0,this),I$("span",{className:"deck-carousel-counter","aria-label":`Slide ${K+1} of ${X}`,children:[I$("span",{className:"deck-carousel-counter-current",children:String(K+1).padStart(2,"0")},void 0,!1,void 0,this)," / ",I$("span",{children:Z},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},K,!0,void 0,this))]},void 0,!0,void 0,this)}import{mkdtemp as a_0,rm as t_0}from"fs/promises";import{tmpdir as s_0}from"os";import{join as e_0}from"path";Z3();U6();var $R0=26214400,wR0=60000,G10=20;class $M{metadata={outputEntityType:"document"};context;renderPdf;getThemeMode;constructor($,w={}){this.context=$,this.renderPdf=w.renderPdf??iv,this.getThemeMode=w.getThemeMode??(async()=>"dark")}async resolve($){if($.sourceEntityType!=="deck")return;let w=await this.context.entityService.getEntity({entityType:"deck",id:$.sourceEntityId});if(!w)return;let f=fR0(w,{brandLabel:this.resolveBrandLabel()});if(f.slides.length>G10)throw Error(`Refusing to render carousel with ${f.slides.length} slides; maxSlides=${G10}`);let v=await this.getThemeMode(),U=await a_0(e_0(s_0(),"brain-deck-carousel-"));try{let W=await R4({outputDir:U,mediaPath:`/_media/carousel/${w.id}`,template:K10,format:"pdf",content:f,siteConfig:{title:f.title,themeMode:v},themeCSS:this.context.themeCSS}),X=await P4({rootDir:U});try{return{type:"document",data:await this.renderPdf(X.urlFor(W.urlPath),{maxBytes:$R0,timeoutMs:wR0,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${vR0(w)}-carousel.pdf`}}finally{await X.close()}}finally{await t_0(U,{recursive:!0,force:!0})}}resolveBrandLabel(){let $=this.context.domain?.trim();if($&&$.length>0)return $;let w=this.context.identity.getProfile().name;return w.length>0?w:void 0}}function fR0($,w={}){let{frontmatter:f,content:v}=J6($.content),U=typeof f.title==="string"?f.title:$.metadata.title,W=typeof f.event==="string"&&f.event.length>0?f.event:void 0,X=v.split(/^---$/gm).map((Z)=>Z.trim()).filter((Z)=>Z.length>0).map((Z)=>({markdown:Z}));return{title:U,slides:X,...w.brandLabel?{brandLabel:w.brandLabel}:{},...W?{eyebrow:W}:{}}}function vR0($){let w=$.metadata.slug;return w.length>0?w:p2($.metadata.title)}D0();import{jsxDEV as XR0}from"preact/jsx-dev-runtime";var SA="og-image",UR0="decks:og-image",H10=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()}),O10={name:UR0,pluginId:"decks",schema:H10,renderers:{image:WR0}};function WR0($){let w=H10.parse($),f=w.slideCount?`${w.slideCount} slide${w.slideCount===1?"":"s"}`:void 0;return XR0(Ev,{brandLabel:w.brandLabel??w.title,eyebrow:"Deck",title:w.title,subtitle:w.description,meta:[w.event],tag:f},void 0,!1,void 0,this)}Z3();U6();class wM{metadata={outputEntityType:"image",targetField:"ogImageId"};context;deps;constructor($,w={}){this.context=$,this.deps=w}async resolve($){if($.sourceEntityType!=="deck"||$.attachmentType!==SA)return;let w=await this.context.entityService.getEntity({entityType:"deck",id:$.sourceEntityId});if(!w)return;let{frontmatter:f,content:v}=J6(w.content),U=t5.parse(f),W=ZR0(v),X=this.resolveBrandLabel(),Z=await this.resolveCoverImageUrl(U.coverImageId),J={title:U.title,...U.description?{description:U.description}:{},...U.event?{event:U.event}:{},...W?{slideCount:W}:{},...Z?{coverImageUrl:Z}:{},...X?{brandLabel:X}:{}};return{type:"image",data:await PD({mediaPath:`/_media/og/deck/${w.id}`,template:O10,content:J,title:J.title,themeMode:"dark",themeCSS:this.context.themeCSS,tmpPrefix:"brain-deck-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${JR0(w)}-og.png`}}resolveBrandLabel(){let $=this.context.domain?.trim();if($&&$.length>0)return $;let w=this.context.identity.getProfile().name.trim();return w.length>0?w:void 0}async resolveCoverImageUrl($){if(!$)return;let w=await this.context.entityService.getEntity({entityType:"image",id:$});return w?.content.startsWith("data:image/")?w.content:void 0}}function ZR0($){return $.split(/^---$/gm).map((w)=>w.trim()).filter((w)=>w.length>0).length}function JR0($){let w=$.metadata.slug;return w.length>0?w:p2($.metadata.title)}$2();async function k10({entity:$,config:w}){let f=H7.parse($),v=h2(f.content,t5),U=v.metadata;return{$type:"ai.rizom.brain.deck",title:U.title,...U.slug&&{slug:U.slug},...U.description&&{description:U.description},body:v.content,format:"text/markdown",...U.author&&{author:U.author},...U.event&&{event:U.event},...U.publishedAt&&{publishedAt:U.publishedAt},...w.brainDid&&{brainDid:w.brainDid},...w.anchorDid&&{anchorDid:w.anchorDid},sourceEntityType:"deck",sourceEntityId:f.id,createdAt:f.created,...f.updated&&{updatedAt:f.updated}}}function fM(){return{entityType:"deck",collection:"ai.rizom.brain.deck",lexicon:a$["ai.rizom.brain.deck"],validate:!1,buildRecord:k10}}var r10={name:"@brains/decks",version:"0.2.0-alpha.154",description:"Presentation decks plugin for creating and viewing slide presentations",dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/image":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/site-info":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var AR0=H.object({prompt:H.string(),event:H.string().optional()}),KR0=H.object({title:H.string(),content:H.string()});class F10 extends J3{deps;entityType=gU.entityType;schema=gU.schema;adapter=gU;unregisterCarouselAttachmentProvider;unregisterOgImageAttachmentProvider;unregisterAtprotoProjection;constructor($={}){super("decks",r10,{},wJ);this.deps=$}createGenerationHandler($){return new eD(this.logger.child("DeckGenerationJobHandler"),$)}getTemplates(){return{"deck-detail":yD,"deck-list":oD,generation:w10,description:f10}}getDataSources(){return[new sD(this.logger)]}getEntityTypeConfig(){return{weight:1.5}}async onRegister($){this.deferPublishRegistration($),this.subscribeToPublishExecute($),this.registerCarouselAttachmentProvider($),this.registerOgImageAttachmentProvider($),this.registerEvalHandlers($),this.unregisterAtprotoProjection=K3.getInstance().register(fM()),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($){$.messaging.subscribe("system:plugins:ready",async()=>{return await $.messaging.send({type:"publish:register",payload:{entityType:"deck",provider:{name:"internal",publish:async()=>({id:"internal"})},config:{executionMode:"provider"}}}),{success:!0}})}subscribeToPublishExecute($){$.messaging.subscribe("publish:execute",async(w)=>{let{entityType:f,entityId:v}=w.payload;if(f!=="deck")return{success:!0};try{let U=await $.entityService.getEntity({entityType:"deck",id:v});if(!U)return await $.messaging.send({type:"publish:report:failure",payload:{entityType:f,entityId:v,error:`Deck not found: ${v}`}}),{success:!0};if(U.metadata.status==="published")return{success:!0};let W=new Date().toISOString(),X={...U,metadata:{...U.metadata,status:"published",publishedAt:W}};await $.entityService.updateEntity({entity:{...X,content:this.adapter.toMarkdown(X)}}),await $.messaging.send({type:"publish:report:success",payload:{entityType:f,entityId:v,result:{id:v}}})}catch(U){await $.messaging.send({type:"publish:report:failure",payload:{entityType:f,entityId:v,error:S2(U)}})}return{success:!0}})}registerCarouselAttachmentProvider($){let w={...this.deps,getThemeMode:this.deps.getThemeMode??(async()=>{try{return(await Vw($.entityService)).themeMode??"dark"}catch{return"dark"}})};this.unregisterCarouselAttachmentProvider=$.attachments.register("deck",Y10,new $M($,w))}registerOgImageAttachmentProvider($){this.unregisterOgImageAttachmentProvider=$.attachments.register("deck",SA,new wM($))}registerEvalHandlers($){$.eval.registerHandler("generateDeck",async(w)=>{let f=AR0.parse(w);return $.ai.generate({prompt:`${f.prompt}${f.event?`
1893
+ `}},void 0,!1,void 0,this),U.map((Y,K)=>I$("section",{className:`deck-carousel-slide${K===0?" is-cover":""}`,children:[I$("header",{className:"deck-carousel-header",children:I$("span",{className:"deck-carousel-wordmark","aria-label":f??w,children:[I$("span",{className:"wm-primary",children:W.primary},void 0,!1,void 0,this),W.secondary!==void 0&&I$(d_0,{children:[I$("span",{className:"wm-dot",children:"."},void 0,!1,void 0,this),I$("span",{className:"wm-secondary",children:W.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),I$("div",{className:"deck-carousel-body",children:I$("div",{className:"deck-carousel-content",dangerouslySetInnerHTML:{__html:J(Y.markdown)}},void 0,!1,void 0,this)},void 0,!1,void 0,this),I$("footer",{className:"deck-carousel-footer",children:[I$("span",{className:"deck-carousel-footer-meta",children:v??w},void 0,!1,void 0,this),I$("span",{className:"deck-carousel-counter","aria-label":`Slide ${K+1} of ${X}`,children:[I$("span",{className:"deck-carousel-counter-current",children:String(K+1).padStart(2,"0")},void 0,!1,void 0,this)," / ",I$("span",{children:Z},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},K,!0,void 0,this))]},void 0,!0,void 0,this)}import{mkdtemp as a_0,rm as t_0}from"fs/promises";import{tmpdir as s_0}from"os";import{join as e_0}from"path";Z3();U6();var $R0=26214400,wR0=60000,G10=20;class $M{metadata={outputEntityType:"document"};context;renderPdf;getThemeMode;constructor($,w={}){this.context=$,this.renderPdf=w.renderPdf??iv,this.getThemeMode=w.getThemeMode??(async()=>"dark")}async resolve($){if($.sourceEntityType!=="deck")return;let w=await this.context.entityService.getEntity({entityType:"deck",id:$.sourceEntityId});if(!w)return;let f=fR0(w,{brandLabel:this.resolveBrandLabel()});if(f.slides.length>G10)throw Error(`Refusing to render carousel with ${f.slides.length} slides; maxSlides=${G10}`);let v=await this.getThemeMode(),U=await a_0(e_0(s_0(),"brain-deck-carousel-"));try{let W=await R4({outputDir:U,mediaPath:`/_media/carousel/${w.id}`,template:K10,format:"pdf",content:f,siteConfig:{title:f.title,themeMode:v},themeCSS:this.context.themeCSS}),X=await P4({rootDir:U});try{return{type:"document",data:await this.renderPdf(X.urlFor(W.urlPath),{maxBytes:$R0,timeoutMs:wR0,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${vR0(w)}-carousel.pdf`}}finally{await X.close()}}finally{await t_0(U,{recursive:!0,force:!0})}}resolveBrandLabel(){let $=this.context.domain?.trim();if($&&$.length>0)return $;let w=this.context.identity.getProfile().name;return w.length>0?w:void 0}}function fR0($,w={}){let{frontmatter:f,content:v}=J6($.content),U=typeof f.title==="string"?f.title:$.metadata.title,W=typeof f.event==="string"&&f.event.length>0?f.event:void 0,X=v.split(/^---$/gm).map((Z)=>Z.trim()).filter((Z)=>Z.length>0).map((Z)=>({markdown:Z}));return{title:U,slides:X,...w.brandLabel?{brandLabel:w.brandLabel}:{},...W?{eyebrow:W}:{}}}function vR0($){let w=$.metadata.slug;return w.length>0?w:p2($.metadata.title)}D0();import{jsxDEV as XR0}from"preact/jsx-dev-runtime";var SA="og-image",UR0="decks:og-image",H10=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()}),O10={name:UR0,pluginId:"decks",schema:H10,renderers:{image:WR0}};function WR0($){let w=H10.parse($),f=w.slideCount?`${w.slideCount} slide${w.slideCount===1?"":"s"}`:void 0;return XR0(Ev,{brandLabel:w.brandLabel??w.title,eyebrow:"Deck",title:w.title,subtitle:w.description,meta:[w.event],tag:f},void 0,!1,void 0,this)}Z3();U6();class wM{metadata={outputEntityType:"image",targetField:"ogImageId"};context;deps;constructor($,w={}){this.context=$,this.deps=w}async resolve($){if($.sourceEntityType!=="deck"||$.attachmentType!==SA)return;let w=await this.context.entityService.getEntity({entityType:"deck",id:$.sourceEntityId});if(!w)return;let{frontmatter:f,content:v}=J6(w.content),U=t5.parse(f),W=ZR0(v),X=this.resolveBrandLabel(),Z=await this.resolveCoverImageUrl(U.coverImageId),J={title:U.title,...U.description?{description:U.description}:{},...U.event?{event:U.event}:{},...W?{slideCount:W}:{},...Z?{coverImageUrl:Z}:{},...X?{brandLabel:X}:{}};return{type:"image",data:await PD({mediaPath:`/_media/og/deck/${w.id}`,template:O10,content:J,title:J.title,themeMode:"dark",themeCSS:this.context.themeCSS,tmpPrefix:"brain-deck-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${JR0(w)}-og.png`}}resolveBrandLabel(){let $=this.context.domain?.trim();if($&&$.length>0)return $;let w=this.context.identity.getProfile().name.trim();return w.length>0?w:void 0}async resolveCoverImageUrl($){if(!$)return;let w=await this.context.entityService.getEntity({entityType:"image",id:$});return w?.content.startsWith("data:image/")?w.content:void 0}}function ZR0($){return $.split(/^---$/gm).map((w)=>w.trim()).filter((w)=>w.length>0).length}function JR0($){let w=$.metadata.slug;return w.length>0?w:p2($.metadata.title)}$2();async function k10({entity:$,config:w}){let f=H7.parse($),v=h2(f.content,t5),U=v.metadata;return{$type:"ai.rizom.brain.deck",title:U.title,...U.slug&&{slug:U.slug},...U.description&&{description:U.description},body:v.content,format:"text/markdown",...U.author&&{author:U.author},...U.event&&{event:U.event},...U.publishedAt&&{publishedAt:U.publishedAt},...w.brainDid&&{brainDid:w.brainDid},...w.anchorDid&&{anchorDid:w.anchorDid},sourceEntityType:"deck",sourceEntityId:f.id,createdAt:f.created,...f.updated&&{updatedAt:f.updated}}}function fM(){return{entityType:"deck",collection:"ai.rizom.brain.deck",lexicon:a$["ai.rizom.brain.deck"],validate:!1,buildRecord:k10}}var r10={name:"@brains/decks",version:"0.2.0-alpha.155",description:"Presentation decks plugin for creating and viewing slide presentations",dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/image":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/site-info":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},private:!0,scripts:{eval:"cd evals && bun run brain-eval",lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",test:"bun test",typecheck:"tsc --noEmit"},type:"module"};var AR0=H.object({prompt:H.string(),event:H.string().optional()}),KR0=H.object({title:H.string(),content:H.string()});class F10 extends J3{deps;entityType=gU.entityType;schema=gU.schema;adapter=gU;unregisterCarouselAttachmentProvider;unregisterOgImageAttachmentProvider;unregisterAtprotoProjection;constructor($={}){super("decks",r10,{},wJ);this.deps=$}createGenerationHandler($){return new eD(this.logger.child("DeckGenerationJobHandler"),$)}getTemplates(){return{"deck-detail":yD,"deck-list":oD,generation:w10,description:f10}}getDataSources(){return[new sD(this.logger)]}getEntityTypeConfig(){return{weight:1.5}}async onRegister($){this.deferPublishRegistration($),this.subscribeToPublishExecute($),this.registerCarouselAttachmentProvider($),this.registerOgImageAttachmentProvider($),this.registerEvalHandlers($),this.unregisterAtprotoProjection=K3.getInstance().register(fM()),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($){$.messaging.subscribe("system:plugins:ready",async()=>{return await $.messaging.send({type:"publish:register",payload:{entityType:"deck",provider:{name:"internal",publish:async()=>({id:"internal"})},config:{executionMode:"provider"}}}),{success:!0}})}subscribeToPublishExecute($){$.messaging.subscribe("publish:execute",async(w)=>{let{entityType:f,entityId:v}=w.payload;if(f!=="deck")return{success:!0};try{let U=await $.entityService.getEntity({entityType:"deck",id:v});if(!U)return await $.messaging.send({type:"publish:report:failure",payload:{entityType:f,entityId:v,error:`Deck not found: ${v}`}}),{success:!0};if(U.metadata.status==="published")return{success:!0};let W=new Date().toISOString(),X={...U,metadata:{...U.metadata,status:"published",publishedAt:W}};await $.entityService.updateEntity({entity:{...X,content:this.adapter.toMarkdown(X)}}),await $.messaging.send({type:"publish:report:success",payload:{entityType:f,entityId:v,result:{id:v}}})}catch(U){await $.messaging.send({type:"publish:report:failure",payload:{entityType:f,entityId:v,error:S2(U)}})}return{success:!0}})}registerCarouselAttachmentProvider($){let w={...this.deps,getThemeMode:this.deps.getThemeMode??(async()=>{try{return(await Vw($.entityService)).themeMode??"dark"}catch{return"dark"}})};this.unregisterCarouselAttachmentProvider=$.attachments.register("deck",Y10,new $M($,w))}registerOgImageAttachmentProvider($){this.unregisterOgImageAttachmentProvider=$.attachments.register("deck",SA,new wM($))}registerEvalHandlers($){$.eval.registerHandler("generateDeck",async(w)=>{let f=AR0.parse(w);return $.ai.generate({prompt:`${f.prompt}${f.event?`
1894
1894
 
1895
1895
  Note: This presentation is for "${f.event}".`:""}`,templateName:"decks:generation"})}),$.eval.registerHandler("generateDescription",async(w)=>{let f=KR0.parse(w);return $.ai.generate({prompt:`Title: ${f.title}
1896
1896
 
1897
1897
  Content:
1898
- ${f.content}`,templateName:"decks:description"})})}}class mA{postsListUrl;decksListUrl;id="professional:homepage-list";name="Homepage List DataSource";description="Fetches profile, blog posts, and presentation decks for homepage";constructor($,w){this.postsListUrl=$,this.decksListUrl=w}async fetch($,w,f){let v=f.entityService,[U,W,X,Z]=await Promise.all([E5(v,LU),B8(v,{entityType:"post",count:3,parse:zw}),B8(v,{entityType:"deck",count:3,parse:bU}),Vw(v)]),J={profile:U,posts:W,decks:X,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:Uv(Z.cta),sections:Z.sections??{}};return w.parse(J)}}$2();class xA{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch($,w,f){let U={profile:await E5(f.entityService,LU)};return w.parse(U)}}import{jsxDEV as M2,Fragment as OR0}from"preact/jsx-dev-runtime";var GR0="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",HR0="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",vM=({number:$,title:w,blurb:f,children:v})=>M2("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:M2("div",{className:"max-w-6xl mx-auto",children:M2("div",{className:GR0,children:[M2(Lz,{title:w,number:$,blurb:f},void 0,!1,void 0,this),M2("div",{className:HR0,"aria-hidden":"true"},void 0,!1,void 0,this),M2("div",{className:"mt-6 md:mt-0",children:v},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),UM=({profile:$,posts:w,decks:f,postsListUrl:v,decksListUrl:U,cta:W,sections:X})=>{let Z=$.tagline?.length?$.tagline:$.description,J=w.map((k)=>({id:k.id,url:k.url,title:k.metadata.title,date:k.metadata.publishedAt??k.created,description:k.frontmatter.excerpt,series:k.frontmatter.seriesName&&k.frontmatter.seriesIndex?{name:k.frontmatter.seriesName,index:k.frontmatter.seriesIndex}:void 0})),Y=f.map((k)=>({id:k.id,url:k.url,title:k.frontmatter.title||k.id,date:k.frontmatter.publishedAt??k.created,description:k.frontmatter.description})),K=$.name||"Home",G=[$.intro,$.description,Z].find((k)=>k)??"Professional site",O=Boolean($.description)||$.expertise!==void 0&&$.expertise.length>0;return M2(OR0,{children:[M2(a2,{title:K,description:G,ogType:"website"},void 0,!1,void 0,this),M2("div",{className:"homepage-list bg-theme",children:[M2("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:M2("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[$.name&&M2("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[M2("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),M2("span",{children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Z&&M2("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:QY(Z,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),$.intro&&M2("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:QY($.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),M2(vM,{number:"01",title:"Essays",blurb:X.essays?.blurb,children:M2(hY,{items:J,viewAllUrl:v,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Y.length>0&&M2(vM,{number:"02",title:"Presentations",blurb:X.presentations?.blurb,children:M2(hY,{items:Y,viewAllUrl:U,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),O&&M2(vM,{number:"03",title:"About",blurb:X.about?.blurb,children:M2("div",{className:"flex flex-col gap-8",children:[$.description&&M2("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:$.description},void 0,!1,void 0,this),$.expertise&&$.expertise.length>0&&M2(Tz,{subjects:$.expertise},void 0,!1,void 0,this),M2("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",M2("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),M2(Qz,{cta:W,variant:"editorial",socialLinks:$.socialLinks},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as O2,Fragment as kR0}from"preact/jsx-dev-runtime";var WM=({profile:$})=>{let w=`About ${$.name||"Me"}`,f=[$.description,$.intro].find((U)=>U)??"About page",v=$.expertise!==void 0&&$.expertise.length>0||Boolean($.currentFocus)||Boolean($.availability)||Boolean($.email)||Boolean($.website)||$.socialLinks!==void 0&&$.socialLinks.length>0;return O2(kR0,{children:[O2(a2,{title:w,description:f,ogType:"profile"},void 0,!1,void 0,this),O2("div",{className:"about-page bg-theme",children:[O2("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:O2("div",{className:"relative z-10 max-w-4xl mx-auto",children:[O2("h1",{className:"text-5xl md:text-6xl font-semibold mb-6 text-heading",children:["About ",$.name||"Me"]},void 0,!0,void 0,this),$.description&&O2("p",{className:"text-xl md:text-2xl text-theme-muted leading-relaxed",children:$.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),O2("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[$.story&&O2("section",{className:"content-section-reveal mb-20 md:mb-28",children:O2(h4,{markdown:$.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),v&&O2("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[$.expertise&&$.expertise.length>0&&O2("section",{children:[O2("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),O2("ul",{className:"flex flex-wrap gap-3",children:$.expertise.map((U,W)=>O2("li",{className:Mz({variant:"accent",size:"lg"}),children:U},W,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.currentFocus&&O2("section",{children:[O2("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),O2("p",{className:"text-lg text-theme leading-relaxed",children:$.currentFocus},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.availability&&O2("section",{children:[O2("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),O2("p",{className:"text-lg text-theme leading-relaxed",children:$.availability},void 0,!1,void 0,this)]},void 0,!0,void 0,this),(Boolean($.email)||Boolean($.website)||$.socialLinks!==void 0&&$.socialLinks.length>0)&&O2("section",{children:[O2("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),O2("div",{className:"space-y-4",children:[$.email&&O2("p",{className:"text-lg",children:O2("a",{href:`mailto:${$.email}`,className:"text-brand hover:text-brand-dark transition-colors",children:$.email},void 0,!1,void 0,this)},void 0,!1,void 0,this),$.website&&O2("p",{className:"text-lg",children:O2("a",{href:$.website,target:"_blank",rel:"noopener noreferrer",className:"text-brand hover:text-brand-dark transition-colors",children:$.website},void 0,!1,void 0,this)},void 0,!1,void 0,this),$.socialLinks&&$.socialLinks.length>0&&O2("div",{className:"flex flex-wrap gap-4 mt-4",children:$.socialLinks.map((U,W)=>O2(w5,{href:U.url,external:!0,variant:"secondary",size:"md",children:U.label?.length?U.label:U.platform},W,!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 E$,Fragment as u10}from"preact/jsx-dev-runtime";var XM=()=>{return E$(u10,{children:[E$(a2,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),E$("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:E$("div",{className:"text-center max-w-md",children:[E$("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),E$("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),E$("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),E$(w5,{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)},ZM=()=>{return E$(u10,{children:[E$(a2,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),E$("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:E$("div",{className:"text-center max-w-md",children:[E$("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),E$("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),E$("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),E$(w5,{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)};D0();var h10=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')")}),rR0={post:{label:"Post"},deck:{label:"Deck"}},Q10=H.object({entityDisplay:H.object({post:h10,deck:h10}).default(rR0).describe("Display metadata for post and deck entity types used by the homepage")});var N10={name:"@brains/site-professional",version:"0.2.0-alpha.154",description:"Professional site composition package",dependencies:{"@brains/blog":"workspace:*","@brains/decks":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-engine":"workspace:*","@brains/site-info":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},files:["src"],private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",typecheck:"tsc --noEmit"},type:"module"};var uR0=H.object({blurb:H.string().optional().describe("Short italic subtitle under the section title")}),hR0=H.object({heading:H.string(),buttonText:H.string(),buttonLink:H.string()}),V10=H.looseObject({name:H.string(),kind:H.enum(["professional","team","collective"]),organization:H.string().optional(),description:H.string().optional(),avatar:H.string().optional(),website:H.string().optional(),email:H.string().optional(),socialLinks:H.array(H.object({platform:H.enum(["github","instagram","linkedin","email","website"]),url:H.string(),label:H.string().optional()})).optional(),tagline:H.string().optional(),intro:H.string().optional(),story:H.string().optional(),role:H.string().optional(),audience:H.string().optional(),expertise:H.array(H.string()).optional(),currentFocus:H.string().optional(),availability:H.string().optional(),desiredTone:H.string().optional()}),QR0=H.looseObject({id:H.string(),entityType:H.literal("post"),content:H.string(),created:H.string(),updated:H.string(),contentHash:H.string(),metadata:H.looseObject({title:H.string(),publishedAt:H.string().optional()}),frontmatter:H.looseObject({excerpt:H.string(),seriesName:H.string().optional(),seriesIndex:H.number().optional()}),body:H.string(),url:H.string().optional(),typeLabel:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),seriesUrl:H.string().optional(),coverImageUrl:H.string().optional(),ogImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional(),coverImageSrcset:H.string().optional(),coverImageSizes:H.string().optional()}),NR0=H.looseObject({id:H.string(),entityType:H.literal("deck"),content:H.string(),created:H.string(),updated:H.string(),contentHash:H.string(),metadata:H.looseObject({title:H.string(),publishedAt:H.string().optional()}),frontmatter:H.looseObject({title:H.string(),description:H.string().optional(),publishedAt:H.string().optional()}),body:H.string(),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 JM extends u8{dependencies=["blog","decks"];constructor($){super("professional-site",N10,$,Q10)}async onRegister($){let w=this.config.entityDisplay.post,f=this.config.entityDisplay.deck,v=`/${w.pluralName??w.label.toLowerCase()+"s"}`,U=`/${f.pluralName??f.label.toLowerCase()+"s"}`,W=new mA(v,U);$.entities.registerDataSource(W);let X=new xA;$.entities.registerDataSource(X);let Z=H.object({profile:V10,posts:H.array(QR0),decks:H.array(NR0),postsListUrl:H.string(),decksListUrl:H.string(),cta:hR0,sections:H.record(H.string(),uR0)}),J=H.object({profile:V10}),Y=H.object({});$.templates.register({"homepage-list":D2({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:Z,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:UM}}),about:D2({name:"about",description:"About page with full profile information",schema:J,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:WM}}),"subscribe-thanks":D2({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:Y,requiredPermission:"public",layout:{component:XM}}),"subscribe-error":D2({name:"subscribe-error",description:"Newsletter subscription error page",schema:Y,requiredPermission:"public",layout:{component:ZM}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function YM($){return new JM($??{})}var AM=[{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 CA}from"preact/jsx-dev-runtime";function KM({sections:$,siteInfo:w,slots:f,wordmark:v}){return CA("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[CA(Iv,{title:w.title,navigation:w.navigation.primary,showThemeToggle:!0,...w.logo!==void 0?{logo:w.logo}:{},...v!==void 0?{wordmark:v}:{}},void 0,!1,void 0,this),CA("main",{className:"flex-grow flex flex-col bg-theme",children:$},void 0,!1,void 0,this),CA(zz,{primaryNavigation:w.navigation.primary,secondaryNavigation:w.navigation.secondary,copyright:w.copyright,socialLinks:w.socialLinks,title:w.title,tagline:w.description,children:f?.getSlot("footer-top").map((U)=>U.render())},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function z10($){return{id:$.id,version:$.version,type:$.type,packageName:$.packageName}}var Bk1=jD;function Dk1($){return z10(ID($))}var VR0=ED,Mk1=VR0,_k1=KM;function Rk1($){return z10(YM($))}var Pk1=AM;export{VR0 as routes,Rk1 as professionalSitePlugin,Pk1 as professionalRoutes,Dk1 as personalSitePlugin,Mk1 as personalRoutes,_k1 as ProfessionalLayout,Bk1 as PersonalLayout};
1898
+ ${f.content}`,templateName:"decks:description"})})}}class mA{postsListUrl;decksListUrl;id="professional:homepage-list";name="Homepage List DataSource";description="Fetches profile, blog posts, and presentation decks for homepage";constructor($,w){this.postsListUrl=$,this.decksListUrl=w}async fetch($,w,f){let v=f.entityService,[U,W,X,Z]=await Promise.all([E5(v,LU),B8(v,{entityType:"post",count:3,parse:zw}),B8(v,{entityType:"deck",count:3,parse:bU}),Vw(v)]),J={profile:U,posts:W,decks:X,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:Uv(Z.cta),sections:Z.sections??{}};return w.parse(J)}}$2();class xA{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch($,w,f){let U={profile:await E5(f.entityService,LU)};return w.parse(U)}}import{jsxDEV as M2,Fragment as OR0}from"preact/jsx-dev-runtime";var GR0="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",HR0="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",vM=({number:$,title:w,blurb:f,children:v})=>M2("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:M2("div",{className:"max-w-6xl mx-auto",children:M2("div",{className:GR0,children:[M2(Lz,{title:w,number:$,blurb:f},void 0,!1,void 0,this),M2("div",{className:HR0,"aria-hidden":"true"},void 0,!1,void 0,this),M2("div",{className:"mt-6 md:mt-0",children:v},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),UM=({profile:$,posts:w,decks:f,postsListUrl:v,decksListUrl:U,cta:W,sections:X})=>{let Z=$.tagline?.length?$.tagline:$.description,J=w.map((k)=>({id:k.id,url:k.url,title:k.metadata.title,date:k.metadata.publishedAt??k.created,description:k.frontmatter.excerpt,series:k.frontmatter.seriesName&&k.frontmatter.seriesIndex?{name:k.frontmatter.seriesName,index:k.frontmatter.seriesIndex}:void 0})),Y=f.map((k)=>({id:k.id,url:k.url,title:k.frontmatter.title||k.id,date:k.frontmatter.publishedAt??k.created,description:k.frontmatter.description})),K=$.name||"Home",G=[$.intro,$.description,Z].find((k)=>k)??"Professional site",O=Boolean($.description)||$.expertise!==void 0&&$.expertise.length>0;return M2(OR0,{children:[M2(a2,{title:K,description:G,ogType:"website"},void 0,!1,void 0,this),M2("div",{className:"homepage-list bg-theme",children:[M2("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:M2("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[$.name&&M2("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[M2("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),M2("span",{children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Z&&M2("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:QY(Z,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),$.intro&&M2("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:QY($.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),M2(vM,{number:"01",title:"Essays",blurb:X.essays?.blurb,children:M2(hY,{items:J,viewAllUrl:v,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Y.length>0&&M2(vM,{number:"02",title:"Presentations",blurb:X.presentations?.blurb,children:M2(hY,{items:Y,viewAllUrl:U,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),O&&M2(vM,{number:"03",title:"About",blurb:X.about?.blurb,children:M2("div",{className:"flex flex-col gap-8",children:[$.description&&M2("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:$.description},void 0,!1,void 0,this),$.expertise&&$.expertise.length>0&&M2(Tz,{subjects:$.expertise},void 0,!1,void 0,this),M2("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",M2("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),M2(Qz,{cta:W,variant:"editorial",socialLinks:$.socialLinks},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as O2,Fragment as kR0}from"preact/jsx-dev-runtime";var WM=({profile:$})=>{let w=`About ${$.name||"Me"}`,f=[$.description,$.intro].find((U)=>U)??"About page",v=$.expertise!==void 0&&$.expertise.length>0||Boolean($.currentFocus)||Boolean($.availability)||Boolean($.email)||Boolean($.website)||$.socialLinks!==void 0&&$.socialLinks.length>0;return O2(kR0,{children:[O2(a2,{title:w,description:f,ogType:"profile"},void 0,!1,void 0,this),O2("div",{className:"about-page bg-theme",children:[O2("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:O2("div",{className:"relative z-10 max-w-4xl mx-auto",children:[O2("h1",{className:"text-5xl md:text-6xl font-semibold mb-6 text-heading",children:["About ",$.name||"Me"]},void 0,!0,void 0,this),$.description&&O2("p",{className:"text-xl md:text-2xl text-theme-muted leading-relaxed",children:$.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),O2("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[$.story&&O2("section",{className:"content-section-reveal mb-20 md:mb-28",children:O2(h4,{markdown:$.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),v&&O2("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[$.expertise&&$.expertise.length>0&&O2("section",{children:[O2("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),O2("ul",{className:"flex flex-wrap gap-3",children:$.expertise.map((U,W)=>O2("li",{className:Mz({variant:"accent",size:"lg"}),children:U},W,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.currentFocus&&O2("section",{children:[O2("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),O2("p",{className:"text-lg text-theme leading-relaxed",children:$.currentFocus},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.availability&&O2("section",{children:[O2("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),O2("p",{className:"text-lg text-theme leading-relaxed",children:$.availability},void 0,!1,void 0,this)]},void 0,!0,void 0,this),(Boolean($.email)||Boolean($.website)||$.socialLinks!==void 0&&$.socialLinks.length>0)&&O2("section",{children:[O2("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),O2("div",{className:"space-y-4",children:[$.email&&O2("p",{className:"text-lg",children:O2("a",{href:`mailto:${$.email}`,className:"text-brand hover:text-brand-dark transition-colors",children:$.email},void 0,!1,void 0,this)},void 0,!1,void 0,this),$.website&&O2("p",{className:"text-lg",children:O2("a",{href:$.website,target:"_blank",rel:"noopener noreferrer",className:"text-brand hover:text-brand-dark transition-colors",children:$.website},void 0,!1,void 0,this)},void 0,!1,void 0,this),$.socialLinks&&$.socialLinks.length>0&&O2("div",{className:"flex flex-wrap gap-4 mt-4",children:$.socialLinks.map((U,W)=>O2(w5,{href:U.url,external:!0,variant:"secondary",size:"md",children:U.label?.length?U.label:U.platform},W,!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 E$,Fragment as u10}from"preact/jsx-dev-runtime";var XM=()=>{return E$(u10,{children:[E$(a2,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),E$("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:E$("div",{className:"text-center max-w-md",children:[E$("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),E$("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),E$("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),E$(w5,{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)},ZM=()=>{return E$(u10,{children:[E$(a2,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),E$("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:E$("div",{className:"text-center max-w-md",children:[E$("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),E$("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),E$("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),E$(w5,{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)};D0();var h10=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')")}),rR0={post:{label:"Post"},deck:{label:"Deck"}},Q10=H.object({entityDisplay:H.object({post:h10,deck:h10}).default(rR0).describe("Display metadata for post and deck entity types used by the homepage")});var N10={name:"@brains/site-professional",version:"0.2.0-alpha.155",description:"Professional site composition package",dependencies:{"@brains/blog":"workspace:*","@brains/decks":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-engine":"workspace:*","@brains/site-info":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.3.14","bun-types":"^1.3.14",eslint:"^10.5.0",typescript:"^7.0.2"},exports:{".":"./src/index.ts"},files:["src"],private:!0,scripts:{lint:"eslint . --max-warnings 0","lint:fix":"eslint . --max-warnings 0 --fix",typecheck:"tsc --noEmit"},type:"module"};var uR0=H.object({blurb:H.string().optional().describe("Short italic subtitle under the section title")}),hR0=H.object({heading:H.string(),buttonText:H.string(),buttonLink:H.string()}),V10=H.looseObject({name:H.string(),kind:H.enum(["professional","team","collective"]),organization:H.string().optional(),description:H.string().optional(),avatar:H.string().optional(),website:H.string().optional(),email:H.string().optional(),socialLinks:H.array(H.object({platform:H.enum(["github","instagram","linkedin","email","website"]),url:H.string(),label:H.string().optional()})).optional(),tagline:H.string().optional(),intro:H.string().optional(),story:H.string().optional(),role:H.string().optional(),audience:H.string().optional(),expertise:H.array(H.string()).optional(),currentFocus:H.string().optional(),availability:H.string().optional(),desiredTone:H.string().optional()}),QR0=H.looseObject({id:H.string(),entityType:H.literal("post"),content:H.string(),created:H.string(),updated:H.string(),contentHash:H.string(),metadata:H.looseObject({title:H.string(),publishedAt:H.string().optional()}),frontmatter:H.looseObject({excerpt:H.string(),seriesName:H.string().optional(),seriesIndex:H.number().optional()}),body:H.string(),url:H.string().optional(),typeLabel:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),seriesUrl:H.string().optional(),coverImageUrl:H.string().optional(),ogImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional(),coverImageSrcset:H.string().optional(),coverImageSizes:H.string().optional()}),NR0=H.looseObject({id:H.string(),entityType:H.literal("deck"),content:H.string(),created:H.string(),updated:H.string(),contentHash:H.string(),metadata:H.looseObject({title:H.string(),publishedAt:H.string().optional()}),frontmatter:H.looseObject({title:H.string(),description:H.string().optional(),publishedAt:H.string().optional()}),body:H.string(),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 JM extends u8{dependencies=["blog","decks"];constructor($){super("professional-site",N10,$,Q10)}async onRegister($){let w=this.config.entityDisplay.post,f=this.config.entityDisplay.deck,v=`/${w.pluralName??w.label.toLowerCase()+"s"}`,U=`/${f.pluralName??f.label.toLowerCase()+"s"}`,W=new mA(v,U);$.entities.registerDataSource(W);let X=new xA;$.entities.registerDataSource(X);let Z=H.object({profile:V10,posts:H.array(QR0),decks:H.array(NR0),postsListUrl:H.string(),decksListUrl:H.string(),cta:hR0,sections:H.record(H.string(),uR0)}),J=H.object({profile:V10}),Y=H.object({});$.templates.register({"homepage-list":D2({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:Z,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:UM}}),about:D2({name:"about",description:"About page with full profile information",schema:J,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:WM}}),"subscribe-thanks":D2({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:Y,requiredPermission:"public",layout:{component:XM}}),"subscribe-error":D2({name:"subscribe-error",description:"Newsletter subscription error page",schema:Y,requiredPermission:"public",layout:{component:ZM}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function YM($){return new JM($??{})}var AM=[{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 CA}from"preact/jsx-dev-runtime";function KM({sections:$,siteInfo:w,slots:f,wordmark:v}){return CA("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[CA(Iv,{title:w.title,navigation:w.navigation.primary,showThemeToggle:!0,...w.logo!==void 0?{logo:w.logo}:{},...v!==void 0?{wordmark:v}:{}},void 0,!1,void 0,this),CA("main",{className:"flex-grow flex flex-col bg-theme",children:$},void 0,!1,void 0,this),CA(zz,{primaryNavigation:w.navigation.primary,secondaryNavigation:w.navigation.secondary,copyright:w.copyright,socialLinks:w.socialLinks,title:w.title,tagline:w.description,children:f?.getSlot("footer-top").map((U)=>U.render())},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function z10($){return{id:$.id,version:$.version,type:$.type,packageName:$.packageName}}var Bk1=jD;function Dk1($){return z10(ID($))}var VR0=ED,Mk1=VR0,_k1=KM;function Rk1($){return z10(YM($))}var Pk1=AM;export{VR0 as routes,Rk1 as professionalSitePlugin,Pk1 as professionalRoutes,Dk1 as personalSitePlugin,Mk1 as personalRoutes,_k1 as ProfessionalLayout,Bk1 as PersonalLayout};
1899
1899
 
1900
- //# debugId=8DB2B2C62556C09D64756E2164756E21
1900
+ //# debugId=E476AFAE88A79D8164756E2164756E21
1901
1901
  //# sourceMappingURL=site.js.map