diff --git a/server/events/bus_test.go b/server/events/bus_test.go index 1441e59..091a0a6 100644 --- a/server/events/bus_test.go +++ b/server/events/bus_test.go @@ -113,7 +113,7 @@ func TestRouteFor(t *testing.T) { {"pong", DirToClient}, // Tool bridge routes {"tool.call.abc123", DirToClient}, - {"tool.result.abc123", DirBoth}, // v0.32.0: DirBoth for cross-pod WaitFor + {"tool.result.abc123", DirBoth}, // Extension lifecycle {"extension.loaded", DirLocal}, {"extension.error", DirLocal}, @@ -227,7 +227,6 @@ func TestToolCallRouteToClient(t *testing.T) { } func TestToolResultRouteBoth(t *testing.T) { - // v0.32.0: tool.result is DirBoth so results cross pods for WaitFor. // The WS subscriber explicitly filters out tool.result events to // prevent re-sending to clients (see subscribeToBus in ws.go). if !ShouldAcceptFromClient("tool.result.abc123") { diff --git a/server/events/ticket_adapter.go b/server/events/ticket_adapter.go index 8063983..956bd9e 100644 --- a/server/events/ticket_adapter.go +++ b/server/events/ticket_adapter.go @@ -1,6 +1,5 @@ package events -// v0.32.0: TicketValidatorAdapter bridges the context-aware store.TicketStore // to the middleware.TicketValidator interface (which has no context parameter). // Replaces the in-memory TicketStore that lived in this file previously. diff --git a/server/events/types.go b/server/events/types.go index 5ace1d5..036dcb7 100644 --- a/server/events/types.go +++ b/server/events/types.go @@ -9,7 +9,6 @@ type Event struct { Payload json.RawMessage `json:"payload"` Ts int64 `json:"ts"` - // v0.32.0: Cross-pod targeted delivery. When set, only connections // belonging to this user receive the event. Serialized for pg_broadcast // (harmless if clients see it — they ignore unknown fields). TargetUserID string `json:"target_user_id,omitempty"` @@ -38,8 +37,8 @@ var routeTable = map[string]Direction{ // User/presence "user.presence": DirToClient, "user.status": DirToClient, - "user.mentioned": DirToClient, // v0.23.2: targeted @mention notification - "typing.user": DirToClient, // v0.23.2: human typing in DM/channel + "user.mentioned": DirToClient, + "typing.user": DirToClient, // System "system.notify": DirToClient, @@ -77,7 +76,7 @@ var routeTable = map[string]Direction{ // Tool execution (browser tools bridge) "tool.call.": DirToClient, // Server → specific client (browser tool invocation) - "tool.result.": DirBoth, // v0.32.0: DirBoth — result must cross pods for WaitFor + "tool.result.": DirBoth, // Extension lifecycle "extension.loaded": DirLocal, // Client-only diff --git a/server/events/ws.go b/server/events/ws.go index 64f1f7f..06c6a56 100644 --- a/server/events/ws.go +++ b/server/events/ws.go @@ -174,7 +174,6 @@ func (h *Hub) IsConnected(userID string) bool { } // PublishToUser sends an event to a specific user via the bus. -// v0.32.0: Cross-pod safe — the bus broadcast hook fans out via pg_notify. // All replicas receive the event; only the one with the user's connection delivers it. func (h *Hub) PublishToUser(userID string, event Event) { event.TargetUserID = userID @@ -238,13 +237,11 @@ func (c *Conn) subscribeToBus() { return } - // v0.32.0: Targeted delivery — only deliver to the intended user. // Targeted events skip room filtering (user-scoped, not room-scoped). if e.TargetUserID != "" && e.TargetUserID != c.userID { return } - // v0.32.0: tool.result travels cross-pod for WaitFor (DirBoth) but // must not be forwarded to WebSocket clients — they sent it. if strings.HasPrefix(e.Label, "tool.result.") { return @@ -316,7 +313,6 @@ func (c *Conn) readPump() { continue } - // v0.5.0: Room management — intercept before bus publish (like ping) if event.Label == "room.subscribe" { var req struct { Room string `json:"room"` diff --git a/server/handlers/admin_connections.go b/server/handlers/admin_connections.go index c14e116..f624613 100644 --- a/server/handlers/admin_connections.go +++ b/server/handlers/admin_connections.go @@ -1,6 +1,5 @@ package handlers -// v0.38.1: Extension connection handlers — admin/global scope. // Methods on AdminHandler, mirrors admin provider config pattern. import ( diff --git a/server/handlers/auth.go b/server/handlers/auth.go index 2b46a46..2f9d3eb 100644 --- a/server/handlers/auth.go +++ b/server/handlers/auth.go @@ -345,7 +345,6 @@ func hashToken(token string) string { // - AdminHandler.destroyVault (admin-initiated reset) // // Does NOT evict from UEK cache or write audit logs — callers handle that. -// v0.29.0: accepts stores instead of using database.DB directly. func DestroyVaultDB(ctx context.Context, stores store.Stores, userID string) (deleted int64) { if err := stores.Users.ClearVaultKeys(ctx, userID); err != nil { log.Printf("⚠ DestroyVaultDB: failed to clear vault columns for user %s: %v", userID, err) @@ -366,8 +365,6 @@ func DestroyVaultDB(ctx context.Context, stores store.Stores, userID string) (de // sessions survive server restarts. // // Used by BootstrapAdmin and SeedUsers where the password is known at startup. -// v0.29.0: accepts stores instead of using database.DB directly. -// v0.30.2: accepts optional uekCache to pre-warm vault on restart. func ProbeAndRepairVault(ctx context.Context, stores store.Stores, userID, password string, uekCache ...*crypto.UEKCache) { vaultSet, encryptedUEK, salt, nonce, err := stores.Users.GetVaultKeys(ctx, userID) if err != nil || !vaultSet { diff --git a/server/handlers/connection_resolver.go b/server/handlers/connection_resolver.go index e0ef176..473c889 100644 --- a/server/handlers/connection_resolver.go +++ b/server/handlers/connection_resolver.go @@ -1,6 +1,5 @@ package handlers -// v0.38.1: ConnectionResolver bridges the sandbox connections module // to the store + vault layers. Implements sandbox.ConnectionResolver. import ( diff --git a/server/handlers/connection_types.go b/server/handlers/connection_types.go index 487af54..cfbd1f7 100644 --- a/server/handlers/connection_types.go +++ b/server/handlers/connection_types.go @@ -1,6 +1,5 @@ package handlers -// v0.38.4: Connection type discovery endpoint. // Returns merged connection types from all active packages. // Library declarations take precedence over non-library declarations. diff --git a/server/handlers/connections.go b/server/handlers/connections.go index dc5074b..b8e0fbd 100644 --- a/server/handlers/connections.go +++ b/server/handlers/connections.go @@ -1,6 +1,5 @@ package handlers -// v0.38.1: Extension connection handlers — personal scope + resolution. // Pattern follows apiconfigs.go (ProviderConfigHandler). import ( @@ -28,7 +27,6 @@ func NewConnectionHandler(s store.Stores, vault *crypto.KeyResolver) *Connection // ListConnections returns the user's personal connections. func (h *ConnectionHandler) ListConnections(c *gin.Context) { userID := getUserID(c) - // v0.38.5: Show all accessible connections (personal + team + global) // so users can see which connections are available to them. conns, err := h.stores.Connections.ListAccessible(c.Request.Context(), userID) if err != nil { diff --git a/server/handlers/ext_api.go b/server/handlers/ext_api.go index dd902cd..3531f5a 100644 --- a/server/handlers/ext_api.go +++ b/server/handlers/ext_api.go @@ -1,6 +1,5 @@ // Package handlers — ext_api.go // -// v0.29.1 CS1: Extension API routes. Starlark packages serve custom // JSON endpoints via the existing Gin router. Mounted at // /s/:slug/api/*path with JWT auth. // diff --git a/server/handlers/ext_db_schema.go b/server/handlers/ext_db_schema.go index c29fdf4..aadb49a 100644 --- a/server/handlers/ext_db_schema.go +++ b/server/handlers/ext_db_schema.go @@ -1,6 +1,6 @@ package handlers -// ext_db_schema.go — v0.29.2 +// ext_db_schema.go // // DDL generation and lifecycle management for extension-owned database tables. // Tables are namespaced as ext_{pkg_slug}_{logical_name} and tracked in the diff --git a/server/handlers/extension_permissions.go b/server/handlers/extension_permissions.go index 92ae66f..8ae3521 100644 --- a/server/handlers/extension_permissions.go +++ b/server/handlers/extension_permissions.go @@ -10,7 +10,6 @@ import ( ) // ExtPermHandler serves extension permission management endpoints. -// v0.29.0 CS2: Admin reviews and grants/revokes declared permissions. type ExtPermHandler struct { stores store.Stores } diff --git a/server/handlers/extension_secrets.go b/server/handlers/extension_secrets.go index 12c2b6f..0d98b4e 100644 --- a/server/handlers/extension_secrets.go +++ b/server/handlers/extension_secrets.go @@ -10,7 +10,6 @@ import ( ) // ExtSecretsHandler serves extension secret management endpoints. -// v0.29.0 CS3: Admin sets key-value secrets that Starlark extensions // can read via the secrets.get() module. // // Secrets are stored in GlobalConfig under key "ext_secrets:{packageID}" diff --git a/server/handlers/extensions.go b/server/handlers/extensions.go index 9145bcf..91fcd96 100644 --- a/server/handlers/extensions.go +++ b/server/handlers/extensions.go @@ -16,7 +16,6 @@ import ( ) // ExtensionHandler serves extension management endpoints. -// v0.28.7: Backed by PackageStore (packages table) instead of ExtensionStore. type ExtensionHandler struct { stores store.Stores } @@ -94,7 +93,6 @@ func (h *ExtensionHandler) UpdateUserExtensionSettings(c *gin.Context) { settings := json.RawMessage("{}") if body.Settings != nil { - // v0.2.0: enforce user_overridable — strip locked keys before saving schema := store.ParseSettingsSchema(pkg.Manifest) if len(schema) > 0 { var incoming map[string]any @@ -229,18 +227,15 @@ func (h *ExtensionHandler) AdminInstallExtension(c *gin.Context) { return } - // v0.29.0: Parse manifest permissions and declare them. // If permissions are declared, package moves to pending_review. SyncManifestPermissions(c, h.stores, pkg.ID, manifestMap) - // v0.29.2: Create namespaced DB tables declared in the manifest. if tables, ok := ParseDBTables(manifestMap); ok { if err := CreateExtTables(c.Request.Context(), database.DB, database.IsPostgres(), h.stores, pkg.ID, tables); err != nil { log.Printf("[ext-db] schema create failed for %s: %v", pkg.ID, err) } } - // v0.2.2: Sync triggers from manifest SyncManifestTriggers(c.Request.Context(), h.stores, triggers.GlobalEngine(), pkg.ID, manifestMap) c.JSON(201, gin.H{"data": pkg}) @@ -403,7 +398,6 @@ func (h *ExtensionHandler) AdminUninstallExtension(c *gin.Context) { return } - // v0.29.2: Drop namespaced DB tables before removing the package record. if err := DropExtTables(c.Request.Context(), database.DB, h.stores, id); err != nil { log.Printf("[ext-db] schema drop failed for %s: %v", id, err) } diff --git a/server/handlers/openapi.go b/server/handlers/openapi.go index 50b4cb6..068e290 100644 --- a/server/handlers/openapi.go +++ b/server/handlers/openapi.go @@ -1,6 +1,5 @@ // Package handlers — openapi.go // -// v0.6.2: Dynamic OpenAPI spec generation. Merges the static kernel spec // with extension-declared API routes. Extensions with api_schema get rich // path items; others get auto-generated stubs. // diff --git a/server/handlers/package_registry.go b/server/handlers/package_registry.go index 8a941ec..58480e1 100644 --- a/server/handlers/package_registry.go +++ b/server/handlers/package_registry.go @@ -1,6 +1,6 @@ package handlers -// package_registry.go — v0.30.0 CS4 +// package_registry.go // // Package registry (marketplace discovery). Admin browses available // packages from an external JSON registry and installs them by URL. diff --git a/server/handlers/packages.go b/server/handlers/packages.go index 6850b85..1da13ae 100644 --- a/server/handlers/packages.go +++ b/server/handlers/packages.go @@ -31,8 +31,8 @@ var validPackageID = regexp.MustCompile(`^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$`) type PackageHandler struct { stores store.Stores packagesDir string // e.g. /data/packages — where archives are extracted - sandbox *sandbox.Sandbox // v0.30.0: for schema migration scripts - runner *sandbox.Runner // v0.38.2: for test-tool execution + sandbox *sandbox.Sandbox + runner *sandbox.Runner } func NewPackageHandler(s store.Stores, packagesDir ...string) *PackageHandler { @@ -95,7 +95,6 @@ func (h *PackageHandler) GetPackage(c *gin.Context) { func (h *PackageHandler) EnablePackage(c *gin.Context) { id := c.Param("id") - // v0.3.7: Block enabling dormant packages (unmet requires). pkg, err := h.stores.Packages.Get(c.Request.Context(), id) if err != nil || pkg == nil { c.JSON(http.StatusNotFound, gin.H{"error": "package not found"}) @@ -149,7 +148,6 @@ func (h *PackageHandler) DeletePackage(c *gin.Context) { return } - // v0.38.2: Libraries with active consumers cannot be uninstalled. if pkg.Type == "library" && h.stores.Dependencies != nil { hasConsumers, _ := h.stores.Dependencies.HasConsumers(c.Request.Context(), id) if hasConsumers { @@ -158,12 +156,10 @@ func (h *PackageHandler) DeletePackage(c *gin.Context) { } } - // v0.38.2: Clean up dependency records when uninstalling a consumer. if h.stores.Dependencies != nil { h.stores.Dependencies.DeleteAllForConsumer(c.Request.Context(), id) } - // v0.29.2: Drop namespaced DB tables before removing the package record. if err := DropExtTables(c.Request.Context(), database.DB, h.stores, id); err != nil { log.Printf("[ext-db] schema drop failed for %s: %v", id, err) } @@ -195,7 +191,6 @@ func (h *PackageHandler) InstallPackage(c *gin.Context) { var tmpPath string var cleanupTmp bool - // v0.30.0: Check for pre-downloaded file from registry install if regFile, ok := c.Get("_registry_file"); ok { tmpPath = regFile.(string) // Don't remove — caller manages lifecycle @@ -278,7 +273,6 @@ func (h *PackageHandler) InstallPackage(c *gin.Context) { return } - // v0.38.0: Entry point validation for starlark-tier packages. // Scripts are loaded from disk at runtime — no _starlark_script injection. if manifestTier, _ := manifest["tier"].(string); manifestTier == "starlark" { entryPoint := "script.star" @@ -380,7 +374,6 @@ func (h *PackageHandler) InstallPackage(c *gin.Context) { c.JSON(http.StatusBadRequest, gin.H{"error": "full packages require a route"}) return } - // v0.31.0: full packages need either server-side behavior (tools/pipes/hooks) // or a settings schema. A surface-with-settings is a valid "full" package // (e.g. editor: browser-tier surface + admin-configurable settings). if !hasExtBehavior && !hasSettings { @@ -393,7 +386,6 @@ func (h *PackageHandler) InstallPackage(c *gin.Context) { return } case "library": - // v0.38.2: Libraries must declare exports, cannot have tools/pipes/route. exports, _ := manifest["exports"].([]any) if len(exports) == 0 { c.JSON(http.StatusBadRequest, gin.H{"error": "library packages require an 'exports' array"}) @@ -471,7 +463,6 @@ func (h *PackageHandler) InstallPackage(c *gin.Context) { userID := c.GetString("user_id") - // v0.30.0: use registry source if set by registry install handler pkgSource := "extension" if src, ok := c.Get("_registry_source"); ok { pkgSource = src.(string) @@ -509,22 +500,18 @@ func (h *PackageHandler) InstallPackage(c *gin.Context) { log.Printf("[packages] Failed to update package metadata for %s: %v", pkgID, err) } - // v0.29.2: Create namespaced DB tables declared in the manifest. if tables, ok := ParseDBTables(manifest); ok { if err := CreateExtTables(c.Request.Context(), database.DB, database.IsPostgres(), h.stores, pkgID, tables); err != nil { log.Printf("[ext-db] schema create failed for %s: %v", pkgID, err) } } - // v0.38.5: Declare manifest permissions (same as AdminInstallExtension). // This creates the permission rows and sets status to pending_review // if the package declares permissions. SyncManifestPermissions(c, h.stores, pkgID, manifest) - // v0.2.2: Sync triggers from manifest SyncManifestTriggers(c.Request.Context(), h.stores, triggers.GlobalEngine(), pkgID, manifest) - // v0.30.0: Run schema migrations if declared. newSchemaVersion := ParseSchemaVersion(manifest) if newSchemaVersion > 0 && h.sandbox != nil { oldSchemaVersion := 0 @@ -553,7 +540,6 @@ func (h *PackageHandler) InstallPackage(c *gin.Context) { } } - // v0.30.2: Install workflow definition from package manifest. if pkgType == "workflow" { if err := InstallWorkflowFromManifest(c, h.stores, pkgID, manifest); err != nil { log.Printf("[packages] workflow install failed for %s: %v", pkgID, err) @@ -562,7 +548,6 @@ func (h *PackageHandler) InstallPackage(c *gin.Context) { } } - // v0.38.2: Create dependency records from manifest "dependencies" map. // Libraries must be installed first; consumers declare them. if deps, ok := manifest["dependencies"].(map[string]any); ok && len(deps) > 0 { // Clear stale dependency records from a previous install of the same consumer. @@ -603,7 +588,6 @@ func (h *PackageHandler) InstallPackage(c *gin.Context) { log.Printf("[packages] %s: %d dependencies recorded", pkgID, len(deps)) } - // v0.2.1: Auto-set default_surface when the first extension surface is installed. if (pkgType == "surface" || pkgType == "full") && pkgSource != "core" { if raw, err := h.stores.GlobalConfig.Get(c.Request.Context(), "default_surface"); err != nil || raw == nil { dflt := models.JSONMap{"id": pkgID} @@ -615,7 +599,6 @@ func (h *PackageHandler) InstallPackage(c *gin.Context) { } } - // v0.3.7: Auto-set dormant for packages with unmet requires. // Known capabilities: (none yet — chat and legacy-sdk are future/removed). knownCaps := map[string]bool{} var unmetReqs []string diff --git a/server/handlers/presence.go b/server/handlers/presence.go index a519f5a..bd62fbe 100644 --- a/server/handlers/presence.go +++ b/server/handlers/presence.go @@ -6,7 +6,6 @@ package handlers // GET /api/v1/presence?users=id1,id2 returns current status. // Online = last_seen within 90s. // -// v0.29.0: Raw SQL replaced with PresenceStore + UserStore methods. import ( "net/http" diff --git a/server/handlers/profile_bootstrap.go b/server/handlers/profile_bootstrap.go index 85b2e0d..9e3e3dc 100644 --- a/server/handlers/profile_bootstrap.go +++ b/server/handlers/profile_bootstrap.go @@ -8,7 +8,6 @@ package handlers // (profile, permissions, teams/mine, settings) into one call. // The SDK calls this at startup and on token refresh. // -// v0.37.15 import ( "net/http" diff --git a/server/handlers/settings.go b/server/handlers/settings.go index 9a82ef1..1fdd8c2 100644 --- a/server/handlers/settings.go +++ b/server/handlers/settings.go @@ -2,7 +2,6 @@ package handlers // settings.go — User profile, preferences, and password management. // -// v0.29.0: Raw SQL replaced with UserStore methods. import ( "context" diff --git a/server/handlers/team_package_settings.go b/server/handlers/team_package_settings.go index 18032aa..3d63e4c 100644 --- a/server/handlers/team_package_settings.go +++ b/server/handlers/team_package_settings.go @@ -1,6 +1,6 @@ package handlers -// team_package_settings.go — v0.2.0 +// team_package_settings.go // // Team-admin endpoints for managing team-scoped package settings. // These sit in the settings cascade between global (admin) and user. diff --git a/server/handlers/upgrade_test.go b/server/handlers/upgrade_test.go index 7d1c1ea..1226168 100644 --- a/server/handlers/upgrade_test.go +++ b/server/handlers/upgrade_test.go @@ -14,7 +14,7 @@ import ( ) // ═══════════════════════════════════════════════ -// Upgrade Tests — v0.5.5 +// Upgrade Tests // // Schema edge cases, settings migration, and // package compatibility across kernel upgrades. diff --git a/server/handlers/user_packages.go b/server/handlers/user_packages.go index f48bbc7..94b625d 100644 --- a/server/handlers/user_packages.go +++ b/server/handlers/user_packages.go @@ -1,6 +1,6 @@ package handlers -// user_packages.go — v0.30.0 CS5 +// user_packages.go // // Non-admin package management. Users install personal-scoped packages; // team admins install team-scoped packages. diff --git a/server/handlers/workflow_packages.go b/server/handlers/workflow_packages.go index 0bff0ee..a65643a 100644 --- a/server/handlers/workflow_packages.go +++ b/server/handlers/workflow_packages.go @@ -1,6 +1,6 @@ package handlers -// workflow_packages.go — v0.30.2 CS1 +// workflow_packages.go // // Handles workflow-specific package operations: // - ExportWorkflowPackage: bundles a workflow definition + stages into a .pkg diff --git a/server/handlers/workflows.go b/server/handlers/workflows.go index c90a17c..dc2a598 100644 --- a/server/handlers/workflows.go +++ b/server/handlers/workflows.go @@ -106,7 +106,6 @@ func (h *WorkflowHandler) Create(c *gin.Context) { w.CreatedBy = c.GetString("user_id") - // v0.31.2: team-scoped route injects force_team_id via CreateTeamWorkflow if ftid, ok := c.Get("force_team_id"); ok { tid := ftid.(string) w.TeamID = &tid @@ -417,7 +416,6 @@ func (h *WorkflowHandler) Clone(c *gin.Context) { CreatedBy: c.GetString("user_id"), } - // v0.31.2: team-scoped route injects force_team_id if ftid, ok := c.Get("force_team_id"); ok { tid := ftid.(string) clone.TeamID = &tid diff --git a/server/main.go b/server/main.go index 6598a6f..03158e1 100644 --- a/server/main.go +++ b/server/main.go @@ -36,7 +36,6 @@ import ( sqliteStore "switchboard-core/store/sqlite" ) -// v0.33.0: Embedded OpenAPI spec and Swagger UI for /api/docs. // //go:embed static/openapi.yaml var openapiSpec []byte @@ -106,7 +105,6 @@ func main() { stores = postgres.NewStores(database.DB) } - // v0.33.0: Start Prometheus DB pool collector metrics.StartDBCollector(database.DB, 15*time.Second) // Bootstrap admin from env (K8s secret) — upserts on every restart @@ -158,17 +156,12 @@ func main() { sandbox.New(sandbox.DefaultConfig()), stores, ) - // v0.38.1: connections module — extension connection resolution starlarkRunner.SetConnectionResolver(handlers.NewConnectionResolverAdapter(stores, keyResolver)) - // v0.29.2: db module — extension namespaced table access starlarkRunner.SetDB(database.DB, database.IsPostgres()) - // v0.38.0: disk-based script loading + load() support if cfg.StoragePath != "" { starlarkRunner.SetPackagesDir(cfg.StoragePath + "/packages") } - // v0.5.0: realtime module — extension publish to WebSocket channels starlarkRunner.SetBus(bus) - // v0.38.5: allow extensions to reach private IPs (self-hosted Gitea, etc.) if os.Getenv("EXT_ALLOW_PRIVATE_IPS") == "true" { starlarkRunner.SetAllowPrivateIPs(true) log.Printf(" ⚠️ Extension SSRF protection relaxed: private IPs allowed") @@ -274,7 +267,6 @@ func main() { c.JSON(200, info) }) - // v0.32.0: Kubernetes probe endpoints // Liveness: process is alive and serving (no dependency checks). base.GET("/healthz/live", func(c *gin.Context) { c.JSON(200, gin.H{"status": "ok"}) @@ -296,10 +288,8 @@ func main() { c.JSON(200, gin.H{"status": "ok"}) }) - // v0.33.0: Prometheus metrics endpoint (no auth — Prometheus scrapes directly) base.GET("/metrics", gin.WrapH(promhttp.Handler())) - // v0.33.0: OpenAPI spec + Swagger UI (no auth — documentation) base.GET("/api/docs", func(c *gin.Context) { c.Data(http.StatusOK, "text/html; charset=utf-8", swaggerHTML) }) @@ -308,7 +298,6 @@ func main() { patched := bytes.Replace(openapiSpec, []byte("${VERSION}"), []byte(Version), 1) c.Data(http.StatusOK, "application/yaml", patched) }) - // v0.6.2: Dynamic OpenAPI spec with extension routes merged in base.GET("/api/docs/openapi.json", func(c *gin.Context) { spec, err := handlers.BuildOpenAPISpec(stores, openapiSpec, Version) if err != nil { @@ -501,7 +490,7 @@ func main() { connTypeH := handlers.NewConnectionTypeHandler(stores) protected.GET("/connection-types", connTypeH.ListConnectionTypes) - // Extension Connections (personal scope — v0.38.1) + // Extension Connections (personal scope connH := handlers.NewConnectionHandler(stores, keyResolver) protected.GET("/connections", connH.ListConnections) protected.POST("/connections", connH.CreateConnection) @@ -559,7 +548,7 @@ func main() { teams := handlers.NewTeamHandler(stores, keyResolver) protected.GET("/teams/mine", teams.MyTeams) - // Groups (user: my groups — v0.16.0) + // Groups (user: my groups groupH := handlers.NewGroupHandler(stores) protected.GET("/groups/mine", groupH.MyGroups) @@ -697,7 +686,7 @@ func main() { admin.GET("/audit", adm.ListAuditLog) admin.GET("/audit/actions", adm.ListAuditActions) - // Groups (admin — v0.16.0) + // Groups (admin groupAdm := handlers.NewGroupHandler(stores) admin.GET("/groups", groupAdm.ListGroups) admin.POST("/groups", groupAdm.CreateGroup) @@ -712,7 +701,7 @@ func main() { admin.GET("/permissions", groupAdm.ListPermissions) admin.GET("/users/:id/permissions", groupAdm.GetUserPermissions) - // Resource Grants (admin — v0.16.0) + // Resource Grants (admin admin.GET("/grants/:type/:id", groupAdm.GetResourceGrant) admin.PUT("/grants/:type/:id", groupAdm.SetResourceGrant) @@ -736,7 +725,7 @@ func main() { admin.PUT("/extensions/:id", extAdm.AdminUpdateExtension) admin.DELETE("/extensions/:id", extAdm.AdminUninstallExtension) - // Extension permissions (admin — v0.29.0) + // Extension permissions (admin extPermH := handlers.NewExtPermHandler(stores) admin.GET("/extensions/:id/permissions", extPermH.ListPackagePermissions) admin.GET("/extensions/:id/review", extPermH.ReviewPackage) @@ -744,7 +733,7 @@ func main() { admin.POST("/extensions/:id/permissions/:perm/revoke", extPermH.RevokePermission) admin.POST("/extensions/:id/permissions/grant-all", extPermH.GrantAllPermissions) - // Extension secrets (admin — v0.29.0 CS3) + // Extension secrets (admin extSecH := handlers.NewExtSecretsHandler(stores) admin.GET("/extensions/:id/secrets", extSecH.GetSecrets) admin.PUT("/extensions/:id/secrets", extSecH.SetSecrets) @@ -756,7 +745,7 @@ func main() { packagesDir = cfg.StoragePath + "/packages" } pkgAdm := handlers.NewPackageHandler(stores, packagesDir) - pkgAdm.SetSandbox(sandbox.New(sandbox.DefaultConfig())) // v0.30.0: schema migrations + pkgAdm.SetSandbox(sandbox.New(sandbox.DefaultConfig())) // Package registry — must be registered before /packages/:id (v0.30.0) registryH := handlers.NewRegistryHandler(stores, packagesDir, pkgAdm) @@ -769,14 +758,14 @@ func main() { admin.PUT("/packages/:id/enable", pkgAdm.EnablePackage) admin.PUT("/packages/:id/disable", pkgAdm.DisablePackage) admin.DELETE("/packages/:id", pkgAdm.DeletePackage) - admin.GET("/packages/:id/settings", pkgAdm.GetPackageSettings) // v0.30.0 - admin.PUT("/packages/:id/settings", pkgAdm.UpdatePackageSettings) // v0.30.0 - admin.GET("/packages/:id/dependencies", pkgAdm.ListDependencies) // v0.38.2 - admin.GET("/packages/:id/consumers", pkgAdm.ListConsumers) // v0.38.2 - admin.POST("/packages/:id/test-tool", pkgAdm.TestTool) // v0.38.2 - admin.POST("/packages/:id/update", pkgAdm.UpdatePackage) // v0.5.4 - admin.GET("/packages/:id/export", pkgAdm.ExportPackage) // v0.5.4 - admin.GET("/dependencies", pkgAdm.ListAllDependencies) // v0.38.2 + admin.GET("/packages/:id/settings", pkgAdm.GetPackageSettings) + admin.PUT("/packages/:id/settings", pkgAdm.UpdatePackageSettings) + admin.GET("/packages/:id/dependencies", pkgAdm.ListDependencies) + admin.GET("/packages/:id/consumers", pkgAdm.ListConsumers) + admin.POST("/packages/:id/test-tool", pkgAdm.TestTool) + admin.POST("/packages/:id/update", pkgAdm.UpdatePackage) + admin.GET("/packages/:id/export", pkgAdm.ExportPackage) + admin.GET("/dependencies", pkgAdm.ListAllDependencies) // Workflow package export (v0.30.2) wfPkgH := handlers.NewWorkflowPackageHandler(stores) @@ -825,9 +814,7 @@ func main() { } // ── Page Routes ────────────────────────── - // v0.27.0: Extension surface static assets (JS, CSS, images). // Served without auth — same rationale as extension assets (script tags can't send headers). - // v0.28.7: on-disk path moved to /data/packages/, URL stays /surfaces/:id/ for stability. // In split deployment, nginx serves these from /data/packages/ directly. if cfg.StoragePath != "" { packagesStaticDir := cfg.StoragePath + "/packages" @@ -853,7 +840,6 @@ func main() { // Login page — no auth required base.GET("/login", pageEngine.RenderLogin()) - // v0.25.0: Surface routes generated from manifest registry. // Replaces manual per-surface route blocks. pageEngine.RegisterPageRoutes(base, pages.PageRouteMiddleware{ Authenticated: middleware.AuthOrRedirect(cfg, stores.Users, userCache), @@ -864,7 +850,6 @@ func main() { Session: middleware.AuthOrRedirect(cfg, stores.Users, userCache), // TODO: session middleware for workflow visitors (v0.2.0) }) - // v0.29.1: Extension API routes — Starlark packages serve JSON endpoints. // Mounted at /s/:slug/api/* with JWT auth (returns 401, not redirect). { extAPIH := handlers.NewExtAPIHandler(stores, starlarkRunner) diff --git a/server/middleware/ratelimit.go b/server/middleware/ratelimit.go index 01f3c8c..7c6f6b4 100644 --- a/server/middleware/ratelimit.go +++ b/server/middleware/ratelimit.go @@ -10,7 +10,6 @@ import ( ) // RateLimiter implements per-IP rate limiting backed by a shared store. -// v0.32.0: replaces in-memory token bucket for cross-pod consistency. // // Fail-open: if the store is unavailable (PG down), requests are allowed. // Auth endpoints have their own protections (bcrypt, lockout); blocking diff --git a/server/middleware/team.go b/server/middleware/team.go index 0e54ae6..eee502f 100644 --- a/server/middleware/team.go +++ b/server/middleware/team.go @@ -10,7 +10,6 @@ import ( // RequireTeamAdmin returns middleware that restricts access to team admins. // System admins are always allowed through. -// v0.29.0: accepts TeamStore instead of using database.DB directly. func RequireTeamAdmin(teams store.TeamStore) gin.HandlerFunc { return func(c *gin.Context) { role, _ := c.Get("role") @@ -43,7 +42,6 @@ func RequireTeamAdmin(teams store.TeamStore) gin.HandlerFunc { // RequireTeamMember returns middleware that restricts access to users who // belong to the team identified by :teamId (any role). // System admins are always allowed through. -// v0.29.0: accepts TeamStore instead of using database.DB directly. func RequireTeamMember(teams store.TeamStore) gin.HandlerFunc { return func(c *gin.Context) { role, _ := c.Get("role") diff --git a/server/models/models_extension_perm.go b/server/models/models_extension_perm.go index 8f77789..cd4fe20 100644 --- a/server/models/models_extension_perm.go +++ b/server/models/models_extension_perm.go @@ -31,11 +31,11 @@ const ( ExtPermDBRead = "db.read" ExtPermDBWrite = "db.write" ExtPermAPIHTTP = "api.http" - ExtPermFormValidate = "forms.validate" // v0.29.3: form validation hooks - ExtPermWorkflowAccess = "workflow.access" // v0.30.2: workflow definition + stage data access - ExtPermConnectionsRead = "connections.read" // v0.38.1: extension connection resolution - ExtPermTriggersRegister = "triggers.register" // v0.2.2: event/webhook trigger registration - ExtPermRealtimePublish = "realtime.publish" // v0.5.0: publish events to realtime channels + ExtPermFormValidate = "forms.validate" + ExtPermWorkflowAccess = "workflow.access" + ExtPermConnectionsRead = "connections.read" + ExtPermTriggersRegister = "triggers.register" + ExtPermRealtimePublish = "realtime.publish" ) // ValidExtensionPermissions is the set of recognized permission keys. diff --git a/server/models/workflow.go b/server/models/workflow.go index 12c9fb1..01d43a2 100644 --- a/server/models/workflow.go +++ b/server/models/workflow.go @@ -121,10 +121,9 @@ var ValidAudiences = map[string]bool{ // ── Typed Form Template ───────────────────── // TypedFormTemplate is the structured form_template schema (v0.29.3). -// v0.35.0: added Fieldsets for progressive multi-step forms. type TypedFormTemplate struct { Fields []FormField `json:"fields"` - Fieldsets []FormFieldset `json:"fieldsets,omitempty"` // v0.35.0: multi-step form groups + Fieldsets []FormFieldset `json:"fieldsets,omitempty"` Hooks *FormHooks `json:"hooks,omitempty"` } @@ -153,7 +152,7 @@ type FormField struct { Default interface{} `json:"default,omitempty"` Options []FormOption `json:"options,omitempty"` Validation *FormValidation `json:"validation,omitempty"` - Condition *FieldCondition `json:"condition,omitempty"` // v0.35.0: conditional visibility + Condition *FieldCondition `json:"condition,omitempty"` } // FormOption is a choice for select fields. @@ -200,7 +199,6 @@ func ParseTypedFormTemplate(raw json.RawMessage) *TypedFormTemplate { return nil } - // v0.35.0: If fieldsets present, flatten into fields for backward compat if len(tpl.Fieldsets) > 0 { var allFields []FormField for _, fs := range tpl.Fieldsets { @@ -237,7 +235,6 @@ type FieldError struct { func ValidateFormData(tpl *TypedFormTemplate, data map[string]interface{}) []FieldError { var errs []FieldError for _, f := range tpl.Fields { - // v0.35.0: Skip fields whose condition is not met if f.Condition != nil && !evaluateFieldCondition(f.Condition, data) { continue } diff --git a/server/pages/loaders.go b/server/pages/loaders.go index b0c074c..2672ae5 100644 --- a/server/pages/loaders.go +++ b/server/pages/loaders.go @@ -31,7 +31,7 @@ type AdminPageData struct { // Feature gates (BYOK, personas) moved to sw.auth.policies in v0.37.19. type SettingsPageData struct { Section string `json:"section"` - ConfigSections []ConfigSectionEntry `json:"config_sections,omitempty"` // v0.38.3 + ConfigSections []ConfigSectionEntry `json:"config_sections,omitempty"` } // ── Loader registration ────────────────────── @@ -39,7 +39,7 @@ type SettingsPageData struct { // TeamAdminPageData is what the team-admin surface receives. type TeamAdminPageData struct { Section string `json:"section"` - ConfigSections []ConfigSectionEntry `json:"config_sections,omitempty"` // v0.38.3 + ConfigSections []ConfigSectionEntry `json:"config_sections,omitempty"` } func (e *Engine) registerLoaders() { @@ -91,7 +91,6 @@ func sectionCategory(section string) string { } // ── Settings loader ────────────────────────── -// v0.22.7: Reads feature gates from GlobalConfig to control // which nav links/tabs are visible (BYOK, User Personas). func (e *Engine) teamAdminLoader(c *gin.Context, s store.Stores) (any, error) { diff --git a/server/pages/pages.go b/server/pages/pages.go index 2ddf2a5..52953c4 100644 --- a/server/pages/pages.go +++ b/server/pages/pages.go @@ -38,7 +38,7 @@ type Engine struct { cfg *config.Config stores store.Stores loaders map[string]DataLoaderFunc - surfaces []SurfaceManifest // v0.25.0: registered surface definitions + surfaces []SurfaceManifest devMode bool } @@ -95,25 +95,20 @@ type PageData struct { User *UserContext Data any // surface-specific data from loader - // v0.22.7: Theme + settings injection Theme string // "dark", "light", or "" (= use default) SurfaceSettings any // JSON-serialized to window.__SETTINGS__ - // v0.25.0: Surface manifest — layout preset, components, etc. Manifest *SurfaceManifest `json:"manifest,omitempty"` - // v0.25.0: Enabled surface IDs for conditional nav rendering. EnabledSurfaces []string `json:"-"` - // v0.27.0: Extension surfaces for sidebar nav rendering. ExtensionSurfaces []ExtensionNavItem `json:"-"` - // v0.22.7: Login/splash page fields InstanceName string // branding: instance display name LogoURL string // branding: custom logo URL Tagline string // branding: tagline under instance name RegistrationOpen bool // whether self-registration is enabled - AuthMode string // v0.24.1: "builtin", "mtls", "oidc" + AuthMode string // "builtin", "mtls", "oidc" } // SurfaceEnabled returns true if the given surface ID is in the EnabledSurfaces list. @@ -137,7 +132,6 @@ type ExtensionNavItem struct { // ConfigSectionEntry describes a package-declared config section for // lazy-loading in Settings, Admin, or Team Admin surfaces. -// v0.38.3: manifest-driven discovery — no new tables or endpoints. type ConfigSectionEntry struct { PackageID string `json:"package_id"` // section key & asset path prefix Label string `json:"label"` // nav link text @@ -207,7 +201,7 @@ func New(cfg *config.Config, stores store.Stores) *Engine { e.parseTemplates() e.registerLoaders() e.registerCoreSurfaces() - e.SeedSurfaces() // v0.25.0: Write core manifests to DB (preserves admin toggle state) + e.SeedSurfaces() return e } @@ -322,7 +316,6 @@ func (e *Engine) Render(c *gin.Context, name string, data PageData) { data.Message = e.loadMessage() data.Footer = e.loadFooter() - // v0.22.7: Default theme if not set if data.Theme == "" { data.Theme = "dark" } @@ -477,7 +470,6 @@ func (e *Engine) RegisterPageRoutes(base *gin.RouterGroup, mw PageRouteMiddlewar registerRoutes(group, s, handler) } - // v0.27.0: Extension surface catch-all — DB lookup at request time. // No restart needed after installing new surfaces via admin API. group.GET("/s/:slug", e.RenderExtensionSurface()) } @@ -592,7 +584,6 @@ func stripPrefix(route, prefix string) string { // RenderLogin serves the standalone login page. func (e *Engine) RenderLogin() gin.HandlerFunc { return func(c *gin.Context) { - // v0.22.7: Populate splash/login fields from global config instanceName, logoURL, tagline := e.loadBranding() regOpen := e.isRegistrationOpen() @@ -619,8 +610,8 @@ type WorkflowPageData struct { FormTemplateJSON string // typed form template JSON (empty if custom) TotalStages int CurrentStage int - SurfacePkgID string // v0.30.2: custom package surface override (empty = use StageMode) - BrandingJSON string // v0.35.0: workflow branding JSON (accent_color, logo_url, tagline) + SurfacePkgID string + BrandingJSON string } // WorkflowLandingPageData is passed to workflow-landing.html. diff --git a/server/pages/pages_surfaces.go b/server/pages/pages_surfaces.go index 2a027dd..1fafa92 100644 --- a/server/pages/pages_surfaces.go +++ b/server/pages/pages_surfaces.go @@ -35,7 +35,6 @@ func (e *Engine) SeedSurfaces() { } log.Printf("[pages] Seeded %d core surfaces into registry", len(e.surfaces)) - // v0.31.0: Clean up old "editor" core surface row. // Editor is now an installable package — the old seed row would show a // broken nav link until the package .pkg is uploaded via admin UI. if sr, err := e.stores.Packages.Get(ctx, "editor"); err == nil && sr != nil && sr.Source == "extension" { diff --git a/server/sandbox/connections_module.go b/server/sandbox/connections_module.go index 812829a..ccf512c 100644 --- a/server/sandbox/connections_module.go +++ b/server/sandbox/connections_module.go @@ -1,6 +1,5 @@ // Package sandbox — connections_module.go // -// v0.38.1: Connections module for Starlark extensions. // Requires permission: connections.read // // Starlark API: diff --git a/server/sandbox/db_module.go b/server/sandbox/db_module.go index 374a4fb..e8a3307 100644 --- a/server/sandbox/db_module.go +++ b/server/sandbox/db_module.go @@ -1,6 +1,5 @@ // Package sandbox — db_module.go // -// v0.29.2 CS1: Structured db module for Starlark extensions. // // Permissions: // db.read → db.query(), db.view(), db.list_tables() diff --git a/server/sandbox/http_module.go b/server/sandbox/http_module.go index 72aaa9b..1b2a7f8 100644 --- a/server/sandbox/http_module.go +++ b/server/sandbox/http_module.go @@ -1,6 +1,5 @@ // Package sandbox — http_module.go // -// v0.29.1 CS0: HTTP outbound module for Starlark extensions. // Requires permission: api.http // // Starlark API: diff --git a/server/sandbox/lib_module.go b/server/sandbox/lib_module.go index db87d20..787175e 100644 --- a/server/sandbox/lib_module.go +++ b/server/sandbox/lib_module.go @@ -1,6 +1,5 @@ // Package sandbox — lib_module.go // -// v0.38.2: Library loading module for Starlark extensions. // No permission required — any starlark package can use lib.require(). // // Starlark API: diff --git a/server/sandbox/modules.go b/server/sandbox/modules.go index cd281b8..644c4a7 100644 --- a/server/sandbox/modules.go +++ b/server/sandbox/modules.go @@ -1,6 +1,5 @@ // Package sandbox — modules.go // -// v0.29.0 CS3: Module factories for Starlark sandbox. // Each factory returns a starlarkstruct.Module that the runner // injects into the script namespace based on granted permissions. package sandbox diff --git a/server/sandbox/realtime_module.go b/server/sandbox/realtime_module.go index 065b52f..6e8c5a8 100644 --- a/server/sandbox/realtime_module.go +++ b/server/sandbox/realtime_module.go @@ -1,6 +1,5 @@ // Package sandbox — realtime_module.go // -// v0.5.0: Starlark realtime.publish() module. // // Allows extensions to publish events to WebSocket channels. // Events are scoped to rooms — only clients subscribed to the diff --git a/server/sandbox/runner.go b/server/sandbox/runner.go index 8c26017..bddeab0 100644 --- a/server/sandbox/runner.go +++ b/server/sandbox/runner.go @@ -1,19 +1,14 @@ // Package sandbox — runner.go // -// v0.29.0 CS3: Runner loads a package's Starlark script, assembles // the module set based on granted permissions, and executes it. // -// v0.29.1 CS0: Wires api.http permission to BuildHTTPModule with // network_access config from package manifest. // -// v0.29.1 CS2: Adds RunContext for per-invocation state (user_id), // vault for provider key decryption, and provider.complete module. // -// v0.29.2 CS1: Adds db *sql.DB for the db module. SetDB() wires it // at startup. db.read grants query/view/list_tables; db.write adds // insert/update/delete. If both are granted, db.write wins (superset). // -// v0.38.2: Adds lib.load() for library packages. Libraries run with // their own permission context. Per-invocation lib cache + cycle detection. // // The runner is the bridge between the package/permission system @@ -57,13 +52,13 @@ type RunContext struct { type Runner struct { sandbox *Sandbox stores store.Stores - packagesDir string // v0.38.0: disk path for load() support + packagesDir string notifier NotificationSender // nil = notifications module unavailable connResolver ConnectionResolver // nil = connections module unavailable (v0.38.1) db *sql.DB // nil = db module unavailable dbPostgres bool // true = use $N placeholders; false = use ? - allowPrivateIPs bool // v0.38.5: disable SSRF private IP check - bus *events.Bus // v0.5.0: event bus for realtime module + allowPrivateIPs bool + bus *events.Bus } // NewRunner creates a runner with the given sandbox and dependencies. @@ -94,7 +89,6 @@ func (r *Runner) SetDB(db *sql.DB, isPostgres bool) { // SetPackagesDir sets the disk path where package archives are extracted. // Required for load() support — scripts are read from disk at runtime. -// v0.38.0. func (r *Runner) SetPackagesDir(dir string) { r.packagesDir = dir } @@ -114,7 +108,6 @@ func (r *Runner) SetAllowPrivateIPs(allow bool) { // ExecPackage loads a package's script from disk (primary) or manifest // (legacy) and executes it with modules gated by granted permissions. // -// v0.38.0: Disk-based loading + package-scoped load() support. // // The RunContext carries per-invocation state (user_id for provider // resolution). Pass nil if no per-invocation context is needed. @@ -136,7 +129,6 @@ func (r *Runner) ExecPackage(ctx context.Context, pkg *store.PackageRegistration return nil, err } - // v0.38.2: per-invocation lib context for lib.load() caching + cycle detection lc := newLibContext() // Build modules based on granted permissions @@ -352,7 +344,6 @@ func (r *Runner) buildModulesWithLibCtx(ctx context.Context, packageID string, m }) } - // v0.30.0: settings module — always injected, no permission required. // A package reads its own admin + team + user settings (v0.2.0 cascade). userID := "" teamID := "" @@ -362,7 +353,6 @@ func (r *Runner) buildModulesWithLibCtx(ctx context.Context, packageID string, m } modules["settings"] = BuildSettingsModule(ctx, r.stores, packageID, userID, teamID) - // v0.38.2: lib module — always injected, no permission required. // Allows any starlark package to load declared library dependencies. if lc != nil { modules["lib"] = BuildLibModule(ctx, r, packageID, rc, lc) diff --git a/server/sandbox/sandbox.go b/server/sandbox/sandbox.go index aee01ac..a03e5e7 100644 --- a/server/sandbox/sandbox.go +++ b/server/sandbox/sandbox.go @@ -1,6 +1,5 @@ // Package sandbox — sandboxed Starlark interpreter. // -// v0.29.0 CS1: Provides execution with timeout, step limits, // captured output, and injectable predeclared modules. // // The sandbox is intentionally restrictive: diff --git a/server/sandbox/settings_module.go b/server/sandbox/settings_module.go index fe3c970..e3eb981 100644 --- a/server/sandbox/settings_module.go +++ b/server/sandbox/settings_module.go @@ -1,6 +1,6 @@ package sandbox -// settings_module.go — v0.2.0 +// settings_module.go // // The settings module lets extensions read their resolved settings via // the three-tier cascade: global → team → user, respecting the diff --git a/server/sandbox/unicode_scan.go b/server/sandbox/unicode_scan.go index 65bb330..a9cd950 100644 --- a/server/sandbox/unicode_scan.go +++ b/server/sandbox/unicode_scan.go @@ -1,6 +1,5 @@ // Package sandbox — unicode_scan.go // -// v0.5.1: Invisible Unicode scanning gate. // // Defends against GlassWorm (variation selector payloads), Trojan Source // (bidi override attacks / CVE-2021-42574), and other invisible Unicode diff --git a/server/sandbox/workflow_module.go b/server/sandbox/workflow_module.go index c75a465..9fa6015 100644 --- a/server/sandbox/workflow_module.go +++ b/server/sandbox/workflow_module.go @@ -1,6 +1,6 @@ package sandbox -// workflow_module.go — v0.30.2 CS1, v0.3.2 instance API +// workflow_module.go // // The workflow module lets extensions read workflow definitions, // manage instances, and programmatically advance workflow stages. @@ -27,7 +27,6 @@ import ( // BuildWorkflowModule creates the "workflow" Starlark module for a package. // Requires the workflow.access permission. // -// v0.3.2: added get_instance and list_instances for read-only instance access. // Mutating operations (start/advance/cancel) are available via HTTP API; // Starlark builtins for them will be added when the engine interface is // extracted to a shared package to avoid circular imports. diff --git a/server/store/interfaces.go b/server/store/interfaces.go index c19e787..8ca55a4 100644 --- a/server/store/interfaces.go +++ b/server/store/interfaces.go @@ -42,19 +42,19 @@ type Stores struct { ResourceGrants ResourceGrantStore Notifications NotificationStore NotifPrefs NotificationPreferenceStore - Presence PresenceStore // v0.29.0: User online/offline status - Health HealthStore // v0.29.0: Provider health window management - Connections ConnectionStore // v0.38.1: Extension connection credentials - Dependencies DependencyStore // v0.38.2: Library package dependency graph - Packages PackageStore // v0.28.7: Unified package registry (surfaces + extensions) - Workflows WorkflowStore // v0.26.1: Workflow definitions + stages - ExtPermissions ExtensionPermissionStore // v0.29.0: Extension declared/granted capabilities - ExtData ExtDataStore // v0.29.2: Extension namespaced table catalog - Tickets TicketStore // v0.32.0: WS auth tickets (PG-backed for cross-pod) - RateLimits RateLimitStore // v0.32.0: Distributed rate limiting - Triggers TriggerStore // v0.2.2: Extension event/webhook triggers - ScheduledTasks ScheduledTaskStore // v0.2.2: User-created cron tasks - Cluster ClusterStore // v0.6.0: PG-backed cluster node registry (nil on SQLite) + Presence PresenceStore + Health HealthStore + Connections ConnectionStore + Dependencies DependencyStore + Packages PackageStore + Workflows WorkflowStore + ExtPermissions ExtensionPermissionStore + ExtData ExtDataStore + Tickets TicketStore + RateLimits RateLimitStore + Triggers TriggerStore + ScheduledTasks ScheduledTaskStore + Cluster ClusterStore } // TeamAvailableModel is returned by CatalogStore.ListTeamAvailable. diff --git a/server/store/postgres/ratelimit.go b/server/store/postgres/ratelimit.go index 192a984..47298ec 100644 --- a/server/store/postgres/ratelimit.go +++ b/server/store/postgres/ratelimit.go @@ -7,7 +7,6 @@ import ( ) // RateLimitStore manages distributed rate limit counters in Postgres. -// v0.32.0: fixed-window counter — upsert per-second bucket, check burst. type RateLimitStore struct{} func NewRateLimitStore() *RateLimitStore { return &RateLimitStore{} } diff --git a/server/store/postgres/tickets.go b/server/store/postgres/tickets.go index 58c9a54..f06d70c 100644 --- a/server/store/postgres/tickets.go +++ b/server/store/postgres/tickets.go @@ -8,7 +8,6 @@ import ( ) // TicketStore manages WS auth tickets in Postgres. -// v0.32.0: replaces in-memory sync.Map for cross-pod validation. type TicketStore struct{} func NewTicketStore() *TicketStore { return &TicketStore{} } diff --git a/server/store/ratelimit_iface.go b/server/store/ratelimit_iface.go index 00da431..cb82f7e 100644 --- a/server/store/ratelimit_iface.go +++ b/server/store/ratelimit_iface.go @@ -6,7 +6,6 @@ import ( ) // RateLimitStore manages distributed rate limit counters. -// v0.32.0: replaces in-memory token bucket for cross-pod rate limiting. type RateLimitStore interface { // Allow checks if a request is within the rate limit. // key is "{scope}:{identifier}" e.g. "auth:192.168.1.1". diff --git a/server/store/settings_cascade.go b/server/store/settings_cascade.go index 077b46f..cf23945 100644 --- a/server/store/settings_cascade.go +++ b/server/store/settings_cascade.go @@ -1,6 +1,6 @@ package store -// settings_cascade.go — v0.2.0 +// settings_cascade.go // // Pure functions for three-tier settings resolution: // global (admin) → team → user diff --git a/server/store/sqlite/ratelimit.go b/server/store/sqlite/ratelimit.go index 503a6d8..c2b1f40 100644 --- a/server/store/sqlite/ratelimit.go +++ b/server/store/sqlite/ratelimit.go @@ -7,7 +7,6 @@ import ( ) // RateLimitStore manages rate limit counters in SQLite. -// v0.32.0: functional parity for single-process test coverage. type RateLimitStore struct{} func NewRateLimitStore() *RateLimitStore { return &RateLimitStore{} } diff --git a/server/store/sqlite/tickets.go b/server/store/sqlite/tickets.go index fbc1466..d950f7c 100644 --- a/server/store/sqlite/tickets.go +++ b/server/store/sqlite/tickets.go @@ -8,7 +8,6 @@ import ( ) // TicketStore manages WS auth tickets in SQLite. -// v0.32.0: functional parity for single-process test coverage. type TicketStore struct{} func NewTicketStore() *TicketStore { return &TicketStore{} } diff --git a/server/store/ticket_iface.go b/server/store/ticket_iface.go index 9ab4a45..a652182 100644 --- a/server/store/ticket_iface.go +++ b/server/store/ticket_iface.go @@ -3,7 +3,6 @@ package store import "context" // TicketStore manages short-lived, single-use WebSocket auth tickets. -// v0.32.0: replaces in-memory sync.Map for cross-pod ticket validation. type TicketStore interface { // Issue creates a single-use ticket for the given user. // Returns the opaque ticket ID (128-bit hex). diff --git a/server/triggers/engine.go b/server/triggers/engine.go index 95367e6..665f2c6 100644 --- a/server/triggers/engine.go +++ b/server/triggers/engine.go @@ -1,6 +1,5 @@ // Package triggers — engine.go // -// v0.2.2: Core trigger engine. Manages extension-declared triggers // (event bus subscriptions + webhook receivers) and user-created // scheduled tasks (cron). All three converge to sandbox.Runner.CallEntryPoint. package triggers diff --git a/server/webhook/webhook.go b/server/webhook/webhook.go index 5cf7312..b7c3226 100644 --- a/server/webhook/webhook.go +++ b/server/webhook/webhook.go @@ -1,8 +1,6 @@ // Package webhook delivers HTTP POST notifications on task/workflow completion. // -// v0.27.3: Retry (3 attempts, exponential backoff), HMAC-SHA256 signature, // 10s timeout per attempt. -// v0.28.0: Added RunID, TokensUsed fields (D1 audit fix). package webhook import ( diff --git a/src/js/__tests__/auth-resilience.test.js b/src/js/__tests__/auth-resilience.test.js index 3d74feb..445d82c 100644 --- a/src/js/__tests__/auth-resilience.test.js +++ b/src/js/__tests__/auth-resilience.test.js @@ -243,7 +243,6 @@ describe('init() profile gate', () => { }); // ── Boot-time 401 redirect suppression ────── -// v0.37.14: Stale cookie blank-login-page fix. // When the login page boots the SDK with stale localStorage tokens, // the REST client's 401 handler must NOT redirect to /login (we're // already there). boot() handles 401 gracefully on its own. diff --git a/src/js/__tests__/extensions-builtin.test.js b/src/js/__tests__/extensions-builtin.test.js index 2985f36..ee6684b 100644 --- a/src/js/__tests__/extensions-builtin.test.js +++ b/src/js/__tests__/extensions-builtin.test.js @@ -5,7 +5,6 @@ const path = require('path'); const { createBrowserContext, loadSource, SRC } = require('./helpers'); const vm = require('vm'); -// v0.37.10: extensions.js deleted — extension system moves to Preact in v0.37.12. // Skip all tests if the source file doesn't exist. const EXTENSIONS_EXISTS = fs.existsSync(path.join(SRC, 'extensions.js')); const maybeDescribe = EXTENSIONS_EXISTS ? describe : describe.skip; diff --git a/src/js/__tests__/extensions.test.js b/src/js/__tests__/extensions.test.js index 9fdbc36..37d6e85 100644 --- a/src/js/__tests__/extensions.test.js +++ b/src/js/__tests__/extensions.test.js @@ -5,7 +5,6 @@ const path = require('path'); const { createBrowserContext, loadSource, SRC } = require('./helpers'); const vm = require('vm'); -// v0.37.10: extensions.js deleted — extension system moves to Preact in v0.37.12. // Skip all tests if the source file doesn't exist. const EXTENSIONS_EXISTS = fs.existsSync(path.join(SRC, 'extensions.js')); const maybeDescribe = EXTENSIONS_EXISTS ? describe : describe.skip; diff --git a/src/js/__tests__/helpers.js b/src/js/__tests__/helpers.js index b6c4ef8..775ea94 100644 --- a/src/js/__tests__/helpers.js +++ b/src/js/__tests__/helpers.js @@ -5,7 +5,6 @@ // simulated browser environment so tests run // against the ACTUAL frontend code. // -// v0.37.10: Removed loadAppModules (api.js + app.js deleted). // ========================================== const fs = require('fs'); diff --git a/src/js/__tests__/policy-gating.test.js b/src/js/__tests__/policy-gating.test.js index 6f56972..feceb07 100644 --- a/src/js/__tests__/policy-gating.test.js +++ b/src/js/__tests__/policy-gating.test.js @@ -7,13 +7,9 @@ // policy exists but the frontend doesn't // check it. // -// v0.22.5: Updated for server-rendered Go templates. -// v0.37.5: Settings surface moved to Preact — legacy SPA tests // replaced with component source audits. -// v0.37.10: Legacy SPA source audit removed (ui-core.js, app.js, // pages.js, settings-handlers.js, ui-admin.js all deleted). // Policy gating now verified via Preact surfaces + admin templates. -// v0.37.12: Admin Go templates deleted (Preact since v0.37.6). Template // element ID assertions removed — Preact component source audits // at the bottom of this file cover the same policy keys. // @@ -130,7 +126,6 @@ describe('Team member dropdown population', () => { }); // ── Kernel surface template ────────────────── -// v0.1.0: Chat surface removed. Verify admin mount exists and // old SPA scaffold is gone. describe('Kernel surface templates (v0.1.0)', () => { @@ -153,7 +148,6 @@ describe('Kernel surface templates (v0.1.0)', () => { }); // ── Admin Preact surface ───────────────────── -// v0.37.6: Admin surface handles settings save via Preact. // Verify the admin surface has policy key handling. describe('Admin Preact surface handles settings', () => { diff --git a/src/js/sw/components/debug/badge.js b/src/js/sw/components/debug/badge.js index d6ca88e..83bc2a2 100644 --- a/src/js/sw/components/debug/badge.js +++ b/src/js/sw/components/debug/badge.js @@ -4,7 +4,6 @@ // Bug badge that shows error count. Subscribes to engine // for reactive updates. // -// v0.37.18: Preact rebuild from debug.js _updateBadge(). const html = window.html; const { useEffect } = window.hooks; diff --git a/src/js/sw/components/debug/console-tab.js b/src/js/sw/components/debug/console-tab.js index 1b5bd8d..2835e71 100644 --- a/src/js/sw/components/debug/console-tab.js +++ b/src/js/sw/components/debug/console-tab.js @@ -4,7 +4,6 @@ // Filterable console log display with type coloring, // elapsed timestamps, and auto-scroll. // -// v0.37.18: Preact rebuild from debug.js _renderConsoleTab(). const html = window.html; const { useState, useMemo, useRef, useEffect } = window.hooks; diff --git a/src/js/sw/components/debug/engine.js b/src/js/sw/components/debug/engine.js index dd02bf3..d0b8f8f 100644 --- a/src/js/sw/components/debug/engine.js +++ b/src/js/sw/components/debug/engine.js @@ -5,7 +5,6 @@ // Singleton — init() must run before SDK boot to capture early errors. // UI-agnostic: Preact components subscribe via .subscribe(). // -// v0.37.18: Extracted from debug.js (v0.37.14). // // Exports: debugEngine (singleton) diff --git a/src/js/sw/components/debug/index.js b/src/js/sw/components/debug/index.js index 4b66509..77dbdba 100644 --- a/src/js/sw/components/debug/index.js +++ b/src/js/sw/components/debug/index.js @@ -5,7 +5,6 @@ // Global overlay — not a routed surface. // Mounts via mountDebugModal(el, engine). // -// v0.37.18: Preact rebuild of debug modal (CR P2-5). import { debugEngine } from './engine.js'; import { ConsoleTab } from './console-tab.js'; diff --git a/src/js/sw/components/debug/network-tab.js b/src/js/sw/components/debug/network-tab.js index 1ab0ca5..0c63696 100644 --- a/src/js/sw/components/debug/network-tab.js +++ b/src/js/sw/components/debug/network-tab.js @@ -4,7 +4,6 @@ // Fetch log with expandable request/response details. // Newest entries first. // -// v0.37.18: Preact rebuild from debug.js _renderNetworkTab(). const html = window.html; const { useState } = window.hooks; diff --git a/src/js/sw/components/debug/repl-tab.js b/src/js/sw/components/debug/repl-tab.js index 102ad67..cbe6ef5 100644 --- a/src/js/sw/components/debug/repl-tab.js +++ b/src/js/sw/components/debug/repl-tab.js @@ -5,7 +5,6 @@ // command history, and collapsible JSON output. // Admin-gated OR ?debug=1 URL param. // -// v0.37.18: Preact rebuild from repl.js (v0.37.14). const html = window.html; const { useState, useRef, useEffect, useCallback } = window.hooks; diff --git a/src/js/sw/components/debug/state-tab.js b/src/js/sw/components/debug/state-tab.js index 956ae12..9dfed04 100644 --- a/src/js/sw/components/debug/state-tab.js +++ b/src/js/sw/components/debug/state-tab.js @@ -3,7 +3,6 @@ // ========================================== // Displays current application state snapshot as formatted JSON. // -// v0.37.18: Preact rebuild from debug.js _renderStateTab(). const html = window.html; const { useMemo } = window.hooks; diff --git a/src/js/sw/sdk/api-domains.js b/src/js/sw/sdk/api-domains.js index 3fd0e25..5cf9b38 100644 --- a/src/js/sw/sdk/api-domains.js +++ b/src/js/sw/sdk/api-domains.js @@ -239,7 +239,6 @@ export function createDomains(restClient) { del: (id) => rc.del(`/api/v1/admin/extensions/${id}`), }, - // v0.38.1: Global connections connections: crud(rc, '/api/v1/admin/connections'), packages: { @@ -251,20 +250,18 @@ export function createDomains(restClient) { del: (id) => rc.del(`/api/v1/admin/packages/${id}`), settings: (id) => rc.get(`/api/v1/admin/packages/${id}/settings`), updateSettings: (id, data) => rc.put(`/api/v1/admin/packages/${id}/settings`, data), - dependencies: (id) => rc.get(`/api/v1/admin/packages/${id}/dependencies`), // v0.38.2 - consumers: (id) => rc.get(`/api/v1/admin/packages/${id}/consumers`), // v0.38.2 - update: (id, file) => rc.upload(`/api/v1/admin/packages/${id}/update`, file), // v0.5.4 - exportPkg: (id) => `/api/v1/admin/packages/${id}/export`, // v0.5.4 (URL for window.open) + dependencies: (id) => rc.get(`/api/v1/admin/packages/${id}/dependencies`), + consumers: (id) => rc.get(`/api/v1/admin/packages/${id}/consumers`), + update: (id, file) => rc.upload(`/api/v1/admin/packages/${id}/update`, file), + exportPkg: (id) => `/api/v1/admin/packages/${id}/export`, registry: () => rc.get('/api/v1/admin/packages/registry'), registryInstall: (url) => rc.post('/api/v1/admin/packages/registry/install', { download_url: url }), - // v0.5.0: Extension permissions permissions: (id) => rc.get(`/api/v1/admin/extensions/${id}/permissions`), grantPerm: (id, perm) => rc.post(`/api/v1/admin/extensions/${id}/permissions/${perm}/grant`, {}), revokePerm: (id, perm) => rc.post(`/api/v1/admin/extensions/${id}/permissions/${perm}/revoke`, {}), grantAllPerms: (id) => rc.post(`/api/v1/admin/extensions/${id}/permissions/grant-all`, {}), }, - // v0.38.2: Full dependency graph dependencies: { list: () => rc.get('/api/v1/admin/dependencies'), }, @@ -278,7 +275,6 @@ export function createDomains(restClient) { del: (id) => rc.del(`/api/v1/admin/surfaces/${id}`), }, - // v0.6.1: Backup/Restore backup: { create: (opts) => rc.post('/api/v1/admin/backup' + _qs(opts)), list: () => rc.get('/api/v1/admin/backups'), diff --git a/src/js/sw/surfaces/admin/index.js b/src/js/sw/surfaces/admin/index.js index 9653995..94cc364 100644 --- a/src/js/sw/surfaces/admin/index.js +++ b/src/js/sw/surfaces/admin/index.js @@ -4,7 +4,7 @@ * Reads globals: * __SECTION__ — active section name (string) * __BASE__ — base path - * __CONFIG_SECTIONS__ — v0.38.3: extension config sections (array|null) + * __CONFIG_SECTIONS__ * * Layout: topbar (back + category tabs) + body (sidebar nav + content area). * All 24+ sections are native Preact components loaded lazily. @@ -72,7 +72,6 @@ const sectionModules = { audit: () => import(`./audit.js${_v}`), }; -// v0.38.3: Register dynamic section loaders for extension config sections for (const cs of _configSections) { const pkgId = cs.package_id; const component = cs.component || 'js/config.js'; diff --git a/src/js/sw/surfaces/admin/packages.js b/src/js/sw/surfaces/admin/packages.js index 7a7b906..12ace1f 100644 --- a/src/js/sw/surfaces/admin/packages.js +++ b/src/js/sw/surfaces/admin/packages.js @@ -46,7 +46,7 @@ export default function PackagesSection() { const [registryPkgs, setRegistryPkgs] = useState([]); const [registryLoading, setRegistryLoading] = useState(false); const [installing, setInstalling] = useState(false); - const [permsId, setPermsId] = useState(null); // v0.5.0: permissions drawer + const [permsId, setPermsId] = useState(null); const [perms, setPerms] = useState([]); const BASE = window.__BASE__ || ''; diff --git a/src/js/sw/surfaces/settings/index.js b/src/js/sw/surfaces/settings/index.js index 759c548..2d41479 100644 --- a/src/js/sw/surfaces/settings/index.js +++ b/src/js/sw/surfaces/settings/index.js @@ -4,7 +4,7 @@ * Reads globals: * __SECTION__ — active section name (string) * __BASE__ — base path - * __CONFIG_SECTIONS__ — v0.38.3: extension config sections (array|null) + * __CONFIG_SECTIONS__ * * Layout: topbar + left nav + content area (same CSS classes as before). * All sections are native Preact components loaded lazily. diff --git a/src/js/sw/surfaces/team-admin/index.js b/src/js/sw/surfaces/team-admin/index.js index 04e4513..dab050e 100644 --- a/src/js/sw/surfaces/team-admin/index.js +++ b/src/js/sw/surfaces/team-admin/index.js @@ -4,7 +4,7 @@ * Reads globals: * __SECTION__ — active section name (string) * __BASE__ — base path - * __CONFIG_SECTIONS__ — v0.38.3: extension config sections (array|null) + * __CONFIG_SECTIONS__ * * Layout: topbar (back + team name) + sidebar nav + content area. * All 10+ sections are native Preact components loaded lazily. diff --git a/src/js/sw/surfaces/team-admin/workflows.js b/src/js/sw/surfaces/team-admin/workflows.js index c18c199..71a88d9 100644 --- a/src/js/sw/surfaces/team-admin/workflows.js +++ b/src/js/sw/surfaces/team-admin/workflows.js @@ -1,5 +1,5 @@ /** - * Team Admin > Workflows — v0.37.15 rewrite + * Team Admin > Workflows * * Tab layout: Workflows | Assignments | Monitor * - Workflows: CRUD + inline stage editor (E2) @@ -365,7 +365,6 @@ function StageForm({ stage, teams, onSave, onCancel }) { stage?.branch_rules ? (typeof stage.branch_rules === 'string' ? stage.branch_rules : JSON.stringify(stage.branch_rules, null, 2)) : '' ); - // v0.3.4: stage_config fields const sc = stage?.stage_config ? (typeof stage.stage_config === 'string' ? JSON.parse(stage.stage_config || '{}') : stage.stage_config) : {}; const [requiredRole, setRequiredRole] = useState(sc.required_role || ''); const [valApprovals, setValApprovals] = useState(sc.validation?.required_approvals || '');