Feat v0.6.3 dead code sweep #38

Merged
xcaliber merged 10 commits from feat/v0.6.3-dead-code-sweep into main 2026-03-31 12:37:48 +00:00
72 changed files with 69 additions and 199 deletions
Showing only changes of commit 2f31a69756 - Show all commits

View File

@@ -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") {

View File

@@ -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.

View File

@@ -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

View File

@@ -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"`

View File

@@ -1,6 +1,5 @@
package handlers
// v0.38.1: Extension connection handlers — admin/global scope.
// Methods on AdminHandler, mirrors admin provider config pattern.
import (

View File

@@ -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 {

View File

@@ -1,6 +1,5 @@
package handlers
// v0.38.1: ConnectionResolver bridges the sandbox connections module
// to the store + vault layers. Implements sandbox.ConnectionResolver.
import (

View File

@@ -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.

View File

@@ -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 {

View File

@@ -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.
//

View File

@@ -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

View File

@@ -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
}

View File

@@ -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}"

View File

@@ -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)
}

View File

@@ -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.
//

View File

@@ -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.

View File

@@ -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

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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.

View File

@@ -14,7 +14,7 @@ import (
)
// ═══════════════════════════════════════════════
// Upgrade Tests — v0.5.5
// Upgrade Tests
//
// Schema edge cases, settings migration, and
// package compatibility across kernel upgrades.

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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")

View File

@@ -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.

View File

@@ -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
}

View File

@@ -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) {

View File

@@ -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.

View File

@@ -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" {

View File

@@ -1,6 +1,5 @@
// Package sandbox — connections_module.go
//
// v0.38.1: Connections module for Starlark extensions.
// Requires permission: connections.read
//
// Starlark API:

View File

@@ -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()

View File

@@ -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:

View File

@@ -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:

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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:

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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.

View File

@@ -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{} }

View File

@@ -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{} }

View File

@@ -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".

View File

@@ -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

View File

@@ -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{} }

View File

@@ -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{} }

View File

@@ -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).

View File

@@ -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

View File

@@ -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 (

View File

@@ -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.

View File

@@ -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;

View File

@@ -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;

View File

@@ -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');

View File

@@ -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', () => {

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)

View File

@@ -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';

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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'),

View File

@@ -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';

View File

@@ -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__ || '';

View File

@@ -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.

View File

@@ -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.

View File

@@ -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 || '');