Feat v0.10.0 panel manifest lifecycle

Panels are a new kernel rendering tier between surfaces and block
renderers, enabling composable companion views (e.g. notes panel
inside chat). This version ships the plumbing layer:

- Manifest validation for panels field (provider map + consumer array)
- Soft-dep warning at install time for unresolved panel consumers
- PanelMeta struct + resolvePanels() resolves consumers at surface load
- window.__PANELS__ injected into base template
- sw.panels SDK module (open/close/toggle/isOpen/isAvailable/list/active)
- Lazy JS loading pipeline with module caching
- 10 new tests (6 validation + 4 resolve)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-03 21:03:22 +00:00
parent 414b2290ce
commit b937580ed8
9 changed files with 561 additions and 2 deletions

View File

@@ -349,6 +349,22 @@ func (h *PackageHandler) InstallPackage(c *gin.Context) {
}
}
// Phase 11: Soft-dep warnings for panel consumers
if len(mInfo.PanelConsumers) > 0 {
for _, ref := range mInfo.PanelConsumers {
parts := strings.SplitN(ref, ".", 2)
if len(parts) != 2 {
continue
}
provPkg, _ := h.stores.Packages.Get(c.Request.Context(), parts[0])
if provPkg == nil {
log.Printf("[packages] %s: panel consumer %q — provider package %q not installed", pkgID, ref, parts[0])
} else if !provPkg.Enabled {
log.Printf("[packages] %s: panel consumer %q — provider package %q is disabled", pkgID, ref, parts[0])
}
}
}
resp := gin.H{
"id": pkgID,
"title": mInfo.Title,