Agent PaaS is scoped by workspaces. A workspace is an isolated configuration and deployment environment: it has its own persistence backend (where CR YAML files are stored) and its own deployment target (the Kubernetes cluster or namespace where agents run). All catalog reads/writes and all live resource queries are routed to the active workspace.
A workspace has two independent dimensions:
Determines where CR YAML files are stored and how mutations are committed.
| Type | Fields | Description |
|---|---|---|
local |
directory, authorName, authorEmail |
Local filesystem repo via isomorphic-git |
git |
repoUrl, branch |
Remote Git repository (GitHub) |
Both types accept optional directory overrides in WorkspacePersistence (for example modelsDirectory, toolsDirectory, kbsDirectory, and agentsDirectory). In the current implementation, catalog constructors still use their built-in default directories.
The local type writes commits directly to the filesystem; mutations are auto-committed and the PR lifecycle is skipped. The git type writes via pull request; the PR may be auto-merged based on policy.
Determines where live runtime status is read from.
| Type | Fields | Description |
|---|---|---|
k8s |
namespace, apiUrl?, token?, skipTlsVerify? |
Kubernetes API server (in-cluster or remote) |
local |
— | No-op; no live status available |
At startup, Server.init() reads the workspace list and constructs one Catalog and one Resources instance, each internally keyed by workspace ID:
Server.init()
→ Catalog(workspaces) — one GitClient + WorkspaceCatalog per workspace
→ Resources(workspaces) — one K8sClient + WorkspaceResources per workspace (k8s only)
Both are fully initialized before the first request is served. Workspace configuration is managed by WorkspaceManager (accessed via server.ws); current implementation returns a single local workspace (default).
The active workspace is stored in the workspaceId cookie (path: '/'). On each request, hooks.server.ts reads this cookie into event.locals.workspaceId.
+layout.server.ts calls server.ws.list() on every page navigation and returns the full list to the frontend. It validates the current workspaceId cookie against both the workspace list and the user's permitted workspaces (user.workspaces). If invalid or absent, it resets the cookie to the first workspace in the list.
The workspace selector displays all workspaces the current user has access to and indicates the active one. Selecting a workspace writes the workspaceId cookie and reloads the current page.
Browser request
→ hooks.server.ts
reads session cookie → locals.user
reads workspaceId cookie → locals.workspaceId
→ route handler / load function
server.catalog.getWorkspaceCatalog(locals.workspace.id) → catalog ops
server.resources.getWorkspaceResources(locals.workspace.id) → resource queries
If the workspace is absent or does not match any configured workspace, getWorkspaceCatalog / getWorkspaceResources throw NotFoundError.