From 9e39119555a82a381f6cae3acf29794d212820fe Mon Sep 17 00:00:00 2001 From: Alex Dunmow Date: Sat, 4 Jul 2026 10:02:21 +0800 Subject: [PATCH] =?UTF-8?q?feat(abi):=20injection-complete=20capability=20?= =?UTF-8?q?surface=20=E2=80=94=20provisioner=20family,=20content=20authori?= =?UTF-8?q?ng,=204=20callback=20hooks=20(WO-WZ-019)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dynamic families added to the ABI + guest SDK: - provisioner.* (14 methods, 1:1 plugin.Provisioner): wasm provisioning was silently dead (RegisterWithProvisioner got a noopProvisioner and the cms loader ignored has_provisioner). Now a LOAD-TIME capability via the new CoreServices.Provisioner field; EnsureEmbed rejects RenderFunc-only embeds. - content.* writes (content.Author + CoreServices.ContentAuthor): create_page, set_page_blocks, publish_page, set_page_seo, upsert_post. - settings.update_plugin_settings (settings.Updater grows the method). - bridge.invoke + plugin.BridgeInvokable: opaque-payload cross-plugin calls (typed GetService still returns nil across the sandbox by design). - jobs.progress: HOOK_JOB handlers' progress() now crosses (was discarded). New host→guest hooks: HOOK_AI_TOOL_CALL (executes recorded ai.ToolDefinition handlers — registers tools in Register so every pooled instance has them), HOOK_BRIDGE_CALL, HOOK_DIRECTORY_PANEL_SECTION, HOOK_DIRECTORY_PIN_DECORATOR. The ai/bridge stubs now record handlers/values locally in addition to forwarding names. buf breaking clean (additive within ABI major 1); golden round-trips added for the new families (cms host replays the same goldens). Co-Authored-By: Claude Fable 5 --- abi/proto/v1/capability.proto | 286 ++ abi/proto/v1/invoke.proto | 76 + abi/v1/capability.pb.go | 2875 ++++++++++++++++- abi/v1/invoke.pb.go | 569 +++- content/author.go | 86 + plugin/bridge.go | 20 + plugin/deps.go | 7 + plugin/wasmguest/caps/ai.go | 23 +- plugin/wasmguest/caps/author.go | 120 + plugin/wasmguest/caps/bridge.go | 55 +- plugin/wasmguest/caps/caps_roundtrip_test.go | 131 + plugin/wasmguest/caps/coreservices.go | 8 +- plugin/wasmguest/caps/provisioner.go | 189 ++ plugin/wasmguest/caps/settings.go | 9 + .../caps/testdata/golden/bridge_invoke_req.pb | 3 + .../testdata/golden/bridge_invoke_resp.pb | 2 + .../golden/content_create_page_req.pb | 2 + .../golden/content_create_page_resp.pb | 2 + .../golden/content_publish_page_req.pb | 2 + .../golden/content_publish_page_resp.pb | 0 .../golden/content_set_page_blocks_req.pb | 4 + .../golden/content_set_page_blocks_resp.pb | 0 .../golden/content_set_page_seo_req.pb | 2 + .../golden/content_set_page_seo_resp.pb | 0 .../golden/content_upsert_post_req.pb | 2 + .../golden/content_upsert_post_resp.pb | 2 + .../golden/provisioner_ensure_media_req.pb | 2 + .../golden/provisioner_ensure_media_resp.pb | 0 .../provisioner_ensure_menu_item_req.pb | 2 + .../provisioner_ensure_menu_item_resp.pb | 0 .../golden/provisioner_ensure_page_req.pb | 4 + .../golden/provisioner_ensure_page_resp.pb | 0 .../provisioner_merge_site_settings_req.pb | 2 + .../provisioner_merge_site_settings_resp.pb | 0 .../settings_update_plugin_settings_req.pb | 2 + .../settings_update_plugin_settings_resp.pb | 0 plugin/wasmguest/dispatch.go | 186 +- settings/settings.go | 6 +- 38 files changed, 4552 insertions(+), 127 deletions(-) create mode 100644 content/author.go create mode 100644 plugin/wasmguest/caps/author.go create mode 100644 plugin/wasmguest/caps/provisioner.go create mode 100644 plugin/wasmguest/caps/testdata/golden/bridge_invoke_req.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/bridge_invoke_resp.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/content_create_page_req.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/content_create_page_resp.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/content_publish_page_req.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/content_publish_page_resp.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/content_set_page_blocks_req.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/content_set_page_blocks_resp.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/content_set_page_seo_req.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/content_set_page_seo_resp.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/content_upsert_post_req.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/content_upsert_post_resp.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/provisioner_ensure_media_req.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/provisioner_ensure_media_resp.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/provisioner_ensure_menu_item_req.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/provisioner_ensure_menu_item_resp.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/provisioner_ensure_page_req.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/provisioner_ensure_page_resp.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/provisioner_merge_site_settings_req.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/provisioner_merge_site_settings_resp.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/settings_update_plugin_settings_req.pb create mode 100644 plugin/wasmguest/caps/testdata/golden/settings_update_plugin_settings_resp.pb diff --git a/abi/proto/v1/capability.proto b/abi/proto/v1/capability.proto index ef9b656..6158e03 100644 --- a/abi/proto/v1/capability.proto +++ b/abi/proto/v1/capability.proto @@ -556,3 +556,289 @@ message BadgesRefreshBadgesRequest { } message BadgesRefreshBadgesResponse {} + +// --- content.* writes (content.Author, WO-WZ-019) --- +// +// Imperative page/post authoring. The idempotent seed-time counterparts live +// in the provisioner.* family below; these are for runtime authoring and for +// the WO-WZ-020 codeless seed runner. + +message ContentCreatePageRequest { + string slug = 1; + string parent_slug = 2; // "" = root + string title = 3; + string template_key = 4; + string master_page_key = 5; // "" = none +} + +message ContentCreatePageResponse { + string page_id = 1; // UUID + // False when a page with this slug already existed (the existing ID is + // returned and nothing is modified). + bool created = 2; +} + +// PageBlock is one block instance placed on a page (mirrors +// plugin.PageBlockConfig / MasterPageBlock). +message PageBlock { + string block_key = 1; + string title = 2; + // JSON encoding of the block's content map. + bytes content_json = 3; + optional string html_content = 4; + string slot = 5; + int32 sort_order = 6; +} + +message ContentSetPageBlocksRequest { + string page_id = 1; // UUID + // Full replacement set for the page's draft document blocks. + repeated PageBlock blocks = 2; +} + +message ContentSetPageBlocksResponse {} + +message ContentPublishPageRequest { + string page_id = 1; // UUID +} + +message ContentPublishPageResponse {} + +// ContentSetPageSeoRequest mirrors the CMS UpdatePageSEO surface. Unset +// optionals leave the existing value untouched. +message ContentSetPageSeoRequest { + string page_id = 1; // UUID + optional string meta_title = 2; + optional string meta_description = 3; + optional string og_title = 4; + optional string og_description = 5; + optional string og_image = 6; + optional string focus_keyphrase = 7; + optional string canonical_url = 8; + optional string robots_directive = 9; + optional string twitter_title = 10; + optional string twitter_description = 11; + optional string twitter_image = 12; +} + +message ContentSetPageSeoResponse {} + +// ContentUpsertPostRequest creates or updates a blog post by slug (posts live +// in the dedicated blog_posts table). +message ContentUpsertPostRequest { + string slug = 1; + string title = 2; + // JSON encoding of the BlockNote document. + bytes document_json = 3; + optional string excerpt = 4; + optional string author_profile_id = 5; // UUID + optional string featured_image_id = 6; // UUID (e.g. from media.deposit) + // Publish immediately after the upsert. + bool publish = 7; + bool is_featured = 8; +} + +message ContentUpsertPostResponse { + string post_id = 1; // UUID + bool created = 2; +} + +// --- provisioner.* (plugin.Provisioner, WO-WZ-019) --- +// +// Idempotent seed/ensure operations, 1:1 with the plugin.Provisioner Go +// interface. In the wasm world these are LOAD-TIME capabilities: plugins call +// deps.Provisioner from their Load hook (RegisterWithProvisioner cannot cross +// the DESCRIBE boundary — host functions are stubbed there). All methods +// check-then-create; re-running them is safe. +// +// EmbedConfig.RenderFunc deliberately does not cross: an ABI-provisioned +// embed is template-rendered host-side. A compute-rendered embed needs a +// block + hook instead. + +message ProvisionerEnsureDataTableRequest { + string key = 1; + string name = 2; + string description = 3; + // JSON schema of the table (json.RawMessage in DataTableConfig). + bytes schema_json = 4; + string primary_key = 5; +} + +message ProvisionerEnsureDataTableResponse {} + +message ProvisionerMergeSiteSettingsRequest { + // JSON encoding of the defaults map; existing keys win. + bytes defaults_json = 1; +} + +message ProvisionerMergeSiteSettingsResponse {} + +message ProvisionerEnsureSettingRequest { + string key = 1; + // JSON encoding of the default value. + bytes default_value_json = 2; +} + +message ProvisionerEnsureSettingResponse {} + +// PageSeed mirrors plugin.PageConfig. +message PageSeed { + string slug = 1; + string parent_slug = 2; + string title = 3; + string template_key = 4; + repeated PageBlock blocks = 5; + string detail_source_type = 6; + string detail_source_key = 7; + string detail_slug_field = 8; + bool reconcile_blocks = 9; + bool reconcile_template = 10; +} + +message ProvisionerEnsurePageRequest { + PageSeed page = 1; +} + +message ProvisionerEnsurePageResponse {} + +message ProvisionerOverrideSiteSettingsRequest { + // JSON encoding of the overrides map; plugin values win. + bytes overrides_json = 1; +} + +message ProvisionerOverrideSiteSettingsResponse {} + +// ProvisionerEnsureMenuItemRequest mirrors plugin.MenuItemConfig under a +// named menu. +message ProvisionerEnsureMenuItemRequest { + string menu_name = 1; + string label = 2; + string url = 3; + string page_slug = 4; + int32 sort_order = 5; +} + +message ProvisionerEnsureMenuItemResponse {} + +// ProvisionerRegisterEmbeddingConfigRequest mirrors plugin.EmbeddingConfigDef. +message ProvisionerRegisterEmbeddingConfigRequest { + string table_key = 1; + string text_template = 2; + bool enabled = 3; +} + +message ProvisionerRegisterEmbeddingConfigResponse {} + +// ProvisionerEnsureEmbedRequest mirrors plugin.EmbedConfig minus RenderFunc +// (function values cannot cross; the Template renders host-side). +message ProvisionerEnsureEmbedRequest { + string key = 1; + string title = 2; + string description = 3; + string icon = 4; + string label_field = 5; + string template = 6; + string data_source_type = 7; // EmbedDataSource.Type + string data_source_table_key = 8; // EmbedDataSource.TableKey +} + +message ProvisionerEnsureEmbedResponse {} + +// ProvisionerEnsureJobScheduleRequest mirrors plugin.JobScheduleConfig. +message ProvisionerEnsureJobScheduleRequest { + string job_type = 1; + string cron_expression = 2; + // JSON job configuration. + bytes config_json = 3; +} + +message ProvisionerEnsureJobScheduleResponse {} + +message ProvisionerUpdateDataTableRowFieldRequest { + string row_id = 1; // UUID + string field_key = 2; + // JSON encoding of the value. + bytes value_json = 3; +} + +message ProvisionerUpdateDataTableRowFieldResponse {} + +message ProvisionerDisableOrphanedJobSchedulesRequest { + repeated string registered_types = 1; +} + +message ProvisionerDisableOrphanedJobSchedulesResponse {} + +message ProvisionerEnsurePluginRequest { + string name = 1; +} + +message ProvisionerEnsurePluginResponse {} + +// ProvisionerEnsureCustomColorRequest mirrors plugin.CustomColorConfig. +message ProvisionerEnsureCustomColorRequest { + string name = 1; + string light_value = 2; + string dark_value = 3; + string source = 4; +} + +message ProvisionerEnsureCustomColorResponse {} + +// ProvisionerEnsureMediaRequest mirrors plugin.MediaDeposit with a REQUIRED +// deterministic id (the template-referable key). Idempotent: an existing id +// is a no-op; changed bytes warn rather than overwrite. +message ProvisionerEnsureMediaRequest { + string id = 1; // UUID, required + string filename = 2; + bytes data = 3; + string alt_text = 4; + string folder = 5; + string source = 6; +} + +message ProvisionerEnsureMediaResponse {} + +// --- settings.update_plugin_settings (settings.Updater, WO-WZ-019) --- + +// SettingsUpdatePluginSettingsRequest replaces the calling plugin's own +// settings map. The host binds the target plugin from the caller's identity; +// plugin_name is advisory and MUST match it (PERMISSION_DENIED otherwise). +message SettingsUpdatePluginSettingsRequest { + string plugin_name = 1; + // JSON encoding of the full settings map. + bytes settings_json = 2; +} + +message SettingsUpdatePluginSettingsResponse {} + +// --- jobs.progress (plugin.JobHandlerFunc progress callback, WO-WZ-019) --- + +// JobsProgressRequest reports progress for the CURRENTLY EXECUTING job. The +// host correlates it to the job via the invoking HOOK_JOB call's context, so +// it is only meaningful while a JOB hook is on the stack; outside one it is +// accepted and discarded. +message JobsProgressRequest { + int32 current = 1; + int32 total = 2; + string message = 3; +} + +message JobsProgressResponse {} + +// --- bridge.invoke (plugin.PluginBridge cross-plugin calls, WO-WZ-019) --- + +// BridgeInvokeRequest calls a method on another plugin's registered bridge +// service. The provider answers via HOOK_BRIDGE_CALL (wasm) or an in-process +// plugin.BridgeInvokable (bundled). Payloads are opaque bytes — the two +// plugins agree on the encoding (JSON by convention). +message BridgeInvokeRequest { + string plugin_name = 1; + string service_name = 2; + string method = 3; + bytes payload = 4; +} + +message BridgeInvokeResponse { + bytes payload = 1; +} diff --git a/abi/proto/v1/invoke.proto b/abi/proto/v1/invoke.proto index 2bd6895..c377239 100644 --- a/abi/proto/v1/invoke.proto +++ b/abi/proto/v1/invoke.proto @@ -49,6 +49,18 @@ enum Hook { // Apply a plugin-declared template filter (manifest.declared_filters): // payload = ApplyFilterRequest / ApplyFilterResponse. HOOK_APPLY_FILTER = 11; + // Execute a guest-registered AI tool handler (ai.tools.register): + // payload = AiToolCallRequest / AiToolCallResponse. + HOOK_AI_TOOL_CALL = 12; + // Invoke a method on a bridge service this plugin registered + // (bridge.register_service): payload = BridgeCallRequest / BridgeCallResponse. + HOOK_BRIDGE_CALL = 13; + // Render one directory panel section (DirectoryExtensions.PanelSections): + // payload = DirectoryPanelSectionRequest / DirectoryPanelSectionResponse. + HOOK_DIRECTORY_PANEL_SECTION = 14; + // Run one directory pin decorator (DirectoryExtensions.PinDecorators): + // payload = DirectoryPinDecoratorRequest / DirectoryPinDecoratorResponse. + HOOK_DIRECTORY_PIN_DECORATOR = 15; } // InvokeRequest is the host→guest call envelope. @@ -188,6 +200,70 @@ message MediaAnalyzedEvent { string safe_racy = 10; } +// --- AI_TOOL_CALL --- + +// AiToolCallRequest executes the guest-side Handler of a tool the plugin +// registered via ai.tools.register (ai.ToolHandler). +message AiToolCallRequest { + string slug = 1; + // JSON encoding of the params map. + bytes params_json = 2; +} + +// AiToolCallResponse mirrors ai.ToolResult. A handler-level failure travels +// in error_message (a normal tool outcome the model sees); AbiError stays +// reserved for transport/decode/panic failures. +message AiToolCallResponse { + string content = 1; + string error_message = 2; +} + +// --- BRIDGE_CALL --- + +// BridgeCallRequest asks THIS plugin (the provider) to run a method on one of +// its registered bridge services. The consumer side is the bridge.invoke +// capability; payload encoding is agreed between the two plugins (JSON by +// convention). +message BridgeCallRequest { + string service_name = 1; + string method = 2; + bytes payload = 3; +} + +message BridgeCallResponse { + bytes payload = 1; +} + +// --- DIRECTORY_PANEL_SECTION / DIRECTORY_PIN_DECORATOR --- + +// DirectoryPanelSectionRequest renders the index-th registered panel section +// (DirectoryExtensions.PanelSections[index], counted in +// manifest.directory_extensions.panel_section_count). +message DirectoryPanelSectionRequest { + uint32 index = 1; + // JSON encoding of the row data map. + bytes data_json = 2; +} + +message DirectoryPanelSectionResponse { + string html = 1; +} + +// DirectoryPinDecoratorRequest runs the index-th registered pin decorator, +// which mutates the pin map in place; the mutated pin is returned. +message DirectoryPinDecoratorRequest { + uint32 index = 1; + // JSON encoding of the pin map (mutated by the decorator). + bytes pin_json = 2; + // JSON encoding of the row data map (read-only input). + bytes data_json = 3; +} + +message DirectoryPinDecoratorResponse { + // JSON encoding of the mutated pin map. + bytes pin_json = 1; +} + // ModerationDecisionEvent mirrors plugin.ModerationDecisionEvent. message ModerationDecisionEvent { string media_id = 1; diff --git a/abi/v1/capability.pb.go b/abi/v1/capability.pb.go index de74966..695aaee 100644 --- a/abi/v1/capability.pb.go +++ b/abi/v1/capability.pb.go @@ -4864,6 +4864,2519 @@ func (*BadgesRefreshBadgesResponse) Descriptor() ([]byte, []int) { return file_v1_capability_proto_rawDescGZIP(), []int{92} } +type ContentCreatePageRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Slug string `protobuf:"bytes,1,opt,name=slug,proto3" json:"slug,omitempty"` + ParentSlug string `protobuf:"bytes,2,opt,name=parent_slug,json=parentSlug,proto3" json:"parent_slug,omitempty"` // "" = root + Title string `protobuf:"bytes,3,opt,name=title,proto3" json:"title,omitempty"` + TemplateKey string `protobuf:"bytes,4,opt,name=template_key,json=templateKey,proto3" json:"template_key,omitempty"` + MasterPageKey string `protobuf:"bytes,5,opt,name=master_page_key,json=masterPageKey,proto3" json:"master_page_key,omitempty"` // "" = none + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContentCreatePageRequest) Reset() { + *x = ContentCreatePageRequest{} + mi := &file_v1_capability_proto_msgTypes[93] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContentCreatePageRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContentCreatePageRequest) ProtoMessage() {} + +func (x *ContentCreatePageRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[93] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContentCreatePageRequest.ProtoReflect.Descriptor instead. +func (*ContentCreatePageRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{93} +} + +func (x *ContentCreatePageRequest) GetSlug() string { + if x != nil { + return x.Slug + } + return "" +} + +func (x *ContentCreatePageRequest) GetParentSlug() string { + if x != nil { + return x.ParentSlug + } + return "" +} + +func (x *ContentCreatePageRequest) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +func (x *ContentCreatePageRequest) GetTemplateKey() string { + if x != nil { + return x.TemplateKey + } + return "" +} + +func (x *ContentCreatePageRequest) GetMasterPageKey() string { + if x != nil { + return x.MasterPageKey + } + return "" +} + +type ContentCreatePageResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + PageId string `protobuf:"bytes,1,opt,name=page_id,json=pageId,proto3" json:"page_id,omitempty"` // UUID + // False when a page with this slug already existed (the existing ID is + // returned and nothing is modified). + Created bool `protobuf:"varint,2,opt,name=created,proto3" json:"created,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContentCreatePageResponse) Reset() { + *x = ContentCreatePageResponse{} + mi := &file_v1_capability_proto_msgTypes[94] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContentCreatePageResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContentCreatePageResponse) ProtoMessage() {} + +func (x *ContentCreatePageResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[94] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContentCreatePageResponse.ProtoReflect.Descriptor instead. +func (*ContentCreatePageResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{94} +} + +func (x *ContentCreatePageResponse) GetPageId() string { + if x != nil { + return x.PageId + } + return "" +} + +func (x *ContentCreatePageResponse) GetCreated() bool { + if x != nil { + return x.Created + } + return false +} + +// PageBlock is one block instance placed on a page (mirrors +// plugin.PageBlockConfig / MasterPageBlock). +type PageBlock struct { + state protoimpl.MessageState `protogen:"open.v1"` + BlockKey string `protobuf:"bytes,1,opt,name=block_key,json=blockKey,proto3" json:"block_key,omitempty"` + Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` + // JSON encoding of the block's content map. + ContentJson []byte `protobuf:"bytes,3,opt,name=content_json,json=contentJson,proto3" json:"content_json,omitempty"` + HtmlContent *string `protobuf:"bytes,4,opt,name=html_content,json=htmlContent,proto3,oneof" json:"html_content,omitempty"` + Slot string `protobuf:"bytes,5,opt,name=slot,proto3" json:"slot,omitempty"` + SortOrder int32 `protobuf:"varint,6,opt,name=sort_order,json=sortOrder,proto3" json:"sort_order,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PageBlock) Reset() { + *x = PageBlock{} + mi := &file_v1_capability_proto_msgTypes[95] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PageBlock) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PageBlock) ProtoMessage() {} + +func (x *PageBlock) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[95] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PageBlock.ProtoReflect.Descriptor instead. +func (*PageBlock) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{95} +} + +func (x *PageBlock) GetBlockKey() string { + if x != nil { + return x.BlockKey + } + return "" +} + +func (x *PageBlock) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +func (x *PageBlock) GetContentJson() []byte { + if x != nil { + return x.ContentJson + } + return nil +} + +func (x *PageBlock) GetHtmlContent() string { + if x != nil && x.HtmlContent != nil { + return *x.HtmlContent + } + return "" +} + +func (x *PageBlock) GetSlot() string { + if x != nil { + return x.Slot + } + return "" +} + +func (x *PageBlock) GetSortOrder() int32 { + if x != nil { + return x.SortOrder + } + return 0 +} + +type ContentSetPageBlocksRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + PageId string `protobuf:"bytes,1,opt,name=page_id,json=pageId,proto3" json:"page_id,omitempty"` // UUID + // Full replacement set for the page's draft document blocks. + Blocks []*PageBlock `protobuf:"bytes,2,rep,name=blocks,proto3" json:"blocks,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContentSetPageBlocksRequest) Reset() { + *x = ContentSetPageBlocksRequest{} + mi := &file_v1_capability_proto_msgTypes[96] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContentSetPageBlocksRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContentSetPageBlocksRequest) ProtoMessage() {} + +func (x *ContentSetPageBlocksRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[96] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContentSetPageBlocksRequest.ProtoReflect.Descriptor instead. +func (*ContentSetPageBlocksRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{96} +} + +func (x *ContentSetPageBlocksRequest) GetPageId() string { + if x != nil { + return x.PageId + } + return "" +} + +func (x *ContentSetPageBlocksRequest) GetBlocks() []*PageBlock { + if x != nil { + return x.Blocks + } + return nil +} + +type ContentSetPageBlocksResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContentSetPageBlocksResponse) Reset() { + *x = ContentSetPageBlocksResponse{} + mi := &file_v1_capability_proto_msgTypes[97] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContentSetPageBlocksResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContentSetPageBlocksResponse) ProtoMessage() {} + +func (x *ContentSetPageBlocksResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[97] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContentSetPageBlocksResponse.ProtoReflect.Descriptor instead. +func (*ContentSetPageBlocksResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{97} +} + +type ContentPublishPageRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + PageId string `protobuf:"bytes,1,opt,name=page_id,json=pageId,proto3" json:"page_id,omitempty"` // UUID + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContentPublishPageRequest) Reset() { + *x = ContentPublishPageRequest{} + mi := &file_v1_capability_proto_msgTypes[98] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContentPublishPageRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContentPublishPageRequest) ProtoMessage() {} + +func (x *ContentPublishPageRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[98] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContentPublishPageRequest.ProtoReflect.Descriptor instead. +func (*ContentPublishPageRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{98} +} + +func (x *ContentPublishPageRequest) GetPageId() string { + if x != nil { + return x.PageId + } + return "" +} + +type ContentPublishPageResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContentPublishPageResponse) Reset() { + *x = ContentPublishPageResponse{} + mi := &file_v1_capability_proto_msgTypes[99] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContentPublishPageResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContentPublishPageResponse) ProtoMessage() {} + +func (x *ContentPublishPageResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[99] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContentPublishPageResponse.ProtoReflect.Descriptor instead. +func (*ContentPublishPageResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{99} +} + +// ContentSetPageSeoRequest mirrors the CMS UpdatePageSEO surface. Unset +// optionals leave the existing value untouched. +type ContentSetPageSeoRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + PageId string `protobuf:"bytes,1,opt,name=page_id,json=pageId,proto3" json:"page_id,omitempty"` // UUID + MetaTitle *string `protobuf:"bytes,2,opt,name=meta_title,json=metaTitle,proto3,oneof" json:"meta_title,omitempty"` + MetaDescription *string `protobuf:"bytes,3,opt,name=meta_description,json=metaDescription,proto3,oneof" json:"meta_description,omitempty"` + OgTitle *string `protobuf:"bytes,4,opt,name=og_title,json=ogTitle,proto3,oneof" json:"og_title,omitempty"` + OgDescription *string `protobuf:"bytes,5,opt,name=og_description,json=ogDescription,proto3,oneof" json:"og_description,omitempty"` + OgImage *string `protobuf:"bytes,6,opt,name=og_image,json=ogImage,proto3,oneof" json:"og_image,omitempty"` + FocusKeyphrase *string `protobuf:"bytes,7,opt,name=focus_keyphrase,json=focusKeyphrase,proto3,oneof" json:"focus_keyphrase,omitempty"` + CanonicalUrl *string `protobuf:"bytes,8,opt,name=canonical_url,json=canonicalUrl,proto3,oneof" json:"canonical_url,omitempty"` + RobotsDirective *string `protobuf:"bytes,9,opt,name=robots_directive,json=robotsDirective,proto3,oneof" json:"robots_directive,omitempty"` + TwitterTitle *string `protobuf:"bytes,10,opt,name=twitter_title,json=twitterTitle,proto3,oneof" json:"twitter_title,omitempty"` + TwitterDescription *string `protobuf:"bytes,11,opt,name=twitter_description,json=twitterDescription,proto3,oneof" json:"twitter_description,omitempty"` + TwitterImage *string `protobuf:"bytes,12,opt,name=twitter_image,json=twitterImage,proto3,oneof" json:"twitter_image,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContentSetPageSeoRequest) Reset() { + *x = ContentSetPageSeoRequest{} + mi := &file_v1_capability_proto_msgTypes[100] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContentSetPageSeoRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContentSetPageSeoRequest) ProtoMessage() {} + +func (x *ContentSetPageSeoRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[100] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContentSetPageSeoRequest.ProtoReflect.Descriptor instead. +func (*ContentSetPageSeoRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{100} +} + +func (x *ContentSetPageSeoRequest) GetPageId() string { + if x != nil { + return x.PageId + } + return "" +} + +func (x *ContentSetPageSeoRequest) GetMetaTitle() string { + if x != nil && x.MetaTitle != nil { + return *x.MetaTitle + } + return "" +} + +func (x *ContentSetPageSeoRequest) GetMetaDescription() string { + if x != nil && x.MetaDescription != nil { + return *x.MetaDescription + } + return "" +} + +func (x *ContentSetPageSeoRequest) GetOgTitle() string { + if x != nil && x.OgTitle != nil { + return *x.OgTitle + } + return "" +} + +func (x *ContentSetPageSeoRequest) GetOgDescription() string { + if x != nil && x.OgDescription != nil { + return *x.OgDescription + } + return "" +} + +func (x *ContentSetPageSeoRequest) GetOgImage() string { + if x != nil && x.OgImage != nil { + return *x.OgImage + } + return "" +} + +func (x *ContentSetPageSeoRequest) GetFocusKeyphrase() string { + if x != nil && x.FocusKeyphrase != nil { + return *x.FocusKeyphrase + } + return "" +} + +func (x *ContentSetPageSeoRequest) GetCanonicalUrl() string { + if x != nil && x.CanonicalUrl != nil { + return *x.CanonicalUrl + } + return "" +} + +func (x *ContentSetPageSeoRequest) GetRobotsDirective() string { + if x != nil && x.RobotsDirective != nil { + return *x.RobotsDirective + } + return "" +} + +func (x *ContentSetPageSeoRequest) GetTwitterTitle() string { + if x != nil && x.TwitterTitle != nil { + return *x.TwitterTitle + } + return "" +} + +func (x *ContentSetPageSeoRequest) GetTwitterDescription() string { + if x != nil && x.TwitterDescription != nil { + return *x.TwitterDescription + } + return "" +} + +func (x *ContentSetPageSeoRequest) GetTwitterImage() string { + if x != nil && x.TwitterImage != nil { + return *x.TwitterImage + } + return "" +} + +type ContentSetPageSeoResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContentSetPageSeoResponse) Reset() { + *x = ContentSetPageSeoResponse{} + mi := &file_v1_capability_proto_msgTypes[101] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContentSetPageSeoResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContentSetPageSeoResponse) ProtoMessage() {} + +func (x *ContentSetPageSeoResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[101] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContentSetPageSeoResponse.ProtoReflect.Descriptor instead. +func (*ContentSetPageSeoResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{101} +} + +// ContentUpsertPostRequest creates or updates a blog post by slug (posts live +// in the dedicated blog_posts table). +type ContentUpsertPostRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Slug string `protobuf:"bytes,1,opt,name=slug,proto3" json:"slug,omitempty"` + Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` + // JSON encoding of the BlockNote document. + DocumentJson []byte `protobuf:"bytes,3,opt,name=document_json,json=documentJson,proto3" json:"document_json,omitempty"` + Excerpt *string `protobuf:"bytes,4,opt,name=excerpt,proto3,oneof" json:"excerpt,omitempty"` + AuthorProfileId *string `protobuf:"bytes,5,opt,name=author_profile_id,json=authorProfileId,proto3,oneof" json:"author_profile_id,omitempty"` // UUID + FeaturedImageId *string `protobuf:"bytes,6,opt,name=featured_image_id,json=featuredImageId,proto3,oneof" json:"featured_image_id,omitempty"` // UUID (e.g. from media.deposit) + // Publish immediately after the upsert. + Publish bool `protobuf:"varint,7,opt,name=publish,proto3" json:"publish,omitempty"` + IsFeatured bool `protobuf:"varint,8,opt,name=is_featured,json=isFeatured,proto3" json:"is_featured,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContentUpsertPostRequest) Reset() { + *x = ContentUpsertPostRequest{} + mi := &file_v1_capability_proto_msgTypes[102] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContentUpsertPostRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContentUpsertPostRequest) ProtoMessage() {} + +func (x *ContentUpsertPostRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[102] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContentUpsertPostRequest.ProtoReflect.Descriptor instead. +func (*ContentUpsertPostRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{102} +} + +func (x *ContentUpsertPostRequest) GetSlug() string { + if x != nil { + return x.Slug + } + return "" +} + +func (x *ContentUpsertPostRequest) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +func (x *ContentUpsertPostRequest) GetDocumentJson() []byte { + if x != nil { + return x.DocumentJson + } + return nil +} + +func (x *ContentUpsertPostRequest) GetExcerpt() string { + if x != nil && x.Excerpt != nil { + return *x.Excerpt + } + return "" +} + +func (x *ContentUpsertPostRequest) GetAuthorProfileId() string { + if x != nil && x.AuthorProfileId != nil { + return *x.AuthorProfileId + } + return "" +} + +func (x *ContentUpsertPostRequest) GetFeaturedImageId() string { + if x != nil && x.FeaturedImageId != nil { + return *x.FeaturedImageId + } + return "" +} + +func (x *ContentUpsertPostRequest) GetPublish() bool { + if x != nil { + return x.Publish + } + return false +} + +func (x *ContentUpsertPostRequest) GetIsFeatured() bool { + if x != nil { + return x.IsFeatured + } + return false +} + +type ContentUpsertPostResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + PostId string `protobuf:"bytes,1,opt,name=post_id,json=postId,proto3" json:"post_id,omitempty"` // UUID + Created bool `protobuf:"varint,2,opt,name=created,proto3" json:"created,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContentUpsertPostResponse) Reset() { + *x = ContentUpsertPostResponse{} + mi := &file_v1_capability_proto_msgTypes[103] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContentUpsertPostResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContentUpsertPostResponse) ProtoMessage() {} + +func (x *ContentUpsertPostResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[103] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContentUpsertPostResponse.ProtoReflect.Descriptor instead. +func (*ContentUpsertPostResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{103} +} + +func (x *ContentUpsertPostResponse) GetPostId() string { + if x != nil { + return x.PostId + } + return "" +} + +func (x *ContentUpsertPostResponse) GetCreated() bool { + if x != nil { + return x.Created + } + return false +} + +type ProvisionerEnsureDataTableRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + // JSON schema of the table (json.RawMessage in DataTableConfig). + SchemaJson []byte `protobuf:"bytes,4,opt,name=schema_json,json=schemaJson,proto3" json:"schema_json,omitempty"` + PrimaryKey string `protobuf:"bytes,5,opt,name=primary_key,json=primaryKey,proto3" json:"primary_key,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerEnsureDataTableRequest) Reset() { + *x = ProvisionerEnsureDataTableRequest{} + mi := &file_v1_capability_proto_msgTypes[104] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerEnsureDataTableRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerEnsureDataTableRequest) ProtoMessage() {} + +func (x *ProvisionerEnsureDataTableRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[104] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerEnsureDataTableRequest.ProtoReflect.Descriptor instead. +func (*ProvisionerEnsureDataTableRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{104} +} + +func (x *ProvisionerEnsureDataTableRequest) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *ProvisionerEnsureDataTableRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ProvisionerEnsureDataTableRequest) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *ProvisionerEnsureDataTableRequest) GetSchemaJson() []byte { + if x != nil { + return x.SchemaJson + } + return nil +} + +func (x *ProvisionerEnsureDataTableRequest) GetPrimaryKey() string { + if x != nil { + return x.PrimaryKey + } + return "" +} + +type ProvisionerEnsureDataTableResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerEnsureDataTableResponse) Reset() { + *x = ProvisionerEnsureDataTableResponse{} + mi := &file_v1_capability_proto_msgTypes[105] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerEnsureDataTableResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerEnsureDataTableResponse) ProtoMessage() {} + +func (x *ProvisionerEnsureDataTableResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[105] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerEnsureDataTableResponse.ProtoReflect.Descriptor instead. +func (*ProvisionerEnsureDataTableResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{105} +} + +type ProvisionerMergeSiteSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // JSON encoding of the defaults map; existing keys win. + DefaultsJson []byte `protobuf:"bytes,1,opt,name=defaults_json,json=defaultsJson,proto3" json:"defaults_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerMergeSiteSettingsRequest) Reset() { + *x = ProvisionerMergeSiteSettingsRequest{} + mi := &file_v1_capability_proto_msgTypes[106] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerMergeSiteSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerMergeSiteSettingsRequest) ProtoMessage() {} + +func (x *ProvisionerMergeSiteSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[106] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerMergeSiteSettingsRequest.ProtoReflect.Descriptor instead. +func (*ProvisionerMergeSiteSettingsRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{106} +} + +func (x *ProvisionerMergeSiteSettingsRequest) GetDefaultsJson() []byte { + if x != nil { + return x.DefaultsJson + } + return nil +} + +type ProvisionerMergeSiteSettingsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerMergeSiteSettingsResponse) Reset() { + *x = ProvisionerMergeSiteSettingsResponse{} + mi := &file_v1_capability_proto_msgTypes[107] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerMergeSiteSettingsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerMergeSiteSettingsResponse) ProtoMessage() {} + +func (x *ProvisionerMergeSiteSettingsResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[107] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerMergeSiteSettingsResponse.ProtoReflect.Descriptor instead. +func (*ProvisionerMergeSiteSettingsResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{107} +} + +type ProvisionerEnsureSettingRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // JSON encoding of the default value. + DefaultValueJson []byte `protobuf:"bytes,2,opt,name=default_value_json,json=defaultValueJson,proto3" json:"default_value_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerEnsureSettingRequest) Reset() { + *x = ProvisionerEnsureSettingRequest{} + mi := &file_v1_capability_proto_msgTypes[108] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerEnsureSettingRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerEnsureSettingRequest) ProtoMessage() {} + +func (x *ProvisionerEnsureSettingRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[108] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerEnsureSettingRequest.ProtoReflect.Descriptor instead. +func (*ProvisionerEnsureSettingRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{108} +} + +func (x *ProvisionerEnsureSettingRequest) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *ProvisionerEnsureSettingRequest) GetDefaultValueJson() []byte { + if x != nil { + return x.DefaultValueJson + } + return nil +} + +type ProvisionerEnsureSettingResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerEnsureSettingResponse) Reset() { + *x = ProvisionerEnsureSettingResponse{} + mi := &file_v1_capability_proto_msgTypes[109] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerEnsureSettingResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerEnsureSettingResponse) ProtoMessage() {} + +func (x *ProvisionerEnsureSettingResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[109] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerEnsureSettingResponse.ProtoReflect.Descriptor instead. +func (*ProvisionerEnsureSettingResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{109} +} + +// PageSeed mirrors plugin.PageConfig. +type PageSeed struct { + state protoimpl.MessageState `protogen:"open.v1"` + Slug string `protobuf:"bytes,1,opt,name=slug,proto3" json:"slug,omitempty"` + ParentSlug string `protobuf:"bytes,2,opt,name=parent_slug,json=parentSlug,proto3" json:"parent_slug,omitempty"` + Title string `protobuf:"bytes,3,opt,name=title,proto3" json:"title,omitempty"` + TemplateKey string `protobuf:"bytes,4,opt,name=template_key,json=templateKey,proto3" json:"template_key,omitempty"` + Blocks []*PageBlock `protobuf:"bytes,5,rep,name=blocks,proto3" json:"blocks,omitempty"` + DetailSourceType string `protobuf:"bytes,6,opt,name=detail_source_type,json=detailSourceType,proto3" json:"detail_source_type,omitempty"` + DetailSourceKey string `protobuf:"bytes,7,opt,name=detail_source_key,json=detailSourceKey,proto3" json:"detail_source_key,omitempty"` + DetailSlugField string `protobuf:"bytes,8,opt,name=detail_slug_field,json=detailSlugField,proto3" json:"detail_slug_field,omitempty"` + ReconcileBlocks bool `protobuf:"varint,9,opt,name=reconcile_blocks,json=reconcileBlocks,proto3" json:"reconcile_blocks,omitempty"` + ReconcileTemplate bool `protobuf:"varint,10,opt,name=reconcile_template,json=reconcileTemplate,proto3" json:"reconcile_template,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PageSeed) Reset() { + *x = PageSeed{} + mi := &file_v1_capability_proto_msgTypes[110] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PageSeed) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PageSeed) ProtoMessage() {} + +func (x *PageSeed) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[110] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PageSeed.ProtoReflect.Descriptor instead. +func (*PageSeed) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{110} +} + +func (x *PageSeed) GetSlug() string { + if x != nil { + return x.Slug + } + return "" +} + +func (x *PageSeed) GetParentSlug() string { + if x != nil { + return x.ParentSlug + } + return "" +} + +func (x *PageSeed) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +func (x *PageSeed) GetTemplateKey() string { + if x != nil { + return x.TemplateKey + } + return "" +} + +func (x *PageSeed) GetBlocks() []*PageBlock { + if x != nil { + return x.Blocks + } + return nil +} + +func (x *PageSeed) GetDetailSourceType() string { + if x != nil { + return x.DetailSourceType + } + return "" +} + +func (x *PageSeed) GetDetailSourceKey() string { + if x != nil { + return x.DetailSourceKey + } + return "" +} + +func (x *PageSeed) GetDetailSlugField() string { + if x != nil { + return x.DetailSlugField + } + return "" +} + +func (x *PageSeed) GetReconcileBlocks() bool { + if x != nil { + return x.ReconcileBlocks + } + return false +} + +func (x *PageSeed) GetReconcileTemplate() bool { + if x != nil { + return x.ReconcileTemplate + } + return false +} + +type ProvisionerEnsurePageRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Page *PageSeed `protobuf:"bytes,1,opt,name=page,proto3" json:"page,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerEnsurePageRequest) Reset() { + *x = ProvisionerEnsurePageRequest{} + mi := &file_v1_capability_proto_msgTypes[111] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerEnsurePageRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerEnsurePageRequest) ProtoMessage() {} + +func (x *ProvisionerEnsurePageRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[111] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerEnsurePageRequest.ProtoReflect.Descriptor instead. +func (*ProvisionerEnsurePageRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{111} +} + +func (x *ProvisionerEnsurePageRequest) GetPage() *PageSeed { + if x != nil { + return x.Page + } + return nil +} + +type ProvisionerEnsurePageResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerEnsurePageResponse) Reset() { + *x = ProvisionerEnsurePageResponse{} + mi := &file_v1_capability_proto_msgTypes[112] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerEnsurePageResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerEnsurePageResponse) ProtoMessage() {} + +func (x *ProvisionerEnsurePageResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[112] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerEnsurePageResponse.ProtoReflect.Descriptor instead. +func (*ProvisionerEnsurePageResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{112} +} + +type ProvisionerOverrideSiteSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // JSON encoding of the overrides map; plugin values win. + OverridesJson []byte `protobuf:"bytes,1,opt,name=overrides_json,json=overridesJson,proto3" json:"overrides_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerOverrideSiteSettingsRequest) Reset() { + *x = ProvisionerOverrideSiteSettingsRequest{} + mi := &file_v1_capability_proto_msgTypes[113] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerOverrideSiteSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerOverrideSiteSettingsRequest) ProtoMessage() {} + +func (x *ProvisionerOverrideSiteSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[113] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerOverrideSiteSettingsRequest.ProtoReflect.Descriptor instead. +func (*ProvisionerOverrideSiteSettingsRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{113} +} + +func (x *ProvisionerOverrideSiteSettingsRequest) GetOverridesJson() []byte { + if x != nil { + return x.OverridesJson + } + return nil +} + +type ProvisionerOverrideSiteSettingsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerOverrideSiteSettingsResponse) Reset() { + *x = ProvisionerOverrideSiteSettingsResponse{} + mi := &file_v1_capability_proto_msgTypes[114] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerOverrideSiteSettingsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerOverrideSiteSettingsResponse) ProtoMessage() {} + +func (x *ProvisionerOverrideSiteSettingsResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[114] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerOverrideSiteSettingsResponse.ProtoReflect.Descriptor instead. +func (*ProvisionerOverrideSiteSettingsResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{114} +} + +// ProvisionerEnsureMenuItemRequest mirrors plugin.MenuItemConfig under a +// named menu. +type ProvisionerEnsureMenuItemRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + MenuName string `protobuf:"bytes,1,opt,name=menu_name,json=menuName,proto3" json:"menu_name,omitempty"` + Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"` + Url string `protobuf:"bytes,3,opt,name=url,proto3" json:"url,omitempty"` + PageSlug string `protobuf:"bytes,4,opt,name=page_slug,json=pageSlug,proto3" json:"page_slug,omitempty"` + SortOrder int32 `protobuf:"varint,5,opt,name=sort_order,json=sortOrder,proto3" json:"sort_order,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerEnsureMenuItemRequest) Reset() { + *x = ProvisionerEnsureMenuItemRequest{} + mi := &file_v1_capability_proto_msgTypes[115] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerEnsureMenuItemRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerEnsureMenuItemRequest) ProtoMessage() {} + +func (x *ProvisionerEnsureMenuItemRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[115] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerEnsureMenuItemRequest.ProtoReflect.Descriptor instead. +func (*ProvisionerEnsureMenuItemRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{115} +} + +func (x *ProvisionerEnsureMenuItemRequest) GetMenuName() string { + if x != nil { + return x.MenuName + } + return "" +} + +func (x *ProvisionerEnsureMenuItemRequest) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *ProvisionerEnsureMenuItemRequest) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +func (x *ProvisionerEnsureMenuItemRequest) GetPageSlug() string { + if x != nil { + return x.PageSlug + } + return "" +} + +func (x *ProvisionerEnsureMenuItemRequest) GetSortOrder() int32 { + if x != nil { + return x.SortOrder + } + return 0 +} + +type ProvisionerEnsureMenuItemResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerEnsureMenuItemResponse) Reset() { + *x = ProvisionerEnsureMenuItemResponse{} + mi := &file_v1_capability_proto_msgTypes[116] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerEnsureMenuItemResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerEnsureMenuItemResponse) ProtoMessage() {} + +func (x *ProvisionerEnsureMenuItemResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[116] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerEnsureMenuItemResponse.ProtoReflect.Descriptor instead. +func (*ProvisionerEnsureMenuItemResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{116} +} + +// ProvisionerRegisterEmbeddingConfigRequest mirrors plugin.EmbeddingConfigDef. +type ProvisionerRegisterEmbeddingConfigRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + TableKey string `protobuf:"bytes,1,opt,name=table_key,json=tableKey,proto3" json:"table_key,omitempty"` + TextTemplate string `protobuf:"bytes,2,opt,name=text_template,json=textTemplate,proto3" json:"text_template,omitempty"` + Enabled bool `protobuf:"varint,3,opt,name=enabled,proto3" json:"enabled,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerRegisterEmbeddingConfigRequest) Reset() { + *x = ProvisionerRegisterEmbeddingConfigRequest{} + mi := &file_v1_capability_proto_msgTypes[117] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerRegisterEmbeddingConfigRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerRegisterEmbeddingConfigRequest) ProtoMessage() {} + +func (x *ProvisionerRegisterEmbeddingConfigRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[117] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerRegisterEmbeddingConfigRequest.ProtoReflect.Descriptor instead. +func (*ProvisionerRegisterEmbeddingConfigRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{117} +} + +func (x *ProvisionerRegisterEmbeddingConfigRequest) GetTableKey() string { + if x != nil { + return x.TableKey + } + return "" +} + +func (x *ProvisionerRegisterEmbeddingConfigRequest) GetTextTemplate() string { + if x != nil { + return x.TextTemplate + } + return "" +} + +func (x *ProvisionerRegisterEmbeddingConfigRequest) GetEnabled() bool { + if x != nil { + return x.Enabled + } + return false +} + +type ProvisionerRegisterEmbeddingConfigResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerRegisterEmbeddingConfigResponse) Reset() { + *x = ProvisionerRegisterEmbeddingConfigResponse{} + mi := &file_v1_capability_proto_msgTypes[118] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerRegisterEmbeddingConfigResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerRegisterEmbeddingConfigResponse) ProtoMessage() {} + +func (x *ProvisionerRegisterEmbeddingConfigResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[118] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerRegisterEmbeddingConfigResponse.ProtoReflect.Descriptor instead. +func (*ProvisionerRegisterEmbeddingConfigResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{118} +} + +// ProvisionerEnsureEmbedRequest mirrors plugin.EmbedConfig minus RenderFunc +// (function values cannot cross; the Template renders host-side). +type ProvisionerEnsureEmbedRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Icon string `protobuf:"bytes,4,opt,name=icon,proto3" json:"icon,omitempty"` + LabelField string `protobuf:"bytes,5,opt,name=label_field,json=labelField,proto3" json:"label_field,omitempty"` + Template string `protobuf:"bytes,6,opt,name=template,proto3" json:"template,omitempty"` + DataSourceType string `protobuf:"bytes,7,opt,name=data_source_type,json=dataSourceType,proto3" json:"data_source_type,omitempty"` // EmbedDataSource.Type + DataSourceTableKey string `protobuf:"bytes,8,opt,name=data_source_table_key,json=dataSourceTableKey,proto3" json:"data_source_table_key,omitempty"` // EmbedDataSource.TableKey + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerEnsureEmbedRequest) Reset() { + *x = ProvisionerEnsureEmbedRequest{} + mi := &file_v1_capability_proto_msgTypes[119] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerEnsureEmbedRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerEnsureEmbedRequest) ProtoMessage() {} + +func (x *ProvisionerEnsureEmbedRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[119] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerEnsureEmbedRequest.ProtoReflect.Descriptor instead. +func (*ProvisionerEnsureEmbedRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{119} +} + +func (x *ProvisionerEnsureEmbedRequest) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *ProvisionerEnsureEmbedRequest) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +func (x *ProvisionerEnsureEmbedRequest) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *ProvisionerEnsureEmbedRequest) GetIcon() string { + if x != nil { + return x.Icon + } + return "" +} + +func (x *ProvisionerEnsureEmbedRequest) GetLabelField() string { + if x != nil { + return x.LabelField + } + return "" +} + +func (x *ProvisionerEnsureEmbedRequest) GetTemplate() string { + if x != nil { + return x.Template + } + return "" +} + +func (x *ProvisionerEnsureEmbedRequest) GetDataSourceType() string { + if x != nil { + return x.DataSourceType + } + return "" +} + +func (x *ProvisionerEnsureEmbedRequest) GetDataSourceTableKey() string { + if x != nil { + return x.DataSourceTableKey + } + return "" +} + +type ProvisionerEnsureEmbedResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerEnsureEmbedResponse) Reset() { + *x = ProvisionerEnsureEmbedResponse{} + mi := &file_v1_capability_proto_msgTypes[120] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerEnsureEmbedResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerEnsureEmbedResponse) ProtoMessage() {} + +func (x *ProvisionerEnsureEmbedResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[120] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerEnsureEmbedResponse.ProtoReflect.Descriptor instead. +func (*ProvisionerEnsureEmbedResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{120} +} + +// ProvisionerEnsureJobScheduleRequest mirrors plugin.JobScheduleConfig. +type ProvisionerEnsureJobScheduleRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + JobType string `protobuf:"bytes,1,opt,name=job_type,json=jobType,proto3" json:"job_type,omitempty"` + CronExpression string `protobuf:"bytes,2,opt,name=cron_expression,json=cronExpression,proto3" json:"cron_expression,omitempty"` + // JSON job configuration. + ConfigJson []byte `protobuf:"bytes,3,opt,name=config_json,json=configJson,proto3" json:"config_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerEnsureJobScheduleRequest) Reset() { + *x = ProvisionerEnsureJobScheduleRequest{} + mi := &file_v1_capability_proto_msgTypes[121] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerEnsureJobScheduleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerEnsureJobScheduleRequest) ProtoMessage() {} + +func (x *ProvisionerEnsureJobScheduleRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[121] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerEnsureJobScheduleRequest.ProtoReflect.Descriptor instead. +func (*ProvisionerEnsureJobScheduleRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{121} +} + +func (x *ProvisionerEnsureJobScheduleRequest) GetJobType() string { + if x != nil { + return x.JobType + } + return "" +} + +func (x *ProvisionerEnsureJobScheduleRequest) GetCronExpression() string { + if x != nil { + return x.CronExpression + } + return "" +} + +func (x *ProvisionerEnsureJobScheduleRequest) GetConfigJson() []byte { + if x != nil { + return x.ConfigJson + } + return nil +} + +type ProvisionerEnsureJobScheduleResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerEnsureJobScheduleResponse) Reset() { + *x = ProvisionerEnsureJobScheduleResponse{} + mi := &file_v1_capability_proto_msgTypes[122] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerEnsureJobScheduleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerEnsureJobScheduleResponse) ProtoMessage() {} + +func (x *ProvisionerEnsureJobScheduleResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[122] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerEnsureJobScheduleResponse.ProtoReflect.Descriptor instead. +func (*ProvisionerEnsureJobScheduleResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{122} +} + +type ProvisionerUpdateDataTableRowFieldRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + RowId string `protobuf:"bytes,1,opt,name=row_id,json=rowId,proto3" json:"row_id,omitempty"` // UUID + FieldKey string `protobuf:"bytes,2,opt,name=field_key,json=fieldKey,proto3" json:"field_key,omitempty"` + // JSON encoding of the value. + ValueJson []byte `protobuf:"bytes,3,opt,name=value_json,json=valueJson,proto3" json:"value_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerUpdateDataTableRowFieldRequest) Reset() { + *x = ProvisionerUpdateDataTableRowFieldRequest{} + mi := &file_v1_capability_proto_msgTypes[123] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerUpdateDataTableRowFieldRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerUpdateDataTableRowFieldRequest) ProtoMessage() {} + +func (x *ProvisionerUpdateDataTableRowFieldRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[123] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerUpdateDataTableRowFieldRequest.ProtoReflect.Descriptor instead. +func (*ProvisionerUpdateDataTableRowFieldRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{123} +} + +func (x *ProvisionerUpdateDataTableRowFieldRequest) GetRowId() string { + if x != nil { + return x.RowId + } + return "" +} + +func (x *ProvisionerUpdateDataTableRowFieldRequest) GetFieldKey() string { + if x != nil { + return x.FieldKey + } + return "" +} + +func (x *ProvisionerUpdateDataTableRowFieldRequest) GetValueJson() []byte { + if x != nil { + return x.ValueJson + } + return nil +} + +type ProvisionerUpdateDataTableRowFieldResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerUpdateDataTableRowFieldResponse) Reset() { + *x = ProvisionerUpdateDataTableRowFieldResponse{} + mi := &file_v1_capability_proto_msgTypes[124] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerUpdateDataTableRowFieldResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerUpdateDataTableRowFieldResponse) ProtoMessage() {} + +func (x *ProvisionerUpdateDataTableRowFieldResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[124] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerUpdateDataTableRowFieldResponse.ProtoReflect.Descriptor instead. +func (*ProvisionerUpdateDataTableRowFieldResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{124} +} + +type ProvisionerDisableOrphanedJobSchedulesRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + RegisteredTypes []string `protobuf:"bytes,1,rep,name=registered_types,json=registeredTypes,proto3" json:"registered_types,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerDisableOrphanedJobSchedulesRequest) Reset() { + *x = ProvisionerDisableOrphanedJobSchedulesRequest{} + mi := &file_v1_capability_proto_msgTypes[125] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerDisableOrphanedJobSchedulesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerDisableOrphanedJobSchedulesRequest) ProtoMessage() {} + +func (x *ProvisionerDisableOrphanedJobSchedulesRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[125] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerDisableOrphanedJobSchedulesRequest.ProtoReflect.Descriptor instead. +func (*ProvisionerDisableOrphanedJobSchedulesRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{125} +} + +func (x *ProvisionerDisableOrphanedJobSchedulesRequest) GetRegisteredTypes() []string { + if x != nil { + return x.RegisteredTypes + } + return nil +} + +type ProvisionerDisableOrphanedJobSchedulesResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerDisableOrphanedJobSchedulesResponse) Reset() { + *x = ProvisionerDisableOrphanedJobSchedulesResponse{} + mi := &file_v1_capability_proto_msgTypes[126] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerDisableOrphanedJobSchedulesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerDisableOrphanedJobSchedulesResponse) ProtoMessage() {} + +func (x *ProvisionerDisableOrphanedJobSchedulesResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[126] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerDisableOrphanedJobSchedulesResponse.ProtoReflect.Descriptor instead. +func (*ProvisionerDisableOrphanedJobSchedulesResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{126} +} + +type ProvisionerEnsurePluginRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerEnsurePluginRequest) Reset() { + *x = ProvisionerEnsurePluginRequest{} + mi := &file_v1_capability_proto_msgTypes[127] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerEnsurePluginRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerEnsurePluginRequest) ProtoMessage() {} + +func (x *ProvisionerEnsurePluginRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[127] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerEnsurePluginRequest.ProtoReflect.Descriptor instead. +func (*ProvisionerEnsurePluginRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{127} +} + +func (x *ProvisionerEnsurePluginRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type ProvisionerEnsurePluginResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerEnsurePluginResponse) Reset() { + *x = ProvisionerEnsurePluginResponse{} + mi := &file_v1_capability_proto_msgTypes[128] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerEnsurePluginResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerEnsurePluginResponse) ProtoMessage() {} + +func (x *ProvisionerEnsurePluginResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[128] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerEnsurePluginResponse.ProtoReflect.Descriptor instead. +func (*ProvisionerEnsurePluginResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{128} +} + +// ProvisionerEnsureCustomColorRequest mirrors plugin.CustomColorConfig. +type ProvisionerEnsureCustomColorRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + LightValue string `protobuf:"bytes,2,opt,name=light_value,json=lightValue,proto3" json:"light_value,omitempty"` + DarkValue string `protobuf:"bytes,3,opt,name=dark_value,json=darkValue,proto3" json:"dark_value,omitempty"` + Source string `protobuf:"bytes,4,opt,name=source,proto3" json:"source,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerEnsureCustomColorRequest) Reset() { + *x = ProvisionerEnsureCustomColorRequest{} + mi := &file_v1_capability_proto_msgTypes[129] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerEnsureCustomColorRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerEnsureCustomColorRequest) ProtoMessage() {} + +func (x *ProvisionerEnsureCustomColorRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[129] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerEnsureCustomColorRequest.ProtoReflect.Descriptor instead. +func (*ProvisionerEnsureCustomColorRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{129} +} + +func (x *ProvisionerEnsureCustomColorRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ProvisionerEnsureCustomColorRequest) GetLightValue() string { + if x != nil { + return x.LightValue + } + return "" +} + +func (x *ProvisionerEnsureCustomColorRequest) GetDarkValue() string { + if x != nil { + return x.DarkValue + } + return "" +} + +func (x *ProvisionerEnsureCustomColorRequest) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +type ProvisionerEnsureCustomColorResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerEnsureCustomColorResponse) Reset() { + *x = ProvisionerEnsureCustomColorResponse{} + mi := &file_v1_capability_proto_msgTypes[130] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerEnsureCustomColorResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerEnsureCustomColorResponse) ProtoMessage() {} + +func (x *ProvisionerEnsureCustomColorResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[130] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerEnsureCustomColorResponse.ProtoReflect.Descriptor instead. +func (*ProvisionerEnsureCustomColorResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{130} +} + +// ProvisionerEnsureMediaRequest mirrors plugin.MediaDeposit with a REQUIRED +// deterministic id (the template-referable key). Idempotent: an existing id +// is a no-op; changed bytes warn rather than overwrite. +type ProvisionerEnsureMediaRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // UUID, required + Filename string `protobuf:"bytes,2,opt,name=filename,proto3" json:"filename,omitempty"` + Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + AltText string `protobuf:"bytes,4,opt,name=alt_text,json=altText,proto3" json:"alt_text,omitempty"` + Folder string `protobuf:"bytes,5,opt,name=folder,proto3" json:"folder,omitempty"` + Source string `protobuf:"bytes,6,opt,name=source,proto3" json:"source,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerEnsureMediaRequest) Reset() { + *x = ProvisionerEnsureMediaRequest{} + mi := &file_v1_capability_proto_msgTypes[131] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerEnsureMediaRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerEnsureMediaRequest) ProtoMessage() {} + +func (x *ProvisionerEnsureMediaRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[131] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerEnsureMediaRequest.ProtoReflect.Descriptor instead. +func (*ProvisionerEnsureMediaRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{131} +} + +func (x *ProvisionerEnsureMediaRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ProvisionerEnsureMediaRequest) GetFilename() string { + if x != nil { + return x.Filename + } + return "" +} + +func (x *ProvisionerEnsureMediaRequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *ProvisionerEnsureMediaRequest) GetAltText() string { + if x != nil { + return x.AltText + } + return "" +} + +func (x *ProvisionerEnsureMediaRequest) GetFolder() string { + if x != nil { + return x.Folder + } + return "" +} + +func (x *ProvisionerEnsureMediaRequest) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +type ProvisionerEnsureMediaResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProvisionerEnsureMediaResponse) Reset() { + *x = ProvisionerEnsureMediaResponse{} + mi := &file_v1_capability_proto_msgTypes[132] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProvisionerEnsureMediaResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProvisionerEnsureMediaResponse) ProtoMessage() {} + +func (x *ProvisionerEnsureMediaResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[132] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProvisionerEnsureMediaResponse.ProtoReflect.Descriptor instead. +func (*ProvisionerEnsureMediaResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{132} +} + +// SettingsUpdatePluginSettingsRequest replaces the calling plugin's own +// settings map. The host binds the target plugin from the caller's identity; +// plugin_name is advisory and MUST match it (PERMISSION_DENIED otherwise). +type SettingsUpdatePluginSettingsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + PluginName string `protobuf:"bytes,1,opt,name=plugin_name,json=pluginName,proto3" json:"plugin_name,omitempty"` + // JSON encoding of the full settings map. + SettingsJson []byte `protobuf:"bytes,2,opt,name=settings_json,json=settingsJson,proto3" json:"settings_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SettingsUpdatePluginSettingsRequest) Reset() { + *x = SettingsUpdatePluginSettingsRequest{} + mi := &file_v1_capability_proto_msgTypes[133] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SettingsUpdatePluginSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SettingsUpdatePluginSettingsRequest) ProtoMessage() {} + +func (x *SettingsUpdatePluginSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[133] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SettingsUpdatePluginSettingsRequest.ProtoReflect.Descriptor instead. +func (*SettingsUpdatePluginSettingsRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{133} +} + +func (x *SettingsUpdatePluginSettingsRequest) GetPluginName() string { + if x != nil { + return x.PluginName + } + return "" +} + +func (x *SettingsUpdatePluginSettingsRequest) GetSettingsJson() []byte { + if x != nil { + return x.SettingsJson + } + return nil +} + +type SettingsUpdatePluginSettingsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SettingsUpdatePluginSettingsResponse) Reset() { + *x = SettingsUpdatePluginSettingsResponse{} + mi := &file_v1_capability_proto_msgTypes[134] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SettingsUpdatePluginSettingsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SettingsUpdatePluginSettingsResponse) ProtoMessage() {} + +func (x *SettingsUpdatePluginSettingsResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[134] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SettingsUpdatePluginSettingsResponse.ProtoReflect.Descriptor instead. +func (*SettingsUpdatePluginSettingsResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{134} +} + +// JobsProgressRequest reports progress for the CURRENTLY EXECUTING job. The +// host correlates it to the job via the invoking HOOK_JOB call's context, so +// it is only meaningful while a JOB hook is on the stack; outside one it is +// accepted and discarded. +type JobsProgressRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Current int32 `protobuf:"varint,1,opt,name=current,proto3" json:"current,omitempty"` + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` + Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JobsProgressRequest) Reset() { + *x = JobsProgressRequest{} + mi := &file_v1_capability_proto_msgTypes[135] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobsProgressRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobsProgressRequest) ProtoMessage() {} + +func (x *JobsProgressRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[135] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobsProgressRequest.ProtoReflect.Descriptor instead. +func (*JobsProgressRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{135} +} + +func (x *JobsProgressRequest) GetCurrent() int32 { + if x != nil { + return x.Current + } + return 0 +} + +func (x *JobsProgressRequest) GetTotal() int32 { + if x != nil { + return x.Total + } + return 0 +} + +func (x *JobsProgressRequest) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type JobsProgressResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JobsProgressResponse) Reset() { + *x = JobsProgressResponse{} + mi := &file_v1_capability_proto_msgTypes[136] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobsProgressResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobsProgressResponse) ProtoMessage() {} + +func (x *JobsProgressResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[136] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobsProgressResponse.ProtoReflect.Descriptor instead. +func (*JobsProgressResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{136} +} + +// BridgeInvokeRequest calls a method on another plugin's registered bridge +// service. The provider answers via HOOK_BRIDGE_CALL (wasm) or an in-process +// plugin.BridgeInvokable (bundled). Payloads are opaque bytes — the two +// plugins agree on the encoding (JSON by convention). +type BridgeInvokeRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + PluginName string `protobuf:"bytes,1,opt,name=plugin_name,json=pluginName,proto3" json:"plugin_name,omitempty"` + ServiceName string `protobuf:"bytes,2,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` + Method string `protobuf:"bytes,3,opt,name=method,proto3" json:"method,omitempty"` + Payload []byte `protobuf:"bytes,4,opt,name=payload,proto3" json:"payload,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BridgeInvokeRequest) Reset() { + *x = BridgeInvokeRequest{} + mi := &file_v1_capability_proto_msgTypes[137] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BridgeInvokeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BridgeInvokeRequest) ProtoMessage() {} + +func (x *BridgeInvokeRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[137] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BridgeInvokeRequest.ProtoReflect.Descriptor instead. +func (*BridgeInvokeRequest) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{137} +} + +func (x *BridgeInvokeRequest) GetPluginName() string { + if x != nil { + return x.PluginName + } + return "" +} + +func (x *BridgeInvokeRequest) GetServiceName() string { + if x != nil { + return x.ServiceName + } + return "" +} + +func (x *BridgeInvokeRequest) GetMethod() string { + if x != nil { + return x.Method + } + return "" +} + +func (x *BridgeInvokeRequest) GetPayload() []byte { + if x != nil { + return x.Payload + } + return nil +} + +type BridgeInvokeResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BridgeInvokeResponse) Reset() { + *x = BridgeInvokeResponse{} + mi := &file_v1_capability_proto_msgTypes[138] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BridgeInvokeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BridgeInvokeResponse) ProtoMessage() {} + +func (x *BridgeInvokeResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_capability_proto_msgTypes[138] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BridgeInvokeResponse.ProtoReflect.Descriptor instead. +func (*BridgeInvokeResponse) Descriptor() ([]byte, []int) { + return file_v1_capability_proto_rawDescGZIP(), []int{138} +} + +func (x *BridgeInvokeResponse) GetPayload() []byte { + if x != nil { + return x.Payload + } + return nil +} + var File_v1_capability_proto protoreflect.FileDescriptor const file_v1_capability_proto_rawDesc = "" + @@ -5176,7 +7689,189 @@ const file_v1_capability_proto_rawDesc = "" + "\x1aBadgesRefreshBadgesRequest\x12\x19\n" + "\btable_id\x18\x01 \x01(\tR\atableId\x12\x15\n" + "\x06row_id\x18\x02 \x01(\tR\x05rowId\"\x1d\n" + - "\x1bBadgesRefreshBadgesResponseB0Z.git.dev.alexdunmow.com/block/core/abi/v1;abiv1b\x06proto3" + "\x1bBadgesRefreshBadgesResponse\"\xb0\x01\n" + + "\x18ContentCreatePageRequest\x12\x12\n" + + "\x04slug\x18\x01 \x01(\tR\x04slug\x12\x1f\n" + + "\vparent_slug\x18\x02 \x01(\tR\n" + + "parentSlug\x12\x14\n" + + "\x05title\x18\x03 \x01(\tR\x05title\x12!\n" + + "\ftemplate_key\x18\x04 \x01(\tR\vtemplateKey\x12&\n" + + "\x0fmaster_page_key\x18\x05 \x01(\tR\rmasterPageKey\"N\n" + + "\x19ContentCreatePageResponse\x12\x17\n" + + "\apage_id\x18\x01 \x01(\tR\x06pageId\x12\x18\n" + + "\acreated\x18\x02 \x01(\bR\acreated\"\xcd\x01\n" + + "\tPageBlock\x12\x1b\n" + + "\tblock_key\x18\x01 \x01(\tR\bblockKey\x12\x14\n" + + "\x05title\x18\x02 \x01(\tR\x05title\x12!\n" + + "\fcontent_json\x18\x03 \x01(\fR\vcontentJson\x12&\n" + + "\fhtml_content\x18\x04 \x01(\tH\x00R\vhtmlContent\x88\x01\x01\x12\x12\n" + + "\x04slot\x18\x05 \x01(\tR\x04slot\x12\x1d\n" + + "\n" + + "sort_order\x18\x06 \x01(\x05R\tsortOrderB\x0f\n" + + "\r_html_content\"a\n" + + "\x1bContentSetPageBlocksRequest\x12\x17\n" + + "\apage_id\x18\x01 \x01(\tR\x06pageId\x12)\n" + + "\x06blocks\x18\x02 \x03(\v2\x11.abi.v1.PageBlockR\x06blocks\"\x1e\n" + + "\x1cContentSetPageBlocksResponse\"4\n" + + "\x19ContentPublishPageRequest\x12\x17\n" + + "\apage_id\x18\x01 \x01(\tR\x06pageId\"\x1c\n" + + "\x1aContentPublishPageResponse\"\xcd\x05\n" + + "\x18ContentSetPageSeoRequest\x12\x17\n" + + "\apage_id\x18\x01 \x01(\tR\x06pageId\x12\"\n" + + "\n" + + "meta_title\x18\x02 \x01(\tH\x00R\tmetaTitle\x88\x01\x01\x12.\n" + + "\x10meta_description\x18\x03 \x01(\tH\x01R\x0fmetaDescription\x88\x01\x01\x12\x1e\n" + + "\bog_title\x18\x04 \x01(\tH\x02R\aogTitle\x88\x01\x01\x12*\n" + + "\x0eog_description\x18\x05 \x01(\tH\x03R\rogDescription\x88\x01\x01\x12\x1e\n" + + "\bog_image\x18\x06 \x01(\tH\x04R\aogImage\x88\x01\x01\x12,\n" + + "\x0ffocus_keyphrase\x18\a \x01(\tH\x05R\x0efocusKeyphrase\x88\x01\x01\x12(\n" + + "\rcanonical_url\x18\b \x01(\tH\x06R\fcanonicalUrl\x88\x01\x01\x12.\n" + + "\x10robots_directive\x18\t \x01(\tH\aR\x0frobotsDirective\x88\x01\x01\x12(\n" + + "\rtwitter_title\x18\n" + + " \x01(\tH\bR\ftwitterTitle\x88\x01\x01\x124\n" + + "\x13twitter_description\x18\v \x01(\tH\tR\x12twitterDescription\x88\x01\x01\x12(\n" + + "\rtwitter_image\x18\f \x01(\tH\n" + + "R\ftwitterImage\x88\x01\x01B\r\n" + + "\v_meta_titleB\x13\n" + + "\x11_meta_descriptionB\v\n" + + "\t_og_titleB\x11\n" + + "\x0f_og_descriptionB\v\n" + + "\t_og_imageB\x12\n" + + "\x10_focus_keyphraseB\x10\n" + + "\x0e_canonical_urlB\x13\n" + + "\x11_robots_directiveB\x10\n" + + "\x0e_twitter_titleB\x16\n" + + "\x14_twitter_descriptionB\x10\n" + + "\x0e_twitter_image\"\x1b\n" + + "\x19ContentSetPageSeoResponse\"\xdd\x02\n" + + "\x18ContentUpsertPostRequest\x12\x12\n" + + "\x04slug\x18\x01 \x01(\tR\x04slug\x12\x14\n" + + "\x05title\x18\x02 \x01(\tR\x05title\x12#\n" + + "\rdocument_json\x18\x03 \x01(\fR\fdocumentJson\x12\x1d\n" + + "\aexcerpt\x18\x04 \x01(\tH\x00R\aexcerpt\x88\x01\x01\x12/\n" + + "\x11author_profile_id\x18\x05 \x01(\tH\x01R\x0fauthorProfileId\x88\x01\x01\x12/\n" + + "\x11featured_image_id\x18\x06 \x01(\tH\x02R\x0ffeaturedImageId\x88\x01\x01\x12\x18\n" + + "\apublish\x18\a \x01(\bR\apublish\x12\x1f\n" + + "\vis_featured\x18\b \x01(\bR\n" + + "isFeaturedB\n" + + "\n" + + "\b_excerptB\x14\n" + + "\x12_author_profile_idB\x14\n" + + "\x12_featured_image_id\"N\n" + + "\x19ContentUpsertPostResponse\x12\x17\n" + + "\apost_id\x18\x01 \x01(\tR\x06postId\x12\x18\n" + + "\acreated\x18\x02 \x01(\bR\acreated\"\xad\x01\n" + + "!ProvisionerEnsureDataTableRequest\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12 \n" + + "\vdescription\x18\x03 \x01(\tR\vdescription\x12\x1f\n" + + "\vschema_json\x18\x04 \x01(\fR\n" + + "schemaJson\x12\x1f\n" + + "\vprimary_key\x18\x05 \x01(\tR\n" + + "primaryKey\"$\n" + + "\"ProvisionerEnsureDataTableResponse\"J\n" + + "#ProvisionerMergeSiteSettingsRequest\x12#\n" + + "\rdefaults_json\x18\x01 \x01(\fR\fdefaultsJson\"&\n" + + "$ProvisionerMergeSiteSettingsResponse\"a\n" + + "\x1fProvisionerEnsureSettingRequest\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12,\n" + + "\x12default_value_json\x18\x02 \x01(\fR\x10defaultValueJson\"\"\n" + + " ProvisionerEnsureSettingResponse\"\x83\x03\n" + + "\bPageSeed\x12\x12\n" + + "\x04slug\x18\x01 \x01(\tR\x04slug\x12\x1f\n" + + "\vparent_slug\x18\x02 \x01(\tR\n" + + "parentSlug\x12\x14\n" + + "\x05title\x18\x03 \x01(\tR\x05title\x12!\n" + + "\ftemplate_key\x18\x04 \x01(\tR\vtemplateKey\x12)\n" + + "\x06blocks\x18\x05 \x03(\v2\x11.abi.v1.PageBlockR\x06blocks\x12,\n" + + "\x12detail_source_type\x18\x06 \x01(\tR\x10detailSourceType\x12*\n" + + "\x11detail_source_key\x18\a \x01(\tR\x0fdetailSourceKey\x12*\n" + + "\x11detail_slug_field\x18\b \x01(\tR\x0fdetailSlugField\x12)\n" + + "\x10reconcile_blocks\x18\t \x01(\bR\x0freconcileBlocks\x12-\n" + + "\x12reconcile_template\x18\n" + + " \x01(\bR\x11reconcileTemplate\"D\n" + + "\x1cProvisionerEnsurePageRequest\x12$\n" + + "\x04page\x18\x01 \x01(\v2\x10.abi.v1.PageSeedR\x04page\"\x1f\n" + + "\x1dProvisionerEnsurePageResponse\"O\n" + + "&ProvisionerOverrideSiteSettingsRequest\x12%\n" + + "\x0eoverrides_json\x18\x01 \x01(\fR\roverridesJson\")\n" + + "'ProvisionerOverrideSiteSettingsResponse\"\xa3\x01\n" + + " ProvisionerEnsureMenuItemRequest\x12\x1b\n" + + "\tmenu_name\x18\x01 \x01(\tR\bmenuName\x12\x14\n" + + "\x05label\x18\x02 \x01(\tR\x05label\x12\x10\n" + + "\x03url\x18\x03 \x01(\tR\x03url\x12\x1b\n" + + "\tpage_slug\x18\x04 \x01(\tR\bpageSlug\x12\x1d\n" + + "\n" + + "sort_order\x18\x05 \x01(\x05R\tsortOrder\"#\n" + + "!ProvisionerEnsureMenuItemResponse\"\x87\x01\n" + + ")ProvisionerRegisterEmbeddingConfigRequest\x12\x1b\n" + + "\ttable_key\x18\x01 \x01(\tR\btableKey\x12#\n" + + "\rtext_template\x18\x02 \x01(\tR\ftextTemplate\x12\x18\n" + + "\aenabled\x18\x03 \x01(\bR\aenabled\",\n" + + "*ProvisionerRegisterEmbeddingConfigResponse\"\x97\x02\n" + + "\x1dProvisionerEnsureEmbedRequest\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05title\x18\x02 \x01(\tR\x05title\x12 \n" + + "\vdescription\x18\x03 \x01(\tR\vdescription\x12\x12\n" + + "\x04icon\x18\x04 \x01(\tR\x04icon\x12\x1f\n" + + "\vlabel_field\x18\x05 \x01(\tR\n" + + "labelField\x12\x1a\n" + + "\btemplate\x18\x06 \x01(\tR\btemplate\x12(\n" + + "\x10data_source_type\x18\a \x01(\tR\x0edataSourceType\x121\n" + + "\x15data_source_table_key\x18\b \x01(\tR\x12dataSourceTableKey\" \n" + + "\x1eProvisionerEnsureEmbedResponse\"\x8a\x01\n" + + "#ProvisionerEnsureJobScheduleRequest\x12\x19\n" + + "\bjob_type\x18\x01 \x01(\tR\ajobType\x12'\n" + + "\x0fcron_expression\x18\x02 \x01(\tR\x0ecronExpression\x12\x1f\n" + + "\vconfig_json\x18\x03 \x01(\fR\n" + + "configJson\"&\n" + + "$ProvisionerEnsureJobScheduleResponse\"~\n" + + ")ProvisionerUpdateDataTableRowFieldRequest\x12\x15\n" + + "\x06row_id\x18\x01 \x01(\tR\x05rowId\x12\x1b\n" + + "\tfield_key\x18\x02 \x01(\tR\bfieldKey\x12\x1d\n" + + "\n" + + "value_json\x18\x03 \x01(\fR\tvalueJson\",\n" + + "*ProvisionerUpdateDataTableRowFieldResponse\"Z\n" + + "-ProvisionerDisableOrphanedJobSchedulesRequest\x12)\n" + + "\x10registered_types\x18\x01 \x03(\tR\x0fregisteredTypes\"0\n" + + ".ProvisionerDisableOrphanedJobSchedulesResponse\"4\n" + + "\x1eProvisionerEnsurePluginRequest\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\"!\n" + + "\x1fProvisionerEnsurePluginResponse\"\x91\x01\n" + + "#ProvisionerEnsureCustomColorRequest\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x1f\n" + + "\vlight_value\x18\x02 \x01(\tR\n" + + "lightValue\x12\x1d\n" + + "\n" + + "dark_value\x18\x03 \x01(\tR\tdarkValue\x12\x16\n" + + "\x06source\x18\x04 \x01(\tR\x06source\"&\n" + + "$ProvisionerEnsureCustomColorResponse\"\xaa\x01\n" + + "\x1dProvisionerEnsureMediaRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x1a\n" + + "\bfilename\x18\x02 \x01(\tR\bfilename\x12\x12\n" + + "\x04data\x18\x03 \x01(\fR\x04data\x12\x19\n" + + "\balt_text\x18\x04 \x01(\tR\aaltText\x12\x16\n" + + "\x06folder\x18\x05 \x01(\tR\x06folder\x12\x16\n" + + "\x06source\x18\x06 \x01(\tR\x06source\" \n" + + "\x1eProvisionerEnsureMediaResponse\"k\n" + + "#SettingsUpdatePluginSettingsRequest\x12\x1f\n" + + "\vplugin_name\x18\x01 \x01(\tR\n" + + "pluginName\x12#\n" + + "\rsettings_json\x18\x02 \x01(\fR\fsettingsJson\"&\n" + + "$SettingsUpdatePluginSettingsResponse\"_\n" + + "\x13JobsProgressRequest\x12\x18\n" + + "\acurrent\x18\x01 \x01(\x05R\acurrent\x12\x14\n" + + "\x05total\x18\x02 \x01(\x05R\x05total\x12\x18\n" + + "\amessage\x18\x03 \x01(\tR\amessage\"\x16\n" + + "\x14JobsProgressResponse\"\x8b\x01\n" + + "\x13BridgeInvokeRequest\x12\x1f\n" + + "\vplugin_name\x18\x01 \x01(\tR\n" + + "pluginName\x12!\n" + + "\fservice_name\x18\x02 \x01(\tR\vserviceName\x12\x16\n" + + "\x06method\x18\x03 \x01(\tR\x06method\x12\x18\n" + + "\apayload\x18\x04 \x01(\fR\apayload\"0\n" + + "\x14BridgeInvokeResponse\x12\x18\n" + + "\apayload\x18\x01 \x01(\fR\apayloadB0Z.git.dev.alexdunmow.com/block/core/abi/v1;abiv1b\x06proto3" var ( file_v1_capability_proto_rawDescOnce sync.Once @@ -5190,7 +7885,7 @@ func file_v1_capability_proto_rawDescGZIP() []byte { return file_v1_capability_proto_rawDescData } -var file_v1_capability_proto_msgTypes = make([]protoimpl.MessageInfo, 95) +var file_v1_capability_proto_msgTypes = make([]protoimpl.MessageInfo, 141) var file_v1_capability_proto_goTypes = []any{ (*HostCallRequest)(nil), // 0: abi.v1.HostCallRequest (*HostCallResponse)(nil), // 1: abi.v1.HostCallResponse @@ -5255,69 +7950,118 @@ var file_v1_capability_proto_goTypes = []any{ (*SubscriptionsListTiersResponse)(nil), // 60: abi.v1.SubscriptionsListTiersResponse (*SubscriptionsListActivePlansRequest)(nil), // 61: abi.v1.SubscriptionsListActivePlansRequest (*SubscriptionsListActivePlansResponse)(nil), // 62: abi.v1.SubscriptionsListActivePlansResponse - (*Plan)(nil), // 63: abi.v1.Plan - (*MediaDepositRequest)(nil), // 64: abi.v1.MediaDepositRequest - (*MediaDepositResponse)(nil), // 65: abi.v1.MediaDepositResponse - (*EmailSendRequest)(nil), // 66: abi.v1.EmailSendRequest - (*EmailSendResponse)(nil), // 67: abi.v1.EmailSendResponse - (*AiTextCallRequest)(nil), // 68: abi.v1.AiTextCallRequest - (*AiTextCallResponse)(nil), // 69: abi.v1.AiTextCallResponse - (*AiToolRegisterRequest)(nil), // 70: abi.v1.AiToolRegisterRequest - (*AiToolRegisterResponse)(nil), // 71: abi.v1.AiToolRegisterResponse - (*BridgeRegisterServiceRequest)(nil), // 72: abi.v1.BridgeRegisterServiceRequest - (*BridgeRegisterServiceResponse)(nil), // 73: abi.v1.BridgeRegisterServiceResponse - (*BridgeGetServiceRequest)(nil), // 74: abi.v1.BridgeGetServiceRequest - (*BridgeGetServiceResponse)(nil), // 75: abi.v1.BridgeGetServiceResponse - (*JobsSubmitRequest)(nil), // 76: abi.v1.JobsSubmitRequest - (*JobsSubmitResponse)(nil), // 77: abi.v1.JobsSubmitResponse - (*EmbeddingsGenerateEmbeddingRequest)(nil), // 78: abi.v1.EmbeddingsGenerateEmbeddingRequest - (*EmbeddingsGenerateEmbeddingResponse)(nil), // 79: abi.v1.EmbeddingsGenerateEmbeddingResponse - (*EmbeddingsEmbedContentRequest)(nil), // 80: abi.v1.EmbeddingsEmbedContentRequest - (*EmbeddingsEmbedContentResponse)(nil), // 81: abi.v1.EmbeddingsEmbedContentResponse - (*EmbeddingsIsAvailableRequest)(nil), // 82: abi.v1.EmbeddingsIsAvailableRequest - (*EmbeddingsIsAvailableResponse)(nil), // 83: abi.v1.EmbeddingsIsAvailableResponse - (*RagQueryRequest)(nil), // 84: abi.v1.RagQueryRequest - (*RagQueryResponse)(nil), // 85: abi.v1.RagQueryResponse - (*RagResult)(nil), // 86: abi.v1.RagResult - (*RagOnContentChangedRequest)(nil), // 87: abi.v1.RagOnContentChangedRequest - (*RagOnContentChangedResponse)(nil), // 88: abi.v1.RagOnContentChangedResponse - (*ReviewsSubmitReviewRequest)(nil), // 89: abi.v1.ReviewsSubmitReviewRequest - (*ReviewsSubmitReviewResponse)(nil), // 90: abi.v1.ReviewsSubmitReviewResponse - (*BadgesRefreshBadgesRequest)(nil), // 91: abi.v1.BadgesRefreshBadgesRequest - (*BadgesRefreshBadgesResponse)(nil), // 92: abi.v1.BadgesRefreshBadgesResponse - nil, // 93: abi.v1.AuthorProfile.SocialLinksEntry - nil, // 94: abi.v1.RagResult.MetadataEntry - (*AbiError)(nil), // 95: abi.v1.AbiError - (*timestamppb.Timestamp)(nil), // 96: google.protobuf.Timestamp + (*Plan)(nil), // 63: abi.v1.Plan + (*MediaDepositRequest)(nil), // 64: abi.v1.MediaDepositRequest + (*MediaDepositResponse)(nil), // 65: abi.v1.MediaDepositResponse + (*EmailSendRequest)(nil), // 66: abi.v1.EmailSendRequest + (*EmailSendResponse)(nil), // 67: abi.v1.EmailSendResponse + (*AiTextCallRequest)(nil), // 68: abi.v1.AiTextCallRequest + (*AiTextCallResponse)(nil), // 69: abi.v1.AiTextCallResponse + (*AiToolRegisterRequest)(nil), // 70: abi.v1.AiToolRegisterRequest + (*AiToolRegisterResponse)(nil), // 71: abi.v1.AiToolRegisterResponse + (*BridgeRegisterServiceRequest)(nil), // 72: abi.v1.BridgeRegisterServiceRequest + (*BridgeRegisterServiceResponse)(nil), // 73: abi.v1.BridgeRegisterServiceResponse + (*BridgeGetServiceRequest)(nil), // 74: abi.v1.BridgeGetServiceRequest + (*BridgeGetServiceResponse)(nil), // 75: abi.v1.BridgeGetServiceResponse + (*JobsSubmitRequest)(nil), // 76: abi.v1.JobsSubmitRequest + (*JobsSubmitResponse)(nil), // 77: abi.v1.JobsSubmitResponse + (*EmbeddingsGenerateEmbeddingRequest)(nil), // 78: abi.v1.EmbeddingsGenerateEmbeddingRequest + (*EmbeddingsGenerateEmbeddingResponse)(nil), // 79: abi.v1.EmbeddingsGenerateEmbeddingResponse + (*EmbeddingsEmbedContentRequest)(nil), // 80: abi.v1.EmbeddingsEmbedContentRequest + (*EmbeddingsEmbedContentResponse)(nil), // 81: abi.v1.EmbeddingsEmbedContentResponse + (*EmbeddingsIsAvailableRequest)(nil), // 82: abi.v1.EmbeddingsIsAvailableRequest + (*EmbeddingsIsAvailableResponse)(nil), // 83: abi.v1.EmbeddingsIsAvailableResponse + (*RagQueryRequest)(nil), // 84: abi.v1.RagQueryRequest + (*RagQueryResponse)(nil), // 85: abi.v1.RagQueryResponse + (*RagResult)(nil), // 86: abi.v1.RagResult + (*RagOnContentChangedRequest)(nil), // 87: abi.v1.RagOnContentChangedRequest + (*RagOnContentChangedResponse)(nil), // 88: abi.v1.RagOnContentChangedResponse + (*ReviewsSubmitReviewRequest)(nil), // 89: abi.v1.ReviewsSubmitReviewRequest + (*ReviewsSubmitReviewResponse)(nil), // 90: abi.v1.ReviewsSubmitReviewResponse + (*BadgesRefreshBadgesRequest)(nil), // 91: abi.v1.BadgesRefreshBadgesRequest + (*BadgesRefreshBadgesResponse)(nil), // 92: abi.v1.BadgesRefreshBadgesResponse + (*ContentCreatePageRequest)(nil), // 93: abi.v1.ContentCreatePageRequest + (*ContentCreatePageResponse)(nil), // 94: abi.v1.ContentCreatePageResponse + (*PageBlock)(nil), // 95: abi.v1.PageBlock + (*ContentSetPageBlocksRequest)(nil), // 96: abi.v1.ContentSetPageBlocksRequest + (*ContentSetPageBlocksResponse)(nil), // 97: abi.v1.ContentSetPageBlocksResponse + (*ContentPublishPageRequest)(nil), // 98: abi.v1.ContentPublishPageRequest + (*ContentPublishPageResponse)(nil), // 99: abi.v1.ContentPublishPageResponse + (*ContentSetPageSeoRequest)(nil), // 100: abi.v1.ContentSetPageSeoRequest + (*ContentSetPageSeoResponse)(nil), // 101: abi.v1.ContentSetPageSeoResponse + (*ContentUpsertPostRequest)(nil), // 102: abi.v1.ContentUpsertPostRequest + (*ContentUpsertPostResponse)(nil), // 103: abi.v1.ContentUpsertPostResponse + (*ProvisionerEnsureDataTableRequest)(nil), // 104: abi.v1.ProvisionerEnsureDataTableRequest + (*ProvisionerEnsureDataTableResponse)(nil), // 105: abi.v1.ProvisionerEnsureDataTableResponse + (*ProvisionerMergeSiteSettingsRequest)(nil), // 106: abi.v1.ProvisionerMergeSiteSettingsRequest + (*ProvisionerMergeSiteSettingsResponse)(nil), // 107: abi.v1.ProvisionerMergeSiteSettingsResponse + (*ProvisionerEnsureSettingRequest)(nil), // 108: abi.v1.ProvisionerEnsureSettingRequest + (*ProvisionerEnsureSettingResponse)(nil), // 109: abi.v1.ProvisionerEnsureSettingResponse + (*PageSeed)(nil), // 110: abi.v1.PageSeed + (*ProvisionerEnsurePageRequest)(nil), // 111: abi.v1.ProvisionerEnsurePageRequest + (*ProvisionerEnsurePageResponse)(nil), // 112: abi.v1.ProvisionerEnsurePageResponse + (*ProvisionerOverrideSiteSettingsRequest)(nil), // 113: abi.v1.ProvisionerOverrideSiteSettingsRequest + (*ProvisionerOverrideSiteSettingsResponse)(nil), // 114: abi.v1.ProvisionerOverrideSiteSettingsResponse + (*ProvisionerEnsureMenuItemRequest)(nil), // 115: abi.v1.ProvisionerEnsureMenuItemRequest + (*ProvisionerEnsureMenuItemResponse)(nil), // 116: abi.v1.ProvisionerEnsureMenuItemResponse + (*ProvisionerRegisterEmbeddingConfigRequest)(nil), // 117: abi.v1.ProvisionerRegisterEmbeddingConfigRequest + (*ProvisionerRegisterEmbeddingConfigResponse)(nil), // 118: abi.v1.ProvisionerRegisterEmbeddingConfigResponse + (*ProvisionerEnsureEmbedRequest)(nil), // 119: abi.v1.ProvisionerEnsureEmbedRequest + (*ProvisionerEnsureEmbedResponse)(nil), // 120: abi.v1.ProvisionerEnsureEmbedResponse + (*ProvisionerEnsureJobScheduleRequest)(nil), // 121: abi.v1.ProvisionerEnsureJobScheduleRequest + (*ProvisionerEnsureJobScheduleResponse)(nil), // 122: abi.v1.ProvisionerEnsureJobScheduleResponse + (*ProvisionerUpdateDataTableRowFieldRequest)(nil), // 123: abi.v1.ProvisionerUpdateDataTableRowFieldRequest + (*ProvisionerUpdateDataTableRowFieldResponse)(nil), // 124: abi.v1.ProvisionerUpdateDataTableRowFieldResponse + (*ProvisionerDisableOrphanedJobSchedulesRequest)(nil), // 125: abi.v1.ProvisionerDisableOrphanedJobSchedulesRequest + (*ProvisionerDisableOrphanedJobSchedulesResponse)(nil), // 126: abi.v1.ProvisionerDisableOrphanedJobSchedulesResponse + (*ProvisionerEnsurePluginRequest)(nil), // 127: abi.v1.ProvisionerEnsurePluginRequest + (*ProvisionerEnsurePluginResponse)(nil), // 128: abi.v1.ProvisionerEnsurePluginResponse + (*ProvisionerEnsureCustomColorRequest)(nil), // 129: abi.v1.ProvisionerEnsureCustomColorRequest + (*ProvisionerEnsureCustomColorResponse)(nil), // 130: abi.v1.ProvisionerEnsureCustomColorResponse + (*ProvisionerEnsureMediaRequest)(nil), // 131: abi.v1.ProvisionerEnsureMediaRequest + (*ProvisionerEnsureMediaResponse)(nil), // 132: abi.v1.ProvisionerEnsureMediaResponse + (*SettingsUpdatePluginSettingsRequest)(nil), // 133: abi.v1.SettingsUpdatePluginSettingsRequest + (*SettingsUpdatePluginSettingsResponse)(nil), // 134: abi.v1.SettingsUpdatePluginSettingsResponse + (*JobsProgressRequest)(nil), // 135: abi.v1.JobsProgressRequest + (*JobsProgressResponse)(nil), // 136: abi.v1.JobsProgressResponse + (*BridgeInvokeRequest)(nil), // 137: abi.v1.BridgeInvokeRequest + (*BridgeInvokeResponse)(nil), // 138: abi.v1.BridgeInvokeResponse + nil, // 139: abi.v1.AuthorProfile.SocialLinksEntry + nil, // 140: abi.v1.RagResult.MetadataEntry + (*AbiError)(nil), // 141: abi.v1.AbiError + (*timestamppb.Timestamp)(nil), // 142: google.protobuf.Timestamp } var file_v1_capability_proto_depIdxs = []int32{ - 95, // 0: abi.v1.HostCallResponse.error:type_name -> abi.v1.AbiError - 4, // 1: abi.v1.ContentGetAuthorProfileResponse.author:type_name -> abi.v1.AuthorProfile - 93, // 2: abi.v1.AuthorProfile.social_links:type_name -> abi.v1.AuthorProfile.SocialLinksEntry - 7, // 3: abi.v1.ContentGetPageResponse.page:type_name -> abi.v1.PageInfo - 10, // 4: abi.v1.ContentGetPostResponse.post:type_name -> abi.v1.PostInfo - 96, // 5: abi.v1.PostInfo.published_at:type_name -> google.protobuf.Timestamp - 10, // 6: abi.v1.ContentListPostsResponse.posts:type_name -> abi.v1.PostInfo - 31, // 7: abi.v1.GatingEvaluateAccessRequest.rule:type_name -> abi.v1.AccessRule - 32, // 8: abi.v1.GatingEvaluateAccessResponse.result:type_name -> abi.v1.AccessResult - 39, // 9: abi.v1.MenusGetMenuByNameResponse.menu:type_name -> abi.v1.Menu - 42, // 10: abi.v1.MenusGetMenuItemsResponse.items:type_name -> abi.v1.MenuItem - 47, // 11: abi.v1.DatasourcesResolveBucketResponse.result:type_name -> abi.v1.DatasourceResult - 47, // 12: abi.v1.DatasourcesResolveBucketByKeyResponse.result:type_name -> abi.v1.DatasourceResult - 52, // 13: abi.v1.UsersGetByUsernameResponse.user:type_name -> abi.v1.PublicUserProfile - 52, // 14: abi.v1.UsersGetByIdResponse.user:type_name -> abi.v1.PublicUserProfile - 55, // 15: abi.v1.SubscriptionsGetUserTierLevelResponse.tier_level:type_name -> abi.v1.TierLevel - 58, // 16: abi.v1.SubscriptionsGetTierBySlugResponse.tier:type_name -> abi.v1.Tier - 58, // 17: abi.v1.SubscriptionsListTiersResponse.tiers:type_name -> abi.v1.Tier - 63, // 18: abi.v1.SubscriptionsListActivePlansResponse.plans:type_name -> abi.v1.Plan - 96, // 19: abi.v1.Plan.created_at:type_name -> google.protobuf.Timestamp - 86, // 20: abi.v1.RagQueryResponse.results:type_name -> abi.v1.RagResult - 94, // 21: abi.v1.RagResult.metadata:type_name -> abi.v1.RagResult.MetadataEntry - 22, // [22:22] is the sub-list for method output_type - 22, // [22:22] is the sub-list for method input_type - 22, // [22:22] is the sub-list for extension type_name - 22, // [22:22] is the sub-list for extension extendee - 0, // [0:22] is the sub-list for field type_name + 141, // 0: abi.v1.HostCallResponse.error:type_name -> abi.v1.AbiError + 4, // 1: abi.v1.ContentGetAuthorProfileResponse.author:type_name -> abi.v1.AuthorProfile + 139, // 2: abi.v1.AuthorProfile.social_links:type_name -> abi.v1.AuthorProfile.SocialLinksEntry + 7, // 3: abi.v1.ContentGetPageResponse.page:type_name -> abi.v1.PageInfo + 10, // 4: abi.v1.ContentGetPostResponse.post:type_name -> abi.v1.PostInfo + 142, // 5: abi.v1.PostInfo.published_at:type_name -> google.protobuf.Timestamp + 10, // 6: abi.v1.ContentListPostsResponse.posts:type_name -> abi.v1.PostInfo + 31, // 7: abi.v1.GatingEvaluateAccessRequest.rule:type_name -> abi.v1.AccessRule + 32, // 8: abi.v1.GatingEvaluateAccessResponse.result:type_name -> abi.v1.AccessResult + 39, // 9: abi.v1.MenusGetMenuByNameResponse.menu:type_name -> abi.v1.Menu + 42, // 10: abi.v1.MenusGetMenuItemsResponse.items:type_name -> abi.v1.MenuItem + 47, // 11: abi.v1.DatasourcesResolveBucketResponse.result:type_name -> abi.v1.DatasourceResult + 47, // 12: abi.v1.DatasourcesResolveBucketByKeyResponse.result:type_name -> abi.v1.DatasourceResult + 52, // 13: abi.v1.UsersGetByUsernameResponse.user:type_name -> abi.v1.PublicUserProfile + 52, // 14: abi.v1.UsersGetByIdResponse.user:type_name -> abi.v1.PublicUserProfile + 55, // 15: abi.v1.SubscriptionsGetUserTierLevelResponse.tier_level:type_name -> abi.v1.TierLevel + 58, // 16: abi.v1.SubscriptionsGetTierBySlugResponse.tier:type_name -> abi.v1.Tier + 58, // 17: abi.v1.SubscriptionsListTiersResponse.tiers:type_name -> abi.v1.Tier + 63, // 18: abi.v1.SubscriptionsListActivePlansResponse.plans:type_name -> abi.v1.Plan + 142, // 19: abi.v1.Plan.created_at:type_name -> google.protobuf.Timestamp + 86, // 20: abi.v1.RagQueryResponse.results:type_name -> abi.v1.RagResult + 140, // 21: abi.v1.RagResult.metadata:type_name -> abi.v1.RagResult.MetadataEntry + 95, // 22: abi.v1.ContentSetPageBlocksRequest.blocks:type_name -> abi.v1.PageBlock + 95, // 23: abi.v1.PageSeed.blocks:type_name -> abi.v1.PageBlock + 110, // 24: abi.v1.ProvisionerEnsurePageRequest.page:type_name -> abi.v1.PageSeed + 25, // [25:25] is the sub-list for method output_type + 25, // [25:25] is the sub-list for method input_type + 25, // [25:25] is the sub-list for extension type_name + 25, // [25:25] is the sub-list for extension extendee + 0, // [0:25] is the sub-list for field type_name } func init() { file_v1_capability_proto_init() } @@ -5327,13 +8071,16 @@ func file_v1_capability_proto_init() { } file_v1_invoke_proto_init() file_v1_capability_proto_msgTypes[42].OneofWrappers = []any{} + file_v1_capability_proto_msgTypes[95].OneofWrappers = []any{} + file_v1_capability_proto_msgTypes[100].OneofWrappers = []any{} + file_v1_capability_proto_msgTypes[102].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_v1_capability_proto_rawDesc), len(file_v1_capability_proto_rawDesc)), NumEnums: 0, - NumMessages: 95, + NumMessages: 141, NumExtensions: 0, NumServices: 0, }, diff --git a/abi/v1/invoke.pb.go b/abi/v1/invoke.pb.go index d85eb57..6a08dc1 100644 --- a/abi/v1/invoke.pb.go +++ b/abi/v1/invoke.pb.go @@ -66,6 +66,18 @@ const ( // Apply a plugin-declared template filter (manifest.declared_filters): // payload = ApplyFilterRequest / ApplyFilterResponse. Hook_HOOK_APPLY_FILTER Hook = 11 + // Execute a guest-registered AI tool handler (ai.tools.register): + // payload = AiToolCallRequest / AiToolCallResponse. + Hook_HOOK_AI_TOOL_CALL Hook = 12 + // Invoke a method on a bridge service this plugin registered + // (bridge.register_service): payload = BridgeCallRequest / BridgeCallResponse. + Hook_HOOK_BRIDGE_CALL Hook = 13 + // Render one directory panel section (DirectoryExtensions.PanelSections): + // payload = DirectoryPanelSectionRequest / DirectoryPanelSectionResponse. + Hook_HOOK_DIRECTORY_PANEL_SECTION Hook = 14 + // Run one directory pin decorator (DirectoryExtensions.PinDecorators): + // payload = DirectoryPinDecoratorRequest / DirectoryPinDecoratorResponse. + Hook_HOOK_DIRECTORY_PIN_DECORATOR Hook = 15 ) // Enum value maps for Hook. @@ -83,20 +95,28 @@ var ( 9: "HOOK_DESCRIBE", 10: "HOOK_RENDER_TAG", 11: "HOOK_APPLY_FILTER", + 12: "HOOK_AI_TOOL_CALL", + 13: "HOOK_BRIDGE_CALL", + 14: "HOOK_DIRECTORY_PANEL_SECTION", + 15: "HOOK_DIRECTORY_PIN_DECORATOR", } Hook_value = map[string]int32{ - "HOOK_UNSPECIFIED": 0, - "HOOK_RENDER_BLOCK": 1, - "HOOK_RENDER_TEMPLATE": 2, - "HOOK_HANDLE_HTTP": 3, - "HOOK_JOB": 4, - "HOOK_LOAD": 5, - "HOOK_UNLOAD": 6, - "HOOK_RAG_FETCH": 7, - "HOOK_MEDIA_HOOK": 8, - "HOOK_DESCRIBE": 9, - "HOOK_RENDER_TAG": 10, - "HOOK_APPLY_FILTER": 11, + "HOOK_UNSPECIFIED": 0, + "HOOK_RENDER_BLOCK": 1, + "HOOK_RENDER_TEMPLATE": 2, + "HOOK_HANDLE_HTTP": 3, + "HOOK_JOB": 4, + "HOOK_LOAD": 5, + "HOOK_UNLOAD": 6, + "HOOK_RAG_FETCH": 7, + "HOOK_MEDIA_HOOK": 8, + "HOOK_DESCRIBE": 9, + "HOOK_RENDER_TAG": 10, + "HOOK_APPLY_FILTER": 11, + "HOOK_AI_TOOL_CALL": 12, + "HOOK_BRIDGE_CALL": 13, + "HOOK_DIRECTORY_PANEL_SECTION": 14, + "HOOK_DIRECTORY_PIN_DECORATOR": 15, } ) @@ -1115,6 +1135,433 @@ func (x *MediaAnalyzedEvent) GetSafeRacy() string { return "" } +// AiToolCallRequest executes the guest-side Handler of a tool the plugin +// registered via ai.tools.register (ai.ToolHandler). +type AiToolCallRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Slug string `protobuf:"bytes,1,opt,name=slug,proto3" json:"slug,omitempty"` + // JSON encoding of the params map. + ParamsJson []byte `protobuf:"bytes,2,opt,name=params_json,json=paramsJson,proto3" json:"params_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AiToolCallRequest) Reset() { + *x = AiToolCallRequest{} + mi := &file_v1_invoke_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AiToolCallRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AiToolCallRequest) ProtoMessage() {} + +func (x *AiToolCallRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_invoke_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AiToolCallRequest.ProtoReflect.Descriptor instead. +func (*AiToolCallRequest) Descriptor() ([]byte, []int) { + return file_v1_invoke_proto_rawDescGZIP(), []int{17} +} + +func (x *AiToolCallRequest) GetSlug() string { + if x != nil { + return x.Slug + } + return "" +} + +func (x *AiToolCallRequest) GetParamsJson() []byte { + if x != nil { + return x.ParamsJson + } + return nil +} + +// AiToolCallResponse mirrors ai.ToolResult. A handler-level failure travels +// in error_message (a normal tool outcome the model sees); AbiError stays +// reserved for transport/decode/panic failures. +type AiToolCallResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Content string `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"` + ErrorMessage string `protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AiToolCallResponse) Reset() { + *x = AiToolCallResponse{} + mi := &file_v1_invoke_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AiToolCallResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AiToolCallResponse) ProtoMessage() {} + +func (x *AiToolCallResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_invoke_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AiToolCallResponse.ProtoReflect.Descriptor instead. +func (*AiToolCallResponse) Descriptor() ([]byte, []int) { + return file_v1_invoke_proto_rawDescGZIP(), []int{18} +} + +func (x *AiToolCallResponse) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +func (x *AiToolCallResponse) GetErrorMessage() string { + if x != nil { + return x.ErrorMessage + } + return "" +} + +// BridgeCallRequest asks THIS plugin (the provider) to run a method on one of +// its registered bridge services. The consumer side is the bridge.invoke +// capability; payload encoding is agreed between the two plugins (JSON by +// convention). +type BridgeCallRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + ServiceName string `protobuf:"bytes,1,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` + Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"` + Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BridgeCallRequest) Reset() { + *x = BridgeCallRequest{} + mi := &file_v1_invoke_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BridgeCallRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BridgeCallRequest) ProtoMessage() {} + +func (x *BridgeCallRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_invoke_proto_msgTypes[19] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BridgeCallRequest.ProtoReflect.Descriptor instead. +func (*BridgeCallRequest) Descriptor() ([]byte, []int) { + return file_v1_invoke_proto_rawDescGZIP(), []int{19} +} + +func (x *BridgeCallRequest) GetServiceName() string { + if x != nil { + return x.ServiceName + } + return "" +} + +func (x *BridgeCallRequest) GetMethod() string { + if x != nil { + return x.Method + } + return "" +} + +func (x *BridgeCallRequest) GetPayload() []byte { + if x != nil { + return x.Payload + } + return nil +} + +type BridgeCallResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BridgeCallResponse) Reset() { + *x = BridgeCallResponse{} + mi := &file_v1_invoke_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BridgeCallResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BridgeCallResponse) ProtoMessage() {} + +func (x *BridgeCallResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_invoke_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BridgeCallResponse.ProtoReflect.Descriptor instead. +func (*BridgeCallResponse) Descriptor() ([]byte, []int) { + return file_v1_invoke_proto_rawDescGZIP(), []int{20} +} + +func (x *BridgeCallResponse) GetPayload() []byte { + if x != nil { + return x.Payload + } + return nil +} + +// DirectoryPanelSectionRequest renders the index-th registered panel section +// (DirectoryExtensions.PanelSections[index], counted in +// manifest.directory_extensions.panel_section_count). +type DirectoryPanelSectionRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Index uint32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` + // JSON encoding of the row data map. + DataJson []byte `protobuf:"bytes,2,opt,name=data_json,json=dataJson,proto3" json:"data_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DirectoryPanelSectionRequest) Reset() { + *x = DirectoryPanelSectionRequest{} + mi := &file_v1_invoke_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DirectoryPanelSectionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DirectoryPanelSectionRequest) ProtoMessage() {} + +func (x *DirectoryPanelSectionRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_invoke_proto_msgTypes[21] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DirectoryPanelSectionRequest.ProtoReflect.Descriptor instead. +func (*DirectoryPanelSectionRequest) Descriptor() ([]byte, []int) { + return file_v1_invoke_proto_rawDescGZIP(), []int{21} +} + +func (x *DirectoryPanelSectionRequest) GetIndex() uint32 { + if x != nil { + return x.Index + } + return 0 +} + +func (x *DirectoryPanelSectionRequest) GetDataJson() []byte { + if x != nil { + return x.DataJson + } + return nil +} + +type DirectoryPanelSectionResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Html string `protobuf:"bytes,1,opt,name=html,proto3" json:"html,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DirectoryPanelSectionResponse) Reset() { + *x = DirectoryPanelSectionResponse{} + mi := &file_v1_invoke_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DirectoryPanelSectionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DirectoryPanelSectionResponse) ProtoMessage() {} + +func (x *DirectoryPanelSectionResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_invoke_proto_msgTypes[22] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DirectoryPanelSectionResponse.ProtoReflect.Descriptor instead. +func (*DirectoryPanelSectionResponse) Descriptor() ([]byte, []int) { + return file_v1_invoke_proto_rawDescGZIP(), []int{22} +} + +func (x *DirectoryPanelSectionResponse) GetHtml() string { + if x != nil { + return x.Html + } + return "" +} + +// DirectoryPinDecoratorRequest runs the index-th registered pin decorator, +// which mutates the pin map in place; the mutated pin is returned. +type DirectoryPinDecoratorRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Index uint32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` + // JSON encoding of the pin map (mutated by the decorator). + PinJson []byte `protobuf:"bytes,2,opt,name=pin_json,json=pinJson,proto3" json:"pin_json,omitempty"` + // JSON encoding of the row data map (read-only input). + DataJson []byte `protobuf:"bytes,3,opt,name=data_json,json=dataJson,proto3" json:"data_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DirectoryPinDecoratorRequest) Reset() { + *x = DirectoryPinDecoratorRequest{} + mi := &file_v1_invoke_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DirectoryPinDecoratorRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DirectoryPinDecoratorRequest) ProtoMessage() {} + +func (x *DirectoryPinDecoratorRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_invoke_proto_msgTypes[23] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DirectoryPinDecoratorRequest.ProtoReflect.Descriptor instead. +func (*DirectoryPinDecoratorRequest) Descriptor() ([]byte, []int) { + return file_v1_invoke_proto_rawDescGZIP(), []int{23} +} + +func (x *DirectoryPinDecoratorRequest) GetIndex() uint32 { + if x != nil { + return x.Index + } + return 0 +} + +func (x *DirectoryPinDecoratorRequest) GetPinJson() []byte { + if x != nil { + return x.PinJson + } + return nil +} + +func (x *DirectoryPinDecoratorRequest) GetDataJson() []byte { + if x != nil { + return x.DataJson + } + return nil +} + +type DirectoryPinDecoratorResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // JSON encoding of the mutated pin map. + PinJson []byte `protobuf:"bytes,1,opt,name=pin_json,json=pinJson,proto3" json:"pin_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DirectoryPinDecoratorResponse) Reset() { + *x = DirectoryPinDecoratorResponse{} + mi := &file_v1_invoke_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DirectoryPinDecoratorResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DirectoryPinDecoratorResponse) ProtoMessage() {} + +func (x *DirectoryPinDecoratorResponse) ProtoReflect() protoreflect.Message { + mi := &file_v1_invoke_proto_msgTypes[24] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DirectoryPinDecoratorResponse.ProtoReflect.Descriptor instead. +func (*DirectoryPinDecoratorResponse) Descriptor() ([]byte, []int) { + return file_v1_invoke_proto_rawDescGZIP(), []int{24} +} + +func (x *DirectoryPinDecoratorResponse) GetPinJson() []byte { + if x != nil { + return x.PinJson + } + return nil +} + // ModerationDecisionEvent mirrors plugin.ModerationDecisionEvent. type ModerationDecisionEvent struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -1133,7 +1580,7 @@ type ModerationDecisionEvent struct { func (x *ModerationDecisionEvent) Reset() { *x = ModerationDecisionEvent{} - mi := &file_v1_invoke_proto_msgTypes[17] + mi := &file_v1_invoke_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1145,7 +1592,7 @@ func (x *ModerationDecisionEvent) String() string { func (*ModerationDecisionEvent) ProtoMessage() {} func (x *ModerationDecisionEvent) ProtoReflect() protoreflect.Message { - mi := &file_v1_invoke_proto_msgTypes[17] + mi := &file_v1_invoke_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1158,7 +1605,7 @@ func (x *ModerationDecisionEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ModerationDecisionEvent.ProtoReflect.Descriptor instead. func (*ModerationDecisionEvent) Descriptor() ([]byte, []int) { - return file_v1_invoke_proto_rawDescGZIP(), []int{17} + return file_v1_invoke_proto_rawDescGZIP(), []int{25} } func (x *ModerationDecisionEvent) GetMediaId() string { @@ -1289,7 +1736,31 @@ const file_v1_invoke_proto_rawDesc = "" + "safe_adult\x18\b \x01(\tR\tsafeAdult\x12#\n" + "\rsafe_violence\x18\t \x01(\tR\fsafeViolence\x12\x1b\n" + "\tsafe_racy\x18\n" + - " \x01(\tR\bsafeRacy\"\xb7\x02\n" + + " \x01(\tR\bsafeRacy\"H\n" + + "\x11AiToolCallRequest\x12\x12\n" + + "\x04slug\x18\x01 \x01(\tR\x04slug\x12\x1f\n" + + "\vparams_json\x18\x02 \x01(\fR\n" + + "paramsJson\"S\n" + + "\x12AiToolCallResponse\x12\x18\n" + + "\acontent\x18\x01 \x01(\tR\acontent\x12#\n" + + "\rerror_message\x18\x02 \x01(\tR\ferrorMessage\"h\n" + + "\x11BridgeCallRequest\x12!\n" + + "\fservice_name\x18\x01 \x01(\tR\vserviceName\x12\x16\n" + + "\x06method\x18\x02 \x01(\tR\x06method\x12\x18\n" + + "\apayload\x18\x03 \x01(\fR\apayload\".\n" + + "\x12BridgeCallResponse\x12\x18\n" + + "\apayload\x18\x01 \x01(\fR\apayload\"Q\n" + + "\x1cDirectoryPanelSectionRequest\x12\x14\n" + + "\x05index\x18\x01 \x01(\rR\x05index\x12\x1b\n" + + "\tdata_json\x18\x02 \x01(\fR\bdataJson\"3\n" + + "\x1dDirectoryPanelSectionResponse\x12\x12\n" + + "\x04html\x18\x01 \x01(\tR\x04html\"l\n" + + "\x1cDirectoryPinDecoratorRequest\x12\x14\n" + + "\x05index\x18\x01 \x01(\rR\x05index\x12\x19\n" + + "\bpin_json\x18\x02 \x01(\fR\apinJson\x12\x1b\n" + + "\tdata_json\x18\x03 \x01(\fR\bdataJson\":\n" + + "\x1dDirectoryPinDecoratorResponse\x12\x19\n" + + "\bpin_json\x18\x01 \x01(\fR\apinJson\"\xb7\x02\n" + "\x17ModerationDecisionEvent\x12\x19\n" + "\bmedia_id\x18\x01 \x01(\tR\amediaId\x12\x1f\n" + "\vanalysis_id\x18\x02 \x01(\tR\n" + @@ -1301,7 +1772,7 @@ const file_v1_invoke_proto_rawDesc = "" + "sourceType\x12\"\n" + "\rsource_ref_id\x18\a \x01(\tR\vsourceRefId\x12!\n" + "\fmoderated_by\x18\b \x01(\tR\vmoderatedBy\x12\x12\n" + - "\x04note\x18\t \x01(\tR\x04note*\xf9\x01\n" + + "\x04note\x18\t \x01(\tR\x04note*\xea\x02\n" + "\x04Hook\x12\x14\n" + "\x10HOOK_UNSPECIFIED\x10\x00\x12\x15\n" + "\x11HOOK_RENDER_BLOCK\x10\x01\x12\x18\n" + @@ -1315,7 +1786,11 @@ const file_v1_invoke_proto_rawDesc = "" + "\rHOOK_DESCRIBE\x10\t\x12\x13\n" + "\x0fHOOK_RENDER_TAG\x10\n" + "\x12\x15\n" + - "\x11HOOK_APPLY_FILTER\x10\v*\xf3\x01\n" + + "\x11HOOK_APPLY_FILTER\x10\v\x12\x15\n" + + "\x11HOOK_AI_TOOL_CALL\x10\f\x12\x14\n" + + "\x10HOOK_BRIDGE_CALL\x10\r\x12 \n" + + "\x1cHOOK_DIRECTORY_PANEL_SECTION\x10\x0e\x12 \n" + + "\x1cHOOK_DIRECTORY_PIN_DECORATOR\x10\x0f*\xf3\x01\n" + "\fAbiErrorCode\x12\x1e\n" + "\x1aABI_ERROR_CODE_UNSPECIFIED\x10\x00\x12\x1b\n" + "\x17ABI_ERROR_CODE_INTERNAL\x10\x01\x12\x19\n" + @@ -1338,38 +1813,46 @@ func file_v1_invoke_proto_rawDescGZIP() []byte { } var file_v1_invoke_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_v1_invoke_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_v1_invoke_proto_msgTypes = make([]protoimpl.MessageInfo, 26) var file_v1_invoke_proto_goTypes = []any{ - (Hook)(0), // 0: abi.v1.Hook - (AbiErrorCode)(0), // 1: abi.v1.AbiErrorCode - (*InvokeRequest)(nil), // 2: abi.v1.InvokeRequest - (*InvokeResponse)(nil), // 3: abi.v1.InvokeResponse - (*AbiError)(nil), // 4: abi.v1.AbiError - (*DescribeRequest)(nil), // 5: abi.v1.DescribeRequest - (*DescribeResponse)(nil), // 6: abi.v1.DescribeResponse - (*LoadRequest)(nil), // 7: abi.v1.LoadRequest - (*HostConfig)(nil), // 8: abi.v1.HostConfig - (*LoadResponse)(nil), // 9: abi.v1.LoadResponse - (*UnloadRequest)(nil), // 10: abi.v1.UnloadRequest - (*UnloadResponse)(nil), // 11: abi.v1.UnloadResponse - (*JobRequest)(nil), // 12: abi.v1.JobRequest - (*JobResponse)(nil), // 13: abi.v1.JobResponse - (*RagFetchRequest)(nil), // 14: abi.v1.RagFetchRequest - (*RagFetchResponse)(nil), // 15: abi.v1.RagFetchResponse - (*MediaHookRequest)(nil), // 16: abi.v1.MediaHookRequest - (*MediaHookResponse)(nil), // 17: abi.v1.MediaHookResponse - (*MediaAnalyzedEvent)(nil), // 18: abi.v1.MediaAnalyzedEvent - (*ModerationDecisionEvent)(nil), // 19: abi.v1.ModerationDecisionEvent - (*PluginManifest)(nil), // 20: abi.v1.PluginManifest + (Hook)(0), // 0: abi.v1.Hook + (AbiErrorCode)(0), // 1: abi.v1.AbiErrorCode + (*InvokeRequest)(nil), // 2: abi.v1.InvokeRequest + (*InvokeResponse)(nil), // 3: abi.v1.InvokeResponse + (*AbiError)(nil), // 4: abi.v1.AbiError + (*DescribeRequest)(nil), // 5: abi.v1.DescribeRequest + (*DescribeResponse)(nil), // 6: abi.v1.DescribeResponse + (*LoadRequest)(nil), // 7: abi.v1.LoadRequest + (*HostConfig)(nil), // 8: abi.v1.HostConfig + (*LoadResponse)(nil), // 9: abi.v1.LoadResponse + (*UnloadRequest)(nil), // 10: abi.v1.UnloadRequest + (*UnloadResponse)(nil), // 11: abi.v1.UnloadResponse + (*JobRequest)(nil), // 12: abi.v1.JobRequest + (*JobResponse)(nil), // 13: abi.v1.JobResponse + (*RagFetchRequest)(nil), // 14: abi.v1.RagFetchRequest + (*RagFetchResponse)(nil), // 15: abi.v1.RagFetchResponse + (*MediaHookRequest)(nil), // 16: abi.v1.MediaHookRequest + (*MediaHookResponse)(nil), // 17: abi.v1.MediaHookResponse + (*MediaAnalyzedEvent)(nil), // 18: abi.v1.MediaAnalyzedEvent + (*AiToolCallRequest)(nil), // 19: abi.v1.AiToolCallRequest + (*AiToolCallResponse)(nil), // 20: abi.v1.AiToolCallResponse + (*BridgeCallRequest)(nil), // 21: abi.v1.BridgeCallRequest + (*BridgeCallResponse)(nil), // 22: abi.v1.BridgeCallResponse + (*DirectoryPanelSectionRequest)(nil), // 23: abi.v1.DirectoryPanelSectionRequest + (*DirectoryPanelSectionResponse)(nil), // 24: abi.v1.DirectoryPanelSectionResponse + (*DirectoryPinDecoratorRequest)(nil), // 25: abi.v1.DirectoryPinDecoratorRequest + (*DirectoryPinDecoratorResponse)(nil), // 26: abi.v1.DirectoryPinDecoratorResponse + (*ModerationDecisionEvent)(nil), // 27: abi.v1.ModerationDecisionEvent + (*PluginManifest)(nil), // 28: abi.v1.PluginManifest } var file_v1_invoke_proto_depIdxs = []int32{ 0, // 0: abi.v1.InvokeRequest.hook:type_name -> abi.v1.Hook 4, // 1: abi.v1.InvokeResponse.error:type_name -> abi.v1.AbiError 1, // 2: abi.v1.AbiError.code:type_name -> abi.v1.AbiErrorCode - 20, // 3: abi.v1.DescribeResponse.manifest:type_name -> abi.v1.PluginManifest + 28, // 3: abi.v1.DescribeResponse.manifest:type_name -> abi.v1.PluginManifest 8, // 4: abi.v1.LoadRequest.host_config:type_name -> abi.v1.HostConfig 18, // 5: abi.v1.MediaHookRequest.media_analyzed:type_name -> abi.v1.MediaAnalyzedEvent - 19, // 6: abi.v1.MediaHookRequest.moderation_decision:type_name -> abi.v1.ModerationDecisionEvent + 27, // 6: abi.v1.MediaHookRequest.moderation_decision:type_name -> abi.v1.ModerationDecisionEvent 7, // [7:7] is the sub-list for method output_type 7, // [7:7] is the sub-list for method input_type 7, // [7:7] is the sub-list for extension type_name @@ -1393,7 +1876,7 @@ func file_v1_invoke_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_v1_invoke_proto_rawDesc), len(file_v1_invoke_proto_rawDesc)), NumEnums: 2, - NumMessages: 18, + NumMessages: 26, NumExtensions: 0, NumServices: 0, }, diff --git a/content/author.go b/content/author.go new file mode 100644 index 0000000..f960e93 --- /dev/null +++ b/content/author.go @@ -0,0 +1,86 @@ +package content + +import ( + "context" + + "github.com/google/uuid" +) + +// Author provides imperative page/post authoring for plugins (WO-WZ-019). +// The CMS implements this interface and wires it into CoreServices. +// +// These are the runtime counterparts of the idempotent seed-time operations +// on plugin.Provisioner: CreatePage is create-or-return-existing, the rest +// mutate an existing page/post. Blog posts live in the CMS's dedicated +// blog_posts table (not the pages table). +type Author interface { + CreatePage(ctx context.Context, params CreatePageParams) (CreatePageResult, error) + SetPageBlocks(ctx context.Context, pageID uuid.UUID, blocks []PageBlock) error + PublishPage(ctx context.Context, pageID uuid.UUID) error + SetPageSEO(ctx context.Context, pageID uuid.UUID, seo PageSEO) error + UpsertPost(ctx context.Context, params UpsertPostParams) (UpsertPostResult, error) +} + +// CreatePageParams describes a page to create. +type CreatePageParams struct { + Slug string + ParentSlug string // "" = root + Title string + TemplateKey string + MasterPageKey string // "" = none +} + +// CreatePageResult reports the created (or pre-existing) page. +type CreatePageResult struct { + PageID uuid.UUID + // Created is false when a page with the slug already existed; the + // existing ID is returned and nothing is modified. + Created bool +} + +// PageBlock is one block instance placed on a page. +type PageBlock struct { + BlockKey string + Title string + Content map[string]any + HTMLContent *string + Slot string + SortOrder int32 +} + +// PageSEO carries the SEO fields settable on a page. Nil pointers leave the +// existing value untouched. +type PageSEO struct { + MetaTitle *string + MetaDescription *string + OGTitle *string + OGDescription *string + OGImage *string + FocusKeyphrase *string + CanonicalURL *string + RobotsDirective *string + TwitterTitle *string + TwitterDescription *string + TwitterImage *string +} + +// UpsertPostParams creates or updates a blog post by slug. +type UpsertPostParams struct { + Slug string + Title string + Document map[string]any // BlockNote document + Excerpt *string + // AuthorProfileID / FeaturedImageID reference existing rows (e.g. a + // media.deposit result for the image). + AuthorProfileID *uuid.UUID + FeaturedImageID *uuid.UUID + // Publish publishes the post immediately after the upsert. + Publish bool + IsFeatured bool +} + +// UpsertPostResult reports the upserted post. +type UpsertPostResult struct { + PostID uuid.UUID + Created bool +} diff --git a/plugin/bridge.go b/plugin/bridge.go index ae27b93..6825f3a 100644 --- a/plugin/bridge.go +++ b/plugin/bridge.go @@ -1,10 +1,30 @@ package plugin +import "context" + // PluginBridge allows plugins to share services with each other. // Plugins register named services during startup; other plugins look them up at runtime. +// +// In-process (bundled) plugins can share typed Go values via +// RegisterService/GetService. Across the wasm sandbox a typed value cannot +// cross, so cross-plugin calls go through Invoke instead: the provider's +// service implements BridgeInvokable and the consumer calls Invoke with an +// opaque payload (JSON by convention). GetService still reports availability +// only (nil) for wasm consumers. type PluginBridge interface { RegisterService(pluginName, serviceName string, service any) GetService(pluginName, serviceName string) any + // Invoke calls a method on another plugin's registered bridge service. + // The provider answers via its BridgeInvokable implementation (bundled) + // or the BRIDGE_CALL hook (wasm). + Invoke(ctx context.Context, pluginName, serviceName, method string, payload []byte) ([]byte, error) +} + +// BridgeInvokable is implemented by bridge service values that support +// method-by-name invocation with opaque payloads, making them callable from +// other plugins across the wasm sandbox boundary. +type BridgeInvokable interface { + InvokeBridge(ctx context.Context, method string, payload []byte) ([]byte, error) } // GetServiceAs retrieves a typed service from the bridge. diff --git a/plugin/deps.go b/plugin/deps.go index 5d1d517..f435201 100644 --- a/plugin/deps.go +++ b/plugin/deps.go @@ -20,6 +20,7 @@ import ( type CoreServices struct { // Capability interfaces — typed access to CMS functionality Content content.Content + ContentAuthor content.Author Settings settings.Settings Gating gating.Gating Crypto crypto.Crypto @@ -61,6 +62,12 @@ type CoreServices struct { JobRunner JobRunner EmbeddingService EmbeddingService RAGService RAGService + + // Provisioner — idempotent ensure/seed operations. In the wasm world this + // is a LOAD-TIME capability: call it from the Load hook, not from + // Register/RegisterWithProvisioner (DESCRIBE stubs every host function to + // fail, so register-time provisioning cannot cross the ABI). + Provisioner Provisioner } // MediaDeposit describes an image a plugin deposits into the CMS media library. diff --git a/plugin/wasmguest/caps/ai.go b/plugin/wasmguest/caps/ai.go index d3dee2b..eefc75b 100644 --- a/plugin/wasmguest/caps/ai.go +++ b/plugin/wasmguest/caps/ai.go @@ -12,9 +12,15 @@ import ( // CoreServices.AITextCall func field (ai.text_call). // // ToolDefinition.Handler stays guest-side: registration marshals only the -// static descriptor. Host→guest tool execution is a runtime-WO concern -// flagged in core/docs/wasm-abi.md. -type aiStub struct{ base } +// static descriptor AND records the full definition locally so the host can +// execute the Handler via HOOK_AI_TOOL_CALL. Register tools in Register (every +// pooled instance runs it), not Load (one instance only) — see +// core/docs/wasm-abi.md §"Per-instance state". Instances are single-threaded, +// so the plain map needs no locking. +type aiStub struct { + base + tools map[string]*ai.ToolDefinition // slug → definition (with Handler) +} var _ ai.ToolRegistry = (*aiStub)(nil) @@ -24,6 +30,10 @@ func (s *aiStub) Register(tool *ai.ToolDefinition) { if tool == nil { return } + if s.tools == nil { + s.tools = make(map[string]*ai.ToolDefinition) + } + s.tools[tool.Slug] = tool req := &abiv1.AiToolRegisterRequest{ Slug: tool.Slug, Name: tool.Name, @@ -37,6 +47,13 @@ func (s *aiStub) Register(tool *ai.ToolDefinition) { _ = s.invoke(context.Background(), "tools.register", req, &abiv1.AiToolRegisterResponse{}) } +// Tool returns the registered tool definition for a slug, for +// HOOK_AI_TOOL_CALL dispatch by the wasm shim. +func (s *aiStub) Tool(slug string) (*ai.ToolDefinition, bool) { + t, ok := s.tools[slug] + return t, ok +} + // textCall backs CoreServices.AITextCall. func (s *aiStub) textCall(ctx context.Context, taskKey, systemPrompt, userMessage string) (string, error) { req := &abiv1.AiTextCallRequest{ diff --git a/plugin/wasmguest/caps/author.go b/plugin/wasmguest/caps/author.go new file mode 100644 index 0000000..92cef48 --- /dev/null +++ b/plugin/wasmguest/caps/author.go @@ -0,0 +1,120 @@ +package caps + +import ( + "context" + "encoding/json" + "fmt" + + abiv1 "git.dev.alexdunmow.com/block/core/abi/v1" + "git.dev.alexdunmow.com/block/core/content" + "github.com/google/uuid" +) + +// authorStub implements content.Author over the content.* write capability +// calls (WO-WZ-019). Same family as contentStub; split so the read surface +// stays untouched. +type authorStub struct{ base } + +var _ content.Author = (*authorStub)(nil) + +func (s *authorStub) CreatePage(ctx context.Context, params content.CreatePageParams) (content.CreatePageResult, error) { + req := &abiv1.ContentCreatePageRequest{ + Slug: params.Slug, + ParentSlug: params.ParentSlug, + Title: params.Title, + TemplateKey: params.TemplateKey, + MasterPageKey: params.MasterPageKey, + } + resp := &abiv1.ContentCreatePageResponse{} + if err := s.invoke(ctx, "create_page", req, resp); err != nil { + return content.CreatePageResult{}, err + } + id, err := uuid.Parse(resp.GetPageId()) + if err != nil { + return content.CreatePageResult{}, fmt.Errorf("content.create_page: bad page_id %q: %w", resp.GetPageId(), err) + } + return content.CreatePageResult{PageID: id, Created: resp.GetCreated()}, nil +} + +func (s *authorStub) SetPageBlocks(ctx context.Context, pageID uuid.UUID, blocks []content.PageBlock) error { + req := &abiv1.ContentSetPageBlocksRequest{PageId: pageID.String()} + for _, b := range blocks { + pb, err := pageBlockToProto(b) + if err != nil { + return fmt.Errorf("content.set_page_blocks: block %q: %w", b.BlockKey, err) + } + req.Blocks = append(req.Blocks, pb) + } + return s.invoke(ctx, "set_page_blocks", req, &abiv1.ContentSetPageBlocksResponse{}) +} + +func (s *authorStub) PublishPage(ctx context.Context, pageID uuid.UUID) error { + req := &abiv1.ContentPublishPageRequest{PageId: pageID.String()} + return s.invoke(ctx, "publish_page", req, &abiv1.ContentPublishPageResponse{}) +} + +func (s *authorStub) SetPageSEO(ctx context.Context, pageID uuid.UUID, seo content.PageSEO) error { + req := &abiv1.ContentSetPageSeoRequest{ + PageId: pageID.String(), + MetaTitle: seo.MetaTitle, + MetaDescription: seo.MetaDescription, + OgTitle: seo.OGTitle, + OgDescription: seo.OGDescription, + OgImage: seo.OGImage, + FocusKeyphrase: seo.FocusKeyphrase, + CanonicalUrl: seo.CanonicalURL, + RobotsDirective: seo.RobotsDirective, + TwitterTitle: seo.TwitterTitle, + TwitterDescription: seo.TwitterDescription, + TwitterImage: seo.TwitterImage, + } + return s.invoke(ctx, "set_page_seo", req, &abiv1.ContentSetPageSeoResponse{}) +} + +func (s *authorStub) UpsertPost(ctx context.Context, params content.UpsertPostParams) (content.UpsertPostResult, error) { + docJSON, err := json.Marshal(params.Document) + if err != nil { + return content.UpsertPostResult{}, fmt.Errorf("content.upsert_post: marshal document: %w", err) + } + req := &abiv1.ContentUpsertPostRequest{ + Slug: params.Slug, + Title: params.Title, + DocumentJson: docJSON, + Excerpt: params.Excerpt, + Publish: params.Publish, + IsFeatured: params.IsFeatured, + } + if params.AuthorProfileID != nil { + v := params.AuthorProfileID.String() + req.AuthorProfileId = &v + } + if params.FeaturedImageID != nil { + v := params.FeaturedImageID.String() + req.FeaturedImageId = &v + } + resp := &abiv1.ContentUpsertPostResponse{} + if err := s.invoke(ctx, "upsert_post", req, resp); err != nil { + return content.UpsertPostResult{}, err + } + id, err := uuid.Parse(resp.GetPostId()) + if err != nil { + return content.UpsertPostResult{}, fmt.Errorf("content.upsert_post: bad post_id %q: %w", resp.GetPostId(), err) + } + return content.UpsertPostResult{PostID: id, Created: resp.GetCreated()}, nil +} + +// pageBlockToProto converts one content.PageBlock to its wire form. +func pageBlockToProto(b content.PageBlock) (*abiv1.PageBlock, error) { + contentJSON, err := json.Marshal(b.Content) + if err != nil { + return nil, err + } + return &abiv1.PageBlock{ + BlockKey: b.BlockKey, + Title: b.Title, + ContentJson: contentJSON, + HtmlContent: b.HTMLContent, + Slot: b.Slot, + SortOrder: b.SortOrder, + }, nil +} diff --git a/plugin/wasmguest/caps/bridge.go b/plugin/wasmguest/caps/bridge.go index 0c2d303..4a869f3 100644 --- a/plugin/wasmguest/caps/bridge.go +++ b/plugin/wasmguest/caps/bridge.go @@ -11,25 +11,64 @@ import ( // // The bridge shares in-process Go values today; across sandboxes only the // registration/lookup *surface* serializes — the service value itself cannot -// cross. RegisterService therefore forwards only plugin/service names (the -// value is dropped), and GetService returns nil (availability is checked but a -// typed value cannot be reconstructed guest-side). Typed cross-plugin -// invocation is an open ABI item (core/docs/wasm-abi.md). -type bridgeStub struct{ base } +// cross. RegisterService therefore forwards only plugin/service names to the +// host AND records the value locally so this plugin's own services are +// dispatchable via HOOK_BRIDGE_CALL; GetService returns nil for remote +// services (availability is checked but a typed value cannot be reconstructed +// guest-side). Cross-plugin calls use Invoke (bridge.invoke) with opaque +// payloads instead. +// +// Instances are single-threaded, so the plain map needs no locking; register +// bridge services in Register (every pooled instance runs it), not Load +// (which fires on one instance only) — see core/docs/wasm-abi.md +// §"Per-instance state". +type bridgeStub struct { + base + services map[string]any // serviceName → registered value (this plugin's own) +} var _ plugin.PluginBridge = (*bridgeStub)(nil) // RegisterService has no error channel; a transport failure is dropped. -func (s *bridgeStub) RegisterService(pluginName, serviceName string, _ any) { +func (s *bridgeStub) RegisterService(pluginName, serviceName string, service any) { + if s.services == nil { + s.services = make(map[string]any) + } + s.services[serviceName] = service req := &abiv1.BridgeRegisterServiceRequest{PluginName: pluginName, ServiceName: serviceName} _ = s.invoke(context.Background(), "register_service", req, &abiv1.BridgeRegisterServiceResponse{}) } // GetService reports availability host-side but cannot return the concrete Go -// value across the sandbox boundary, so it always returns nil. Callers using -// plugin.GetServiceAs correctly observe (zero, false). +// value across the sandbox boundary, so it always returns nil for remote +// services. Callers using plugin.GetServiceAs correctly observe (zero, false); +// cross-plugin calls go through Invoke. func (s *bridgeStub) GetService(pluginName, serviceName string) any { req := &abiv1.BridgeGetServiceRequest{PluginName: pluginName, ServiceName: serviceName} _ = s.invoke(context.Background(), "get_service", req, &abiv1.BridgeGetServiceResponse{}) return nil } + +// Invoke calls a method on another plugin's registered bridge service with an +// opaque payload (bridge.invoke; the provider answers via HOOK_BRIDGE_CALL or +// its in-process plugin.BridgeInvokable). +func (s *bridgeStub) Invoke(ctx context.Context, pluginName, serviceName, method string, payload []byte) ([]byte, error) { + req := &abiv1.BridgeInvokeRequest{ + PluginName: pluginName, + ServiceName: serviceName, + Method: method, + Payload: payload, + } + resp := &abiv1.BridgeInvokeResponse{} + if err := s.invoke(ctx, "invoke", req, resp); err != nil { + return nil, err + } + return resp.GetPayload(), nil +} + +// Service returns this plugin's own registered service value, for +// HOOK_BRIDGE_CALL dispatch by the wasm shim. +func (s *bridgeStub) Service(serviceName string) (any, bool) { + v, ok := s.services[serviceName] + return v, ok +} diff --git a/plugin/wasmguest/caps/caps_roundtrip_test.go b/plugin/wasmguest/caps/caps_roundtrip_test.go index ae3a93d..b27c3a4 100644 --- a/plugin/wasmguest/caps/caps_roundtrip_test.go +++ b/plugin/wasmguest/caps/caps_roundtrip_test.go @@ -611,6 +611,137 @@ func TestCapabilityRoundTrip(t *testing.T) { } }, }, + // --- content writes (WO-WZ-019) --- + { + name: "content_create_page", wantMethod: "content.create_page", + resp: &abiv1.ContentCreatePageResponse{PageId: idItem.String(), Created: true}, + run: func(t *testing.T, cs plugin.CoreServices) { + got, err := cs.ContentAuthor.CreatePage(ctx, content.CreatePageParams{ + Slug: "/pricing", ParentSlug: "", Title: "Pricing", TemplateKey: "landing", + }) + if err != nil || got.PageID != idItem || !got.Created { + t.Errorf("create_page = %+v err = %v", got, err) + } + }, + }, + { + name: "content_set_page_blocks", wantMethod: "content.set_page_blocks", + resp: &abiv1.ContentSetPageBlocksResponse{}, + run: func(t *testing.T, cs plugin.CoreServices) { + html := "

Hi

" + err := cs.ContentAuthor.SetPageBlocks(ctx, idItem, []content.PageBlock{ + {BlockKey: "html", Title: "Hero", Content: map[string]any{"align": "center"}, HTMLContent: &html, Slot: "main", SortOrder: 1}, + {BlockKey: "cta", Title: "CTA", Content: map[string]any{"label": "Go"}, SortOrder: 2}, + }) + if err != nil { + t.Fatal(err) + } + }, + }, + { + name: "content_publish_page", wantMethod: "content.publish_page", + resp: &abiv1.ContentPublishPageResponse{}, + run: func(t *testing.T, cs plugin.CoreServices) { + if err := cs.ContentAuthor.PublishPage(ctx, idItem); err != nil { + t.Fatal(err) + } + }, + }, + { + name: "content_set_page_seo", wantMethod: "content.set_page_seo", + resp: &abiv1.ContentSetPageSeoResponse{}, + run: func(t *testing.T, cs plugin.CoreServices) { + mt, md := "Pricing — Acme", "Plans and pricing." + err := cs.ContentAuthor.SetPageSEO(ctx, idItem, content.PageSEO{MetaTitle: &mt, MetaDescription: &md}) + if err != nil { + t.Fatal(err) + } + }, + }, + { + name: "content_upsert_post", wantMethod: "content.upsert_post", + resp: &abiv1.ContentUpsertPostResponse{PostId: idRow.String(), Created: false}, + run: func(t *testing.T, cs plugin.CoreServices) { + excerpt := "hello" + got, err := cs.ContentAuthor.UpsertPost(ctx, content.UpsertPostParams{ + Slug: "hello", Title: "Hello", Document: map[string]any{"type": "doc"}, + Excerpt: &excerpt, AuthorProfileID: &idAuthor, FeaturedImageID: &idMedia, + Publish: true, + }) + if err != nil || got.PostID != idRow || got.Created { + t.Errorf("upsert_post = %+v err = %v", got, err) + } + }, + }, + // --- settings.update_plugin_settings (WO-WZ-019) --- + { + name: "settings_update_plugin_settings", wantMethod: "settings.update_plugin_settings", + resp: &abiv1.SettingsUpdatePluginSettingsResponse{}, + run: func(t *testing.T, cs plugin.CoreServices) { + err := cs.SettingsUpdater.UpdatePluginSettings(ctx, "myplugin", map[string]any{"enabled": true}) + if err != nil { + t.Fatal(err) + } + }, + }, + // --- provisioner (WO-WZ-019) --- + { + name: "provisioner_ensure_page", wantMethod: "provisioner.ensure_page", + resp: &abiv1.ProvisionerEnsurePageResponse{}, + run: func(t *testing.T, cs plugin.CoreServices) { + err := cs.Provisioner.EnsurePage(plugin.PageConfig{ + Slug: "/", Title: "Home", TemplateKey: "homepage", ReconcileBlocks: true, + Blocks: []plugin.PageBlockConfig{ + {BlockKey: "html", Title: "Hero", Content: map[string]any{"x": float64(1)}, Slot: "main", SortOrder: 1}, + }, + }) + if err != nil { + t.Fatal(err) + } + }, + }, + { + name: "provisioner_merge_site_settings", wantMethod: "provisioner.merge_site_settings", + resp: &abiv1.ProvisionerMergeSiteSettingsResponse{}, + run: func(t *testing.T, cs plugin.CoreServices) { + if err := cs.Provisioner.MergeSiteSettings(map[string]any{"site_name": "Acme"}); err != nil { + t.Fatal(err) + } + }, + }, + { + name: "provisioner_ensure_menu_item", wantMethod: "provisioner.ensure_menu_item", + resp: &abiv1.ProvisionerEnsureMenuItemResponse{}, + run: func(t *testing.T, cs plugin.CoreServices) { + err := cs.Provisioner.EnsureMenuItem("main", plugin.MenuItemConfig{Label: "Docs", PageSlug: "/docs", SortOrder: 3}) + if err != nil { + t.Fatal(err) + } + }, + }, + { + name: "provisioner_ensure_media", wantMethod: "provisioner.ensure_media", + resp: &abiv1.ProvisionerEnsureMediaResponse{}, + run: func(t *testing.T, cs plugin.CoreServices) { + err := cs.Provisioner.EnsureMedia(plugin.MediaDeposit{ + ID: idMedia, Filename: "hero.jpg", Data: []byte{1, 2, 3}, AltText: "hero", Folder: "seed", Source: "myplugin", + }) + if err != nil { + t.Fatal(err) + } + }, + }, + // --- bridge.invoke (WO-WZ-019) --- + { + name: "bridge_invoke", wantMethod: "bridge.invoke", + resp: &abiv1.BridgeInvokeResponse{Payload: []byte(`{"ok":true}`)}, + run: func(t *testing.T, cs plugin.CoreServices) { + got, err := cs.Bridge.Invoke(ctx, "symposium", "seeder", "seed_forum", []byte(`{"n":1}`)) + if err != nil || string(got) != `{"ok":true}` { + t.Errorf("bridge.invoke = %q err = %v", got, err) + } + }, + }, } for _, tc := range cases { diff --git a/plugin/wasmguest/caps/coreservices.go b/plugin/wasmguest/caps/coreservices.go index 16e7188..696dfc8 100644 --- a/plugin/wasmguest/caps/coreservices.go +++ b/plugin/wasmguest/caps/coreservices.go @@ -22,11 +22,12 @@ import ( // - MediaPath / AppURL → delivered in LoadRequest.host_config at load // - CoreServiceBindings → static manifest.core_service_bindings; host mounts func NewCoreServices(call CallFunc) plugin.CoreServices { - settings := &settingsStub{base{family: "settings", call: call}} - ai := &aiStub{base{family: "ai", call: call}} + settings := &settingsStub{base: base{family: "settings", call: call}} + ai := &aiStub{base: base{family: "ai", call: call}} return plugin.CoreServices{ Content: &contentStub{base{family: "content", call: call}}, + ContentAuthor: &authorStub{base{family: "content", call: call}}, Settings: settings, SettingsUpdater: settings, Gating: &gatingStub{base{family: "gating", call: call}}, @@ -39,11 +40,12 @@ func NewCoreServices(call CallFunc) plugin.CoreServices { ToolRegistry: ai, AITextCall: ai.textCall, EmailSender: &emailStub{base{family: "email", call: call}}, - Bridge: &bridgeStub{base{family: "bridge", call: call}}, + Bridge: &bridgeStub{base: base{family: "bridge", call: call}}, ReviewSubmitter: &reviewsStub{base{family: "reviews", call: call}}, BadgeRefresher: &badgesStub{base{family: "badges", call: call}}, JobRunner: &jobsStub{base{family: "jobs", call: call}}, EmbeddingService: &embeddingsStub{base{family: "embeddings", call: call}}, RAGService: NewRAGStub(call), + Provisioner: &provisionerStub{base{family: "provisioner", call: call}}, } } diff --git a/plugin/wasmguest/caps/provisioner.go b/plugin/wasmguest/caps/provisioner.go new file mode 100644 index 0000000..01b6299 --- /dev/null +++ b/plugin/wasmguest/caps/provisioner.go @@ -0,0 +1,189 @@ +package caps + +import ( + "context" + "encoding/json" + "fmt" + + abiv1 "git.dev.alexdunmow.com/block/core/abi/v1" + "git.dev.alexdunmow.com/block/core/plugin" + "github.com/google/uuid" +) + +// provisionerStub implements plugin.Provisioner over provisioner.* capability +// calls (WO-WZ-019). This is a LOAD-TIME capability: call it from the Load +// hook. RegisterWithProvisioner still receives a no-op at Register/DESCRIBE +// time (host functions are stubbed to fail there), so seed logic must move to +// Load — see core/docs/wasm-abi.md. +// +// Most Provisioner methods carry no context (the Go interface predates the +// ABI); calls run under the ambient invoke deadline the host enforces. +type provisionerStub struct{ base } + +var _ plugin.Provisioner = (*provisionerStub)(nil) + +func (s *provisionerStub) EnsureDataTable(config plugin.DataTableConfig) error { + req := &abiv1.ProvisionerEnsureDataTableRequest{ + Key: config.Key, + Name: config.Name, + Description: config.Description, + SchemaJson: config.Schema, + PrimaryKey: config.PrimaryKey, + } + return s.invoke(context.Background(), "ensure_data_table", req, &abiv1.ProvisionerEnsureDataTableResponse{}) +} + +func (s *provisionerStub) MergeSiteSettings(defaults map[string]any) error { + defaultsJSON, err := json.Marshal(defaults) + if err != nil { + return fmt.Errorf("provisioner.merge_site_settings: marshal defaults: %w", err) + } + req := &abiv1.ProvisionerMergeSiteSettingsRequest{DefaultsJson: defaultsJSON} + return s.invoke(context.Background(), "merge_site_settings", req, &abiv1.ProvisionerMergeSiteSettingsResponse{}) +} + +func (s *provisionerStub) EnsureSetting(key string, defaultValue any) error { + valueJSON, err := json.Marshal(defaultValue) + if err != nil { + return fmt.Errorf("provisioner.ensure_setting: marshal value: %w", err) + } + req := &abiv1.ProvisionerEnsureSettingRequest{Key: key, DefaultValueJson: valueJSON} + return s.invoke(context.Background(), "ensure_setting", req, &abiv1.ProvisionerEnsureSettingResponse{}) +} + +func (s *provisionerStub) EnsurePage(config plugin.PageConfig) error { + seed := &abiv1.PageSeed{ + Slug: config.Slug, + ParentSlug: config.ParentSlug, + Title: config.Title, + TemplateKey: config.TemplateKey, + DetailSourceType: config.DetailSourceType, + DetailSourceKey: config.DetailSourceKey, + DetailSlugField: config.DetailSlugField, + ReconcileBlocks: config.ReconcileBlocks, + ReconcileTemplate: config.ReconcileTemplate, + } + for _, b := range config.Blocks { + contentJSON, err := json.Marshal(b.Content) + if err != nil { + return fmt.Errorf("provisioner.ensure_page: block %q: marshal content: %w", b.BlockKey, err) + } + seed.Blocks = append(seed.Blocks, &abiv1.PageBlock{ + BlockKey: b.BlockKey, + Title: b.Title, + ContentJson: contentJSON, + HtmlContent: b.HtmlContent, + Slot: b.Slot, + SortOrder: b.SortOrder, + }) + } + req := &abiv1.ProvisionerEnsurePageRequest{Page: seed} + return s.invoke(context.Background(), "ensure_page", req, &abiv1.ProvisionerEnsurePageResponse{}) +} + +func (s *provisionerStub) OverrideSiteSettings(overrides map[string]any) error { + overridesJSON, err := json.Marshal(overrides) + if err != nil { + return fmt.Errorf("provisioner.override_site_settings: marshal overrides: %w", err) + } + req := &abiv1.ProvisionerOverrideSiteSettingsRequest{OverridesJson: overridesJSON} + return s.invoke(context.Background(), "override_site_settings", req, &abiv1.ProvisionerOverrideSiteSettingsResponse{}) +} + +func (s *provisionerStub) EnsureMenuItem(menuName string, config plugin.MenuItemConfig) error { + req := &abiv1.ProvisionerEnsureMenuItemRequest{ + MenuName: menuName, + Label: config.Label, + Url: config.URL, + PageSlug: config.PageSlug, + SortOrder: config.SortOrder, + } + return s.invoke(context.Background(), "ensure_menu_item", req, &abiv1.ProvisionerEnsureMenuItemResponse{}) +} + +func (s *provisionerStub) RegisterEmbeddingConfig(config plugin.EmbeddingConfigDef) error { + req := &abiv1.ProvisionerRegisterEmbeddingConfigRequest{ + TableKey: config.TableKey, + TextTemplate: config.TextTemplate, + Enabled: config.Enabled, + } + return s.invoke(context.Background(), "register_embedding_config", req, &abiv1.ProvisionerRegisterEmbeddingConfigResponse{}) +} + +// EnsureEmbed crosses the template-rendered surface only: EmbedConfig. +// RenderFunc is a function value that cannot serialize, so an ABI-provisioned +// embed must carry a Template (a RenderFunc-only embed returns an error +// rather than silently dropping the renderer). +func (s *provisionerStub) EnsureEmbed(config plugin.EmbedConfig) error { + if config.RenderFunc != nil && config.Template == "" { + return fmt.Errorf("provisioner.ensure_embed: embed %q uses RenderFunc, which cannot cross the wasm ABI — provide a Template instead", config.Key) + } + req := &abiv1.ProvisionerEnsureEmbedRequest{ + Key: config.Key, + Title: config.Title, + Description: config.Description, + Icon: config.Icon, + LabelField: config.LabelField, + Template: config.Template, + DataSourceType: config.DataSource.Type, + DataSourceTableKey: config.DataSource.TableKey, + } + return s.invoke(context.Background(), "ensure_embed", req, &abiv1.ProvisionerEnsureEmbedResponse{}) +} + +func (s *provisionerStub) EnsureJobSchedule(config plugin.JobScheduleConfig) error { + req := &abiv1.ProvisionerEnsureJobScheduleRequest{ + JobType: config.JobType, + CronExpression: config.CronExpression, + ConfigJson: config.Config, + } + return s.invoke(context.Background(), "ensure_job_schedule", req, &abiv1.ProvisionerEnsureJobScheduleResponse{}) +} + +func (s *provisionerStub) UpdateDataTableRowField(ctx context.Context, rowID uuid.UUID, fieldKey string, value any) error { + valueJSON, err := json.Marshal(value) + if err != nil { + return fmt.Errorf("provisioner.update_data_table_row_field: marshal value: %w", err) + } + req := &abiv1.ProvisionerUpdateDataTableRowFieldRequest{ + RowId: rowID.String(), + FieldKey: fieldKey, + ValueJson: valueJSON, + } + return s.invoke(ctx, "update_data_table_row_field", req, &abiv1.ProvisionerUpdateDataTableRowFieldResponse{}) +} + +func (s *provisionerStub) DisableOrphanedJobSchedules(registeredTypes []string) error { + req := &abiv1.ProvisionerDisableOrphanedJobSchedulesRequest{RegisteredTypes: registeredTypes} + return s.invoke(context.Background(), "disable_orphaned_job_schedules", req, &abiv1.ProvisionerDisableOrphanedJobSchedulesResponse{}) +} + +func (s *provisionerStub) EnsurePlugin(name string) error { + req := &abiv1.ProvisionerEnsurePluginRequest{Name: name} + return s.invoke(context.Background(), "ensure_plugin", req, &abiv1.ProvisionerEnsurePluginResponse{}) +} + +func (s *provisionerStub) EnsureCustomColor(config plugin.CustomColorConfig) error { + req := &abiv1.ProvisionerEnsureCustomColorRequest{ + Name: config.Name, + LightValue: config.LightValue, + DarkValue: config.DarkValue, + Source: config.Source, + } + return s.invoke(context.Background(), "ensure_custom_color", req, &abiv1.ProvisionerEnsureCustomColorResponse{}) +} + +func (s *provisionerStub) EnsureMedia(deposit plugin.MediaDeposit) error { + if deposit.ID == uuid.Nil { + return fmt.Errorf("provisioner.ensure_media: MediaDeposit.ID is required (the deterministic, template-referable key)") + } + req := &abiv1.ProvisionerEnsureMediaRequest{ + Id: deposit.ID.String(), + Filename: deposit.Filename, + Data: deposit.Data, + AltText: deposit.AltText, + Folder: deposit.Folder, + Source: deposit.Source, + } + return s.invoke(context.Background(), "ensure_media", req, &abiv1.ProvisionerEnsureMediaResponse{}) +} diff --git a/plugin/wasmguest/caps/settings.go b/plugin/wasmguest/caps/settings.go index 9d53b47..8bee97b 100644 --- a/plugin/wasmguest/caps/settings.go +++ b/plugin/wasmguest/caps/settings.go @@ -42,3 +42,12 @@ func (s *settingsStub) UpdateSiteSetting(ctx context.Context, key string, value req := &abiv1.SettingsUpdateSiteSettingRequest{Key: key, ValueJson: valueJSON} return s.invoke(ctx, "update_site_setting", req, &abiv1.SettingsUpdateSiteSettingResponse{}) } + +func (s *settingsStub) UpdatePluginSettings(ctx context.Context, pluginName string, settingsMap map[string]any) error { + settingsJSON, err := json.Marshal(settingsMap) + if err != nil { + return err + } + req := &abiv1.SettingsUpdatePluginSettingsRequest{PluginName: pluginName, SettingsJson: settingsJSON} + return s.invoke(ctx, "update_plugin_settings", req, &abiv1.SettingsUpdatePluginSettingsResponse{}) +} diff --git a/plugin/wasmguest/caps/testdata/golden/bridge_invoke_req.pb b/plugin/wasmguest/caps/testdata/golden/bridge_invoke_req.pb new file mode 100644 index 0000000..8ee401d --- /dev/null +++ b/plugin/wasmguest/caps/testdata/golden/bridge_invoke_req.pb @@ -0,0 +1,3 @@ + + symposiumseeder +seed_forum"{"n":1} \ No newline at end of file diff --git a/plugin/wasmguest/caps/testdata/golden/bridge_invoke_resp.pb b/plugin/wasmguest/caps/testdata/golden/bridge_invoke_resp.pb new file mode 100644 index 0000000..c78e5e1 --- /dev/null +++ b/plugin/wasmguest/caps/testdata/golden/bridge_invoke_resp.pb @@ -0,0 +1,2 @@ + + {"ok":true} \ No newline at end of file diff --git a/plugin/wasmguest/caps/testdata/golden/content_create_page_req.pb b/plugin/wasmguest/caps/testdata/golden/content_create_page_req.pb new file mode 100644 index 0000000..ecef402 --- /dev/null +++ b/plugin/wasmguest/caps/testdata/golden/content_create_page_req.pb @@ -0,0 +1,2 @@ + +/pricingPricing"landing \ No newline at end of file diff --git a/plugin/wasmguest/caps/testdata/golden/content_create_page_resp.pb b/plugin/wasmguest/caps/testdata/golden/content_create_page_resp.pb new file mode 100644 index 0000000..0e950ea --- /dev/null +++ b/plugin/wasmguest/caps/testdata/golden/content_create_page_resp.pb @@ -0,0 +1,2 @@ + +$44444444-4444-4444-4444-444444444444 \ No newline at end of file diff --git a/plugin/wasmguest/caps/testdata/golden/content_publish_page_req.pb b/plugin/wasmguest/caps/testdata/golden/content_publish_page_req.pb new file mode 100644 index 0000000..f4e8311 --- /dev/null +++ b/plugin/wasmguest/caps/testdata/golden/content_publish_page_req.pb @@ -0,0 +1,2 @@ + +$44444444-4444-4444-4444-444444444444 \ No newline at end of file diff --git a/plugin/wasmguest/caps/testdata/golden/content_publish_page_resp.pb b/plugin/wasmguest/caps/testdata/golden/content_publish_page_resp.pb new file mode 100644 index 0000000..e69de29 diff --git a/plugin/wasmguest/caps/testdata/golden/content_set_page_blocks_req.pb b/plugin/wasmguest/caps/testdata/golden/content_set_page_blocks_req.pb new file mode 100644 index 0000000..b70c2a2 --- /dev/null +++ b/plugin/wasmguest/caps/testdata/golden/content_set_page_blocks_req.pb @@ -0,0 +1,4 @@ + +$44444444-4444-4444-4444-4444444444445 +htmlHero{"align":"center"}"

Hi

*main0 +ctaCTA{"label":"Go"}0 \ No newline at end of file diff --git a/plugin/wasmguest/caps/testdata/golden/content_set_page_blocks_resp.pb b/plugin/wasmguest/caps/testdata/golden/content_set_page_blocks_resp.pb new file mode 100644 index 0000000..e69de29 diff --git a/plugin/wasmguest/caps/testdata/golden/content_set_page_seo_req.pb b/plugin/wasmguest/caps/testdata/golden/content_set_page_seo_req.pb new file mode 100644 index 0000000..d3fabb4 --- /dev/null +++ b/plugin/wasmguest/caps/testdata/golden/content_set_page_seo_req.pb @@ -0,0 +1,2 @@ + +$44444444-4444-4444-4444-444444444444Pricing — AcmePlans and pricing. \ No newline at end of file diff --git a/plugin/wasmguest/caps/testdata/golden/content_set_page_seo_resp.pb b/plugin/wasmguest/caps/testdata/golden/content_set_page_seo_resp.pb new file mode 100644 index 0000000..e69de29 diff --git a/plugin/wasmguest/caps/testdata/golden/content_upsert_post_req.pb b/plugin/wasmguest/caps/testdata/golden/content_upsert_post_req.pb new file mode 100644 index 0000000..00f65e3 --- /dev/null +++ b/plugin/wasmguest/caps/testdata/golden/content_upsert_post_req.pb @@ -0,0 +1,2 @@ + +helloHello{"type":"doc"}"hello*$22222222-2222-2222-2222-2222222222222$99999999-9999-9999-9999-9999999999998 \ No newline at end of file diff --git a/plugin/wasmguest/caps/testdata/golden/content_upsert_post_resp.pb b/plugin/wasmguest/caps/testdata/golden/content_upsert_post_resp.pb new file mode 100644 index 0000000..8a8e203 --- /dev/null +++ b/plugin/wasmguest/caps/testdata/golden/content_upsert_post_resp.pb @@ -0,0 +1,2 @@ + +$bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb \ No newline at end of file diff --git a/plugin/wasmguest/caps/testdata/golden/provisioner_ensure_media_req.pb b/plugin/wasmguest/caps/testdata/golden/provisioner_ensure_media_req.pb new file mode 100644 index 0000000..c233c34 --- /dev/null +++ b/plugin/wasmguest/caps/testdata/golden/provisioner_ensure_media_req.pb @@ -0,0 +1,2 @@ + +$99999999-9999-9999-9999-999999999999hero.jpg"hero*seed2myplugin \ No newline at end of file diff --git a/plugin/wasmguest/caps/testdata/golden/provisioner_ensure_media_resp.pb b/plugin/wasmguest/caps/testdata/golden/provisioner_ensure_media_resp.pb new file mode 100644 index 0000000..e69de29 diff --git a/plugin/wasmguest/caps/testdata/golden/provisioner_ensure_menu_item_req.pb b/plugin/wasmguest/caps/testdata/golden/provisioner_ensure_menu_item_req.pb new file mode 100644 index 0000000..c486d4f --- /dev/null +++ b/plugin/wasmguest/caps/testdata/golden/provisioner_ensure_menu_item_req.pb @@ -0,0 +1,2 @@ + +mainDocs"/docs( \ No newline at end of file diff --git a/plugin/wasmguest/caps/testdata/golden/provisioner_ensure_menu_item_resp.pb b/plugin/wasmguest/caps/testdata/golden/provisioner_ensure_menu_item_resp.pb new file mode 100644 index 0000000..e69de29 diff --git a/plugin/wasmguest/caps/testdata/golden/provisioner_ensure_page_req.pb b/plugin/wasmguest/caps/testdata/golden/provisioner_ensure_page_req.pb new file mode 100644 index 0000000..1f5bb6f --- /dev/null +++ b/plugin/wasmguest/caps/testdata/golden/provisioner_ensure_page_req.pb @@ -0,0 +1,4 @@ + +4 +/Home"homepage* +htmlHero{"x":1}*main0H \ No newline at end of file diff --git a/plugin/wasmguest/caps/testdata/golden/provisioner_ensure_page_resp.pb b/plugin/wasmguest/caps/testdata/golden/provisioner_ensure_page_resp.pb new file mode 100644 index 0000000..e69de29 diff --git a/plugin/wasmguest/caps/testdata/golden/provisioner_merge_site_settings_req.pb b/plugin/wasmguest/caps/testdata/golden/provisioner_merge_site_settings_req.pb new file mode 100644 index 0000000..770376a --- /dev/null +++ b/plugin/wasmguest/caps/testdata/golden/provisioner_merge_site_settings_req.pb @@ -0,0 +1,2 @@ + +{"site_name":"Acme"} \ No newline at end of file diff --git a/plugin/wasmguest/caps/testdata/golden/provisioner_merge_site_settings_resp.pb b/plugin/wasmguest/caps/testdata/golden/provisioner_merge_site_settings_resp.pb new file mode 100644 index 0000000..e69de29 diff --git a/plugin/wasmguest/caps/testdata/golden/settings_update_plugin_settings_req.pb b/plugin/wasmguest/caps/testdata/golden/settings_update_plugin_settings_req.pb new file mode 100644 index 0000000..e19fe85 --- /dev/null +++ b/plugin/wasmguest/caps/testdata/golden/settings_update_plugin_settings_req.pb @@ -0,0 +1,2 @@ + +myplugin{"enabled":true} \ No newline at end of file diff --git a/plugin/wasmguest/caps/testdata/golden/settings_update_plugin_settings_resp.pb b/plugin/wasmguest/caps/testdata/golden/settings_update_plugin_settings_resp.pb new file mode 100644 index 0000000..e69de29 diff --git a/plugin/wasmguest/dispatch.go b/plugin/wasmguest/dispatch.go index b8c6ea4..7683bc6 100644 --- a/plugin/wasmguest/dispatch.go +++ b/plugin/wasmguest/dispatch.go @@ -12,6 +12,7 @@ import ( "time" abiv1 "git.dev.alexdunmow.com/block/core/abi/v1" + "git.dev.alexdunmow.com/block/core/ai" "git.dev.alexdunmow.com/block/core/blocks" "git.dev.alexdunmow.com/block/core/plugin" "git.dev.alexdunmow.com/block/core/plugin/wasmguest/bnwasm" @@ -102,8 +103,11 @@ func newGuest(reg plugin.PluginRegistration) *guest { } // runRegister invokes Register (or RegisterWithProvisioner with a no-op -// provisioner — provisioning itself runs host-side at load) against capture -// registries, converting panics to errors. +// provisioner) against capture registries, converting panics to errors. +// Register-time provisioning cannot cross the ABI (DESCRIBE stubs every host +// function to fail), so RegisterWithProvisioner's provisioner is inert here; +// wasm plugins provision from Load via deps.Provisioner (the provisioner.* +// capability family, WO-WZ-019) instead. func runRegister(reg plugin.PluginRegistration, tr *captureTemplateRegistry, br *captureBlockRegistry) (err error) { defer func() { if r := recover(); r != nil { @@ -186,6 +190,14 @@ func (g *guest) invoke(hookID uint32, req []byte) (out []byte) { payload, abiErr = g.ragFetch(ctx, env.GetPayload()) case abiv1.Hook_HOOK_MEDIA_HOOK: payload, abiErr = g.mediaHook(ctx, env.GetPayload()) + case abiv1.Hook_HOOK_AI_TOOL_CALL: + payload, abiErr = g.aiToolCall(ctx, env.GetPayload()) + case abiv1.Hook_HOOK_BRIDGE_CALL: + payload, abiErr = g.bridgeCall(ctx, env.GetPayload()) + case abiv1.Hook_HOOK_DIRECTORY_PANEL_SECTION: + payload, abiErr = g.directoryPanelSection(env.GetPayload()) + case abiv1.Hook_HOOK_DIRECTORY_PIN_DECORATOR: + payload, abiErr = g.directoryPinDecorator(env.GetPayload()) default: abiErr = &abiv1.AbiError{ Code: abiv1.AbiErrorCode_ABI_ERROR_CODE_UNIMPLEMENTED, @@ -390,9 +402,16 @@ func (g *guest) runJob(ctx context.Context, payload []byte) (proto.Message, *abi Message: "unknown job type " + req.GetJobType(), } } - // Job progress reporting needs a jobs.progress host function — an ABI - // open item (core/docs/wasm-abi.md); v1 discards progress updates. - progress := func(current, total int, message string) {} + // Progress crosses as best-effort jobs.progress host calls; the host + // correlates them to the running job via the HOOK_JOB call's context. A + // nil transport (native builds) discards updates. + progress := func(current, total int, message string) { + if capTransport == nil { + return + } + preq := &abiv1.JobsProgressRequest{Current: int32(current), Total: int32(total), Message: message} + _ = capTransport("jobs.progress", preq, &abiv1.JobsProgressResponse{}) + } result, err := handler(ctx, req.GetConfigJson(), progress) if err != nil { return nil, internalError(err.Error()) @@ -533,6 +552,163 @@ func (g *guest) ragFetcher(contentType string) (plugin.ContentFetcher, bool) { return g.rag.Fetcher(contentType) } +// toolLookup / serviceLookup are the recording-stub accessors dispatch needs +// for HOOK_AI_TOOL_CALL / HOOK_BRIDGE_CALL. The caps stubs implement them; +// asserting interfaces keeps the stub types unexported. +type toolLookup interface { + Tool(slug string) (*ai.ToolDefinition, bool) +} + +type serviceLookup interface { + Service(serviceName string) (any, bool) +} + +// aiToolCall executes a guest-registered AI tool handler (HOOK_AI_TOOL_CALL). +// Tools must be registered in Register (every pooled instance runs it) for the +// lookup to succeed on any instance — see wasm-abi.md §"Per-instance state". +func (g *guest) aiToolCall(ctx context.Context, payload []byte) (proto.Message, *abiv1.AbiError) { + req := &abiv1.AiToolCallRequest{} + if err := proto.Unmarshal(payload, req); err != nil { + return nil, decodeError("AiToolCallRequest", err) + } + reg, ok := g.services.ToolRegistry.(toolLookup) + if !ok { + return nil, &abiv1.AbiError{ + Code: abiv1.AbiErrorCode_ABI_ERROR_CODE_UNIMPLEMENTED, + Message: "tool registry does not record handlers", + } + } + tool, ok := reg.Tool(req.GetSlug()) + if !ok || tool.Handler == nil { + return nil, &abiv1.AbiError{ + Code: abiv1.AbiErrorCode_ABI_ERROR_CODE_UNIMPLEMENTED, + Message: "no handler for AI tool " + req.GetSlug() + " on this instance (register tools in Register, not Load)", + } + } + var params map[string]any + if raw := req.GetParamsJson(); len(raw) > 0 { + if err := json.Unmarshal(raw, ¶ms); err != nil { + return nil, decodeError("AiToolCallRequest.params_json", err) + } + } + result, err := tool.Handler(ctx, params) + if err != nil { + return nil, internalError(err.Error()) + } + resp := &abiv1.AiToolCallResponse{} + if result != nil { + resp.Content = result.Content + resp.ErrorMessage = result.Error + } + return resp, nil +} + +// bridgeCall invokes a method on one of THIS plugin's registered bridge +// services (HOOK_BRIDGE_CALL; the consumer side is the bridge.invoke +// capability). The service value must implement plugin.BridgeInvokable and be +// registered in Register so every pooled instance has it. +func (g *guest) bridgeCall(ctx context.Context, payload []byte) (proto.Message, *abiv1.AbiError) { + req := &abiv1.BridgeCallRequest{} + if err := proto.Unmarshal(payload, req); err != nil { + return nil, decodeError("BridgeCallRequest", err) + } + lookup, ok := g.services.Bridge.(serviceLookup) + if !ok { + return nil, &abiv1.AbiError{ + Code: abiv1.AbiErrorCode_ABI_ERROR_CODE_UNIMPLEMENTED, + Message: "bridge does not record services", + } + } + svc, ok := lookup.Service(req.GetServiceName()) + if !ok { + return nil, &abiv1.AbiError{ + Code: abiv1.AbiErrorCode_ABI_ERROR_CODE_UNIMPLEMENTED, + Message: "no bridge service " + req.GetServiceName() + " on this instance (register services in Register, not Load)", + } + } + invokable, ok := svc.(plugin.BridgeInvokable) + if !ok { + return nil, &abiv1.AbiError{ + Code: abiv1.AbiErrorCode_ABI_ERROR_CODE_UNIMPLEMENTED, + Message: "bridge service " + req.GetServiceName() + " does not implement plugin.BridgeInvokable", + } + } + out, err := invokable.InvokeBridge(ctx, req.GetMethod(), req.GetPayload()) + if err != nil { + return nil, internalError(err.Error()) + } + return &abiv1.BridgeCallResponse{Payload: out}, nil +} + +// directoryExtensions resolves the registration's DirectoryExtensions value, +// nil when the plugin declares none. +func (g *guest) directoryExtensions() *plugin.DirectoryExtensions { + if g.reg.DirectoryExtensions == nil { + return nil + } + return g.reg.DirectoryExtensions() +} + +// directoryPanelSection renders the index-th registered panel section +// (HOOK_DIRECTORY_PANEL_SECTION). +func (g *guest) directoryPanelSection(payload []byte) (proto.Message, *abiv1.AbiError) { + req := &abiv1.DirectoryPanelSectionRequest{} + if err := proto.Unmarshal(payload, req); err != nil { + return nil, decodeError("DirectoryPanelSectionRequest", err) + } + ext := g.directoryExtensions() + idx := int(req.GetIndex()) + if ext == nil || idx >= len(ext.PanelSections) || ext.PanelSections[idx] == nil { + return nil, &abiv1.AbiError{ + Code: abiv1.AbiErrorCode_ABI_ERROR_CODE_UNIMPLEMENTED, + Message: fmt.Sprintf("no directory panel section at index %d", idx), + } + } + var data map[string]any + if raw := req.GetDataJson(); len(raw) > 0 { + if err := json.Unmarshal(raw, &data); err != nil { + return nil, decodeError("DirectoryPanelSectionRequest.data_json", err) + } + } + return &abiv1.DirectoryPanelSectionResponse{Html: ext.PanelSections[idx](data)}, nil +} + +// directoryPinDecorator runs the index-th registered pin decorator, which +// mutates the pin map in place; the mutated pin is returned +// (HOOK_DIRECTORY_PIN_DECORATOR). +func (g *guest) directoryPinDecorator(payload []byte) (proto.Message, *abiv1.AbiError) { + req := &abiv1.DirectoryPinDecoratorRequest{} + if err := proto.Unmarshal(payload, req); err != nil { + return nil, decodeError("DirectoryPinDecoratorRequest", err) + } + ext := g.directoryExtensions() + idx := int(req.GetIndex()) + if ext == nil || idx >= len(ext.PinDecorators) || ext.PinDecorators[idx] == nil { + return nil, &abiv1.AbiError{ + Code: abiv1.AbiErrorCode_ABI_ERROR_CODE_UNIMPLEMENTED, + Message: fmt.Sprintf("no directory pin decorator at index %d", idx), + } + } + pin := map[string]any{} + if raw := req.GetPinJson(); len(raw) > 0 { + if err := json.Unmarshal(raw, &pin); err != nil { + return nil, decodeError("DirectoryPinDecoratorRequest.pin_json", err) + } + } + var data map[string]any + if raw := req.GetDataJson(); len(raw) > 0 { + if err := json.Unmarshal(raw, &data); err != nil { + return nil, decodeError("DirectoryPinDecoratorRequest.data_json", err) + } + } + ext.PinDecorators[idx](pin, data) + pinJSON, err := json.Marshal(pin) + if err != nil { + return nil, internalError("marshal mutated pin: " + err.Error()) + } + return &abiv1.DirectoryPinDecoratorResponse{PinJson: pinJSON}, nil +} + // sortedKeys returns the map's keys in sorted order (deterministic manifests). func sortedKeys[V any](m map[string]V) []string { keys := make([]string, 0, len(m)) diff --git a/settings/settings.go b/settings/settings.go index 0f5393f..7f2fc8c 100644 --- a/settings/settings.go +++ b/settings/settings.go @@ -8,9 +8,13 @@ type Settings interface { GetPluginSettings(ctx context.Context, pluginName string) (map[string]any, error) } -// Updater allows plugins to modify site settings. +// Updater allows plugins to modify site settings and their own plugin +// settings. type Updater interface { UpdateSiteSetting(ctx context.Context, key string, value any) error + // UpdatePluginSettings replaces the plugin's own settings map. Across the + // wasm ABI the host enforces that pluginName matches the calling plugin. + UpdatePluginSettings(ctx context.Context, pluginName string, settings map[string]any) error } // GetStringOr returns a string value from a map, or defaultVal if not found/wrong type.