feat(ui): derive advanced/composite-child kind flag from the backend#117
Merged
Conversation
The UI's "adv" chip + create-form banner for composite-child kinds (K3sNode, AgentInstall) were driven by a hardcoded ADVANCED_KINDS map in catalogue.ts. That map only knew the two built-in k3s kinds and couldn't flag an external plugin's composite children. Make it a backend-derived signal instead: - providers.AdvancedKindDescriber: an optional provider capability. A provider declares which of its OWN kinds are composite-children, each with an owner kind + note. Only own-kinds are eligible, so a k3s Cluster's proxmox VirtualMachine child is correctly NOT flagged. - k3s provider implements it (K3sNode + AgentInstall -> Cluster), moving the note prose out of the frontend. - SchemaInfo gains advanced/owner_kind/advanced_note; ListSchemas stamps them by joining schema.Registry() against the provider registry (wired into the schema handler). Nil registry -> nothing flagged. - External plugins carry it too: pluginproto.KindInfo gains ownerKind/advancedNote, forwarded by the external adapter's AdvancedKinds(). - UI drops ADVANCED_KINDS; advancedKind() now reads the backend fields off the catalogue, and the "Create a <owner> instead" link derives the owner's apiVersion from the child (same provider) instead of hardcoding k3s. Tests: schema handler stamping (flagged child, unflagged owner + VM, nil registry) and external adapter forwarding.
astrojerms
added a commit
that referenced
this pull request
Jul 8, 2026
…e-child (#118) The pluginproto ownerKind/advancedNote handshake field (from #117) had no plugin exercising it. Make plugins/example a reference for it. - New Notebook kind: a Planner composite that expands (via Plan) into one Note child per spec.page, stamping owner labels on each child. Notebook itself is file-backed (a .notebook marker lists its children) so its Apply/Get/List/Delete are complete CRUD; the plugin creates its child Notes directly (there's no controller-side auto-expansion for external composites — Plan feeds the UI children graph). - Note is declared a composite-child of Notebook in the handshake (OwnerKind + AdvancedNote), so the UI flags it "advanced" and nudges toward creating a Notebook — driven entirely by the backend signal, no client-side list. Note stays directly authorable. - The external e2e test now asserts the advanced declaration survives the real subprocess wire round-trip into AdvancedKindDescriber. - docs/plugin-protocol.md documents OwnerKind/AdvancedNote and points at the Notebook->Note composite.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The UI's "adv" chip (nav) and create-form banner for composite-child kinds —
K3sNode,AgentInstall— were driven by a hardcodedADVANCED_KINDSmap incatalogue.ts. That map only knew the two built-in k3s kinds; an external plugin's composite children got no chip. This moves the "advancedness" of a kind to a backend-derived signal so it's provider-agnostic.What
providers.AdvancedKindDescriber— a new optional provider capability. A provider declares which of its own kinds are composite-children, each with an owner kind + note. Only own-kinds are eligible, which is exactly why a k3sCluster's proxmoxVirtualMachinechild stays un-flagged (it's proxmox's first-class kind).K3sNode+AgentInstall→Cluster), moving the note prose out of the frontend to the provider that owns the knowledge.SchemaInfogainsadvanced/owner_kind/advanced_note.SchemaService.ListSchemasstamps them by joiningschema.Registry()against the provider registry (now wired into the schema handler). A nil registry flags nothing.pluginproto.KindInfogainsownerKind/advancedNote(JSON handshake, no codegen), forwarded by the external adapter'sAdvancedKinds().ADVANCED_KINDS;advancedKind()reads the backend fields off the catalogue, and the "Create a <owner> instead →" link derives the owner's apiVersion from the child (same provider) rather than hardcodingk3s.openctl.io/v1.No behavior change for users: the same two kinds are flagged with the same prose — but now any plugin composite is flagged with zero client-side list.
Tests
schema_test.go: ListSchemas stamps the declared child, leaves the owningClusterand an undeclaredVirtualMachineun-flagged, and flags nothing with a nil registry.external_test.go: adapter forwardsownerKind/advancedNotefrom the handshake throughAdvancedKindDescriber.Local CI
gofmt / go vet / staticcheck / golangci-lint (root + both plugins) / modernize (generated-filtered) /
make test/go test -raceall green. UIsvelte-checkclean.