@standardagents/builder 0.41.16 → 0.41.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1190,6 +1190,8 @@ interface AuthUser {
1190
1190
  * no explicit set — see {@link hasPermission} for the fallback rules.
1191
1191
  */
1192
1192
  permissions?: string[] | null;
1193
+ /** Application roles, independent of built-in instance permissions. */
1194
+ roles?: string[];
1193
1195
  platform_user_id?: string | null;
1194
1196
  email?: string | null;
1195
1197
  display_name?: string | null;
@@ -1609,6 +1611,7 @@ interface AuthenticationUser {
1609
1611
  password_hash: string;
1610
1612
  role: 'admin' | 'user' | 'api';
1611
1613
  permissions?: string | null;
1614
+ roles?: string[];
1612
1615
  platform_user_id?: string | null;
1613
1616
  email?: string | null;
1614
1617
  display_name?: string | null;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { M as ModelDefinition, A as AgentDefinition } from './resolver-CWWRzZU1.js';
2
- export { m as AgentBuilderEnv, n as AgentBuilderEvent, ah as BroadcastOptions, C as CodeExecutionBridge, h as DurableAgentBuilder, D as DurableThread, l as DurableUserHub, af as FlowStateSdk, ai as FlowStateWithSdk, G as HandlerSide, H as HubClientInfo, E as HumanSide, aq as ImageContextConfig, ae as InjectMessageOptions, as as LLMProviderInterface, aL as NamespaceResolutionError, w as PromptContent, s as PromptDefinition, y as PromptIncludePart, x as PromptPart, F as PromptSide, t as PromptToolConfig, P as Provider, at as ProviderContentPart, aw as ProviderFilePart, av as ProviderImagePart, ar as ProviderRegistry, au as ProviderTextPart, B as SessionToolBinding, z as SessionToolConfig, I as SideConfig, J as SubagentRelationship, u as SubagentToolConfig, S as SubpromptConfig, o as ThreadEventPayload, p as ThreadRegistryEntry, T as ThreadWatchdog, j as ThreadWatchdogState, v as ToolConfig, U as UpdateThreadParams, q as User, k as WatchdogCheckin, W as WatchdogProbeResult, f as applyRuntimeCors, am as buildImageDescription, c as canAccessThread, a9 as cat, aJ as createNamespaceContext, Q as emitThreadEvent, ag as enhanceFlowState, a0 as exists, ad as find, R as forceTurn, ap as generateImageDescription, a7 as getFileStats, N as getMessages, al as getMessagesToSummarize, az as getShortName, a8 as getThumbnail, ak as getUnsummarizedImageAttachments, aG as getVisibleAgentNames, aI as getVisibleModelNames, aH as getVisiblePromptNames, aF as getVisibleToolNames, ac as grep, aj as hasImageAttachments, aa as head, L as injectMessage, d as isAdminOnlyApiRoute, i as isHostedInstance, b as isPublicApiRoute, aK as isQualifiedName, e as isSameOriginBrowserRequest, a as isTrustedLocalDevelopmentRequest, Z as linkFile, a2 as mkdir, a5 as move, ao as optimizeImageContext, ax as parseQualifiedName, ay as qualifyName, K as queueTool, _ as readFile, a3 as readdir, O as reloadHistory, a6 as rename, an as replaceImagesWithDescriptions, aD as resolveAgent, aE as resolveHook, aC as resolveModel, aB as resolvePrompt, aA as resolveTool, a4 as rmdir, r as runtimeCorsHeaders, g as runtimePreflightResponse, $ as stat, ab as tail, a1 as unlink, V as updateThread, X as writeFile, Y as writeImage } from './resolver-CWWRzZU1.js';
1
+ import { M as ModelDefinition, A as AgentDefinition } from './resolver-eygn_O1w.js';
2
+ export { m as AgentBuilderEnv, n as AgentBuilderEvent, ah as BroadcastOptions, C as CodeExecutionBridge, h as DurableAgentBuilder, D as DurableThread, l as DurableUserHub, af as FlowStateSdk, ai as FlowStateWithSdk, G as HandlerSide, H as HubClientInfo, E as HumanSide, aq as ImageContextConfig, ae as InjectMessageOptions, as as LLMProviderInterface, aL as NamespaceResolutionError, w as PromptContent, s as PromptDefinition, y as PromptIncludePart, x as PromptPart, F as PromptSide, t as PromptToolConfig, P as Provider, at as ProviderContentPart, aw as ProviderFilePart, av as ProviderImagePart, ar as ProviderRegistry, au as ProviderTextPart, B as SessionToolBinding, z as SessionToolConfig, I as SideConfig, J as SubagentRelationship, u as SubagentToolConfig, S as SubpromptConfig, o as ThreadEventPayload, p as ThreadRegistryEntry, T as ThreadWatchdog, j as ThreadWatchdogState, v as ToolConfig, U as UpdateThreadParams, q as User, k as WatchdogCheckin, W as WatchdogProbeResult, f as applyRuntimeCors, am as buildImageDescription, c as canAccessThread, a9 as cat, aJ as createNamespaceContext, Q as emitThreadEvent, ag as enhanceFlowState, a0 as exists, ad as find, R as forceTurn, ap as generateImageDescription, a7 as getFileStats, N as getMessages, al as getMessagesToSummarize, az as getShortName, a8 as getThumbnail, ak as getUnsummarizedImageAttachments, aG as getVisibleAgentNames, aI as getVisibleModelNames, aH as getVisiblePromptNames, aF as getVisibleToolNames, ac as grep, aj as hasImageAttachments, aa as head, L as injectMessage, d as isAdminOnlyApiRoute, i as isHostedInstance, b as isPublicApiRoute, aK as isQualifiedName, e as isSameOriginBrowserRequest, a as isTrustedLocalDevelopmentRequest, Z as linkFile, a2 as mkdir, a5 as move, ao as optimizeImageContext, ax as parseQualifiedName, ay as qualifyName, K as queueTool, _ as readFile, a3 as readdir, O as reloadHistory, a6 as rename, an as replaceImagesWithDescriptions, aD as resolveAgent, aE as resolveHook, aC as resolveModel, aB as resolvePrompt, aA as resolveTool, a4 as rmdir, r as runtimeCorsHeaders, g as runtimePreflightResponse, $ as stat, ab as tail, a1 as unlink, V as updateThread, X as writeFile, Y as writeImage } from './resolver-eygn_O1w.js';
3
3
  export { AgentPluginOptions, agentbuilder, builder } from './plugin.js';
4
- export { v as Agent, J as AttachmentRef, i as AuthContext, A as AuthUser, e as BuilderThreadEndpointHandler, C as CLIENT_STREAM_CHUNK_BYTES, t as ClientDuplex, u as ClientForwarding, p as ClientStreamRequest, q as ClientStreamResponse, n as ClientToolRequest, o as ClientToolResponse, B as Controller, a as ControllerContext, G as Env, H as FileRecord, N as FileStats, D as FlowResult, F as FlowState, K as GrepResult, P as ImageContentPart, I as ImageMetadata, L as LLMResponse, M as Message, U as MessageContent, Q as MultimodalContent, R as RequestContext, S as StorageBackend, E as TelemetryEvent, O as TextContentPart, T as ThreadEndpointContext, b as ThreadEnv, w as ThreadInstance, x as ThreadMetadata, y as ToolCall, z as ToolResult, f as authenticate, j as callClient, k as callClientStream, c as createThreadEndpointHandler, m as decodeStreamChunk, d as defineController, l as encodeStreamChunk, h as endpointCallerFromAuth, g as requireAdmin, r as requireAuth, s as supportsClientForwarding } from './index-BrQgCoFh.js';
4
+ export { v as Agent, J as AttachmentRef, i as AuthContext, A as AuthUser, e as BuilderThreadEndpointHandler, C as CLIENT_STREAM_CHUNK_BYTES, t as ClientDuplex, u as ClientForwarding, p as ClientStreamRequest, q as ClientStreamResponse, n as ClientToolRequest, o as ClientToolResponse, B as Controller, a as ControllerContext, G as Env, H as FileRecord, N as FileStats, D as FlowResult, F as FlowState, K as GrepResult, P as ImageContentPart, I as ImageMetadata, L as LLMResponse, M as Message, U as MessageContent, Q as MultimodalContent, R as RequestContext, S as StorageBackend, E as TelemetryEvent, O as TextContentPart, T as ThreadEndpointContext, b as ThreadEnv, w as ThreadInstance, x as ThreadMetadata, y as ToolCall, z as ToolResult, f as authenticate, j as callClient, k as callClientStream, c as createThreadEndpointHandler, m as decodeStreamChunk, d as defineController, l as encodeStreamChunk, h as endpointCallerFromAuth, g as requireAdmin, r as requireAuth, s as supportsClientForwarding } from './index-C82dLGPq.js';
5
5
  export { AgentType, DefineHandlerOptions, DefinitionLoader, GlobalNamespaceContext, HANDLER_SYMBOL, HandlerDefinition, HookExecutionContext, HookExecutionSource, HookSignatures, ImageContent, ModelCapabilities, ModelProvider, NamespaceContext, PackageSignature, PackedExports, PackedMeta, PackedMetadata, PackedNamespaceContext, ParentHookRequirement, ParentHookStage, PromptInput, PromptTextPart, ProviderAssistantMessage, ProviderConfigSlot, ProviderConfigSlots, ProviderConfigValueSource, ProviderDefinition, ProviderError, ProviderErrorCode, ProviderFactory, ProviderFactoryConfig, ProviderFinishReason, ProviderGeneratedImage, ProviderMessage, ProviderMessageContent, ProviderMethodOverrides, ModelCapabilities as ProviderModelCapabilities, ProviderOverride, ProviderOverrideContext, ProviderReasoningDetail, ProviderRequest, ProviderResponse, ProviderStreamChunk, ProviderSyncOverride, ProviderSystemMessage, ProviderTool, ProviderToolCallPart, ProviderToolMessage, ProviderToolResultContent, ProviderUsage, ProviderUserMessage, ReasoningConfig, StructuredPrompt, TextContent, ThreadHookName, Tool, ToolArgs, ToolArgsNode, ToolArgsRawShape, ToolContent, belongsToPackage, defineAgent, defineHandler, defineHook, defineModel, definePrompt, defineProvider, defineTool, isHandler, isPacked, isVisibleInNamespace, mapReasoningLevel, providerConst, providerEnv, providerValue } from '@standardagents/spec';
6
6
  export { C as ConstituentItem, D as DiscoveredPackage, N as NamespacedRegistry, P as PackingAnalysis, a as PackingOptions, b as PackingResult, U as UnpackOptions, c as UnpackResult } from './types-Dhd0M369.js';
7
7
  export { D as DiscoveryConfig, P as PackageDiscoveryService, d as discoverPackages } from './discovery-D5pmuazY.js';
package/dist/index.js CHANGED
@@ -10329,6 +10329,24 @@ var init_platform_handoff_jtis = __esm({
10329
10329
  }
10330
10330
  });
10331
10331
 
10332
+ // src/durable-objects/agentbuilder-migrations/0022_application_roles.ts
10333
+ var migration60;
10334
+ var init_application_roles = __esm({
10335
+ "src/durable-objects/agentbuilder-migrations/0022_application_roles.ts"() {
10336
+ migration60 = {
10337
+ version: 22,
10338
+ async up(sql) {
10339
+ sql.exec(`CREATE TABLE platform_application_roles (
10340
+ platform_user_id TEXT PRIMARY KEY,
10341
+ roles TEXT NOT NULL DEFAULT '[]',
10342
+ roles_version INTEGER NOT NULL DEFAULT 0
10343
+ )`);
10344
+ sql.exec(`INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '22')`);
10345
+ }
10346
+ };
10347
+ }
10348
+ });
10349
+
10332
10350
  // src/durable-objects/agentbuilder-migrations/index.ts
10333
10351
  var migrations2, LATEST_SCHEMA_VERSION2;
10334
10352
  var init_agentbuilder_migrations = __esm({
@@ -10354,9 +10372,10 @@ var init_agentbuilder_migrations = __esm({
10354
10372
  init_scope_skills();
10355
10373
  init_websocket_tickets();
10356
10374
  init_platform_handoff_jtis();
10357
- migrations2 = [migration39, migration40, migration41, migration42, migration43, migration44, migration45, migration46, migration47, migration48, migration49, migration50, migration51, migration52, migration53, migration54, migration55, migration56, migration57, migration58, migration59];
10375
+ init_application_roles();
10376
+ migrations2 = [migration39, migration40, migration41, migration42, migration43, migration44, migration45, migration46, migration47, migration48, migration49, migration50, migration51, migration52, migration53, migration54, migration55, migration56, migration57, migration58, migration59, migration60];
10358
10377
  LATEST_SCHEMA_VERSION2 = migrations2.reduce(
10359
- (max, migration60) => Math.max(max, migration60.version),
10378
+ (max, migration61) => Math.max(max, migration61.version),
10360
10379
  0
10361
10380
  );
10362
10381
  }
@@ -11165,9 +11184,9 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
11165
11184
  }
11166
11185
  }
11167
11186
  async runMigrations(fromVersion) {
11168
- for (const migration60 of migrations2) {
11169
- if (migration60.version > fromVersion) {
11170
- await migration60.up(this.ctx.storage.sql);
11187
+ for (const migration61 of migrations2) {
11188
+ if (migration61.version > fromVersion) {
11189
+ await migration61.up(this.ctx.storage.sql);
11171
11190
  }
11172
11191
  }
11173
11192
  }
@@ -12722,6 +12741,7 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
12722
12741
  // admin meaning.
12723
12742
  role: row.role === "user" ? "user" : row.role === "api" ? "api" : "admin",
12724
12743
  permissions: parseStoredPermissions(row.permissions),
12744
+ roles: parseStoredPermissions(row.roles) ?? [],
12725
12745
  platform_user_id: row.platform_user_id ?? null,
12726
12746
  email: row.email ?? null,
12727
12747
  display_name: row.display_name ?? null,
@@ -12739,7 +12759,8 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
12739
12759
  await this.ensureMigrated();
12740
12760
  const cursor = await this.ctx.storage.sql.exec(
12741
12761
  `SELECT id, username, password_hash, COALESCE(instance_role, role) AS role,
12742
- permissions, platform_user_id, email, display_name, avatar_url, source, replica_active,
12762
+ permissions, (SELECT roles FROM platform_application_roles WHERE platform_user_id = users.platform_user_id) AS roles,
12763
+ platform_user_id, email, display_name, avatar_url, source, replica_active,
12743
12764
  created_at, updated_at
12744
12765
  FROM users WHERE username = ? AND deleted_at IS NULL AND replica_active != 0`,
12745
12766
  username
@@ -12755,7 +12776,8 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
12755
12776
  await this.ensureMigrated();
12756
12777
  const cursor = await this.ctx.storage.sql.exec(
12757
12778
  `SELECT id, username, password_hash, COALESCE(instance_role, role) AS role,
12758
- permissions, platform_user_id, email, display_name, avatar_url, source, replica_active,
12779
+ permissions, (SELECT roles FROM platform_application_roles WHERE platform_user_id = users.platform_user_id) AS roles,
12780
+ platform_user_id, email, display_name, avatar_url, source, replica_active,
12759
12781
  created_at, updated_at
12760
12782
  FROM users WHERE id = ? AND deleted_at IS NULL AND replica_active != 0`,
12761
12783
  id
@@ -12799,6 +12821,7 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
12799
12821
  password_hash: params.password_hash,
12800
12822
  role: params.role || "admin",
12801
12823
  permissions: params.permissions ?? null,
12824
+ roles: [],
12802
12825
  platform_user_id: params.platform_user_id ?? null,
12803
12826
  email: params.email ?? null,
12804
12827
  display_name: params.display_name ?? null,
@@ -12932,11 +12955,31 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
12932
12955
  );
12933
12956
  return true;
12934
12957
  }
12935
- /**
12936
- * Upsert a platform-replicated identity and return the local user row.
12937
- */
12958
+ /** Apply an authoritative role replacement while retaining revocation fences. */
12959
+ applyApplicationRoles(platformUserId, roles, version, revoke = false) {
12960
+ const revision = version === void 0 ? 0 : version;
12961
+ if (typeof revision !== "number" || !Number.isSafeInteger(revision) || revision < 0) {
12962
+ throw new Error("Invalid application roles revision");
12963
+ }
12964
+ if (roles !== void 0 && (!Array.isArray(roles) || !roles.every((role) => typeof role === "string"))) {
12965
+ throw new Error("Invalid application roles");
12966
+ }
12967
+ this.ctx.storage.sql.exec(
12968
+ `INSERT INTO platform_application_roles (platform_user_id, roles, roles_version)
12969
+ VALUES (?, ?, ?)
12970
+ ON CONFLICT(platform_user_id) DO UPDATE SET roles = excluded.roles, roles_version = excluded.roles_version
12971
+ WHERE excluded.roles_version > platform_application_roles.roles_version
12972
+ OR (? = 1 AND excluded.roles_version = platform_application_roles.roles_version)`,
12973
+ platformUserId,
12974
+ JSON.stringify(roles ?? []),
12975
+ revision,
12976
+ revoke ? 1 : 0
12977
+ );
12978
+ }
12979
+ /** Upsert a platform-replicated identity and return the local user row. */
12938
12980
  async upsertPlatformReplicaUser(replica) {
12939
12981
  await this.ensureMigrated();
12982
+ this.applyApplicationRoles(replica.platform_user_id, replica.roles, replica.roles_version);
12940
12983
  const now = Math.floor(Date.now() / 1e3);
12941
12984
  const fallback = this.normalizeReplicaUsername(
12942
12985
  replica.email?.split("@")[0] ?? null,
@@ -12983,7 +13026,7 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
12983
13026
  }
12984
13027
  return updated;
12985
13028
  }
12986
- return this.createUser({
13029
+ const created = await this.createUser({
12987
13030
  username: availableUsername,
12988
13031
  password_hash: `platform-replica:${crypto.randomUUID()}`,
12989
13032
  role: replica.role,
@@ -12994,12 +13037,18 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
12994
13037
  avatar_url: replica.avatar_url ?? null,
12995
13038
  source: "standard_agents"
12996
13039
  });
13040
+ const user = await this.getUserById(created.id);
13041
+ if (!user) throw new Error("Failed to load replicated user after creation");
13042
+ return user;
12997
13043
  }
12998
13044
  /**
12999
13045
  * Apply a full platform read-replica snapshot for this instance.
13000
13046
  */
13001
13047
  async applyPlatformReplicaSnapshot(snapshot) {
13002
13048
  await this.ensureMigrated();
13049
+ for (const revocation of snapshot.role_revocations ?? []) {
13050
+ this.applyApplicationRoles(revocation.platform_user_id, [], revocation.roles_version, true);
13051
+ }
13003
13052
  const activeUserIds = /* @__PURE__ */ new Set();
13004
13053
  for (const replicaUser of snapshot.users) {
13005
13054
  const user = await this.upsertPlatformReplicaUser(replicaUser);
@@ -13052,10 +13101,9 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
13052
13101
  const keys = snapshot.api_keys ?? [];
13053
13102
  for (const key of keys) {
13054
13103
  const user = key.user_platform_id ? await this.getUserByPlatformUserId(key.user_platform_id) : await this.getFirstReplicaAdminUser();
13055
- const keyUser = user ?? await this.getFirstReplicaAdminUser();
13056
- if (!keyUser) continue;
13104
+ if (!user) continue;
13057
13105
  activePlatformKeyIds.add(key.id);
13058
- await this.upsertPlatformReplicaApiKey(key, keyUser.id);
13106
+ await this.upsertPlatformReplicaApiKey(key, user.id);
13059
13107
  }
13060
13108
  const now = Math.floor(Date.now() / 1e3);
13061
13109
  if (activePlatformKeyIds.size > 0) {
@@ -17667,9 +17715,9 @@ var init_DurableThread = __esm({
17667
17715
  * Each migration is run in order, starting from the current version + 1.
17668
17716
  */
17669
17717
  async runMigrations(fromVersion) {
17670
- for (const migration60 of migrations) {
17671
- if (migration60.version > fromVersion) {
17672
- await migration60.up(this.ctx.storage.sql);
17718
+ for (const migration61 of migrations) {
17719
+ if (migration61.version > fromVersion) {
17720
+ await migration61.up(this.ctx.storage.sql);
17673
17721
  }
17674
17722
  }
17675
17723
  }
@@ -29547,6 +29595,7 @@ var init_ThreadStateImpl = __esm({
29547
29595
  username: user.username,
29548
29596
  role: user.role,
29549
29597
  permissions: user.permissions ?? null,
29598
+ roles: user.roles ?? [],
29550
29599
  email: user.email ?? null,
29551
29600
  display_name: user.display_name ?? null,
29552
29601
  avatar_url: user.avatar_url ?? null
@@ -30241,14 +30290,7 @@ declare module 'virtual:@standardagents/builder' {
30241
30290
  terminated?: number | null;
30242
30291
  }
30243
30292
 
30244
- export interface User {
30245
- id: string;
30246
- username: string;
30247
- password_hash: string;
30248
- role: 'admin';
30249
- created_at: number;
30250
- updated_at: number;
30251
- }
30293
+ export type User = NonNullable<Awaited<ReturnType<BaseDurableAgentBuilder['getUserById']>>>;
30252
30294
 
30253
30295
  export interface Provider {
30254
30296
  name: string;
@@ -38911,12 +38953,13 @@ function runtimePreflightResponse(request, env) {
38911
38953
  // src/middleware/auth.ts
38912
38954
  function endpointCallerFromAuth(auth) {
38913
38955
  if (!auth) return null;
38914
- const { id, username, role, permissions, email, display_name, avatar_url } = auth.user;
38956
+ const { id, username, role, permissions, roles, email, display_name, avatar_url } = auth.user;
38915
38957
  return {
38916
38958
  id,
38917
38959
  username,
38918
38960
  role,
38919
38961
  permissions: permissions ?? null,
38962
+ roles: roles ?? [],
38920
38963
  email: email ?? null,
38921
38964
  display_name: display_name ?? null,
38922
38965
  avatar_url: avatar_url ?? null
@@ -38962,6 +39005,8 @@ function parseWebSocketTicketAuth(authJson) {
38962
39005
  if (typeof user.id !== "string" || typeof user.username !== "string" || typeof user.role !== "string" || record.authType !== "super_admin" && record.authType !== "session" && record.authType !== "api_key") {
38963
39006
  return null;
38964
39007
  }
39008
+ const roles = user.roles;
39009
+ if (roles !== void 0 && (!Array.isArray(roles) || !roles.every((role) => typeof role === "string"))) return null;
38965
39010
  const permissions = user.permissions;
38966
39011
  if (permissions !== void 0 && permissions !== null && (!Array.isArray(permissions) || !permissions.every((permission) => typeof permission === "string"))) {
38967
39012
  return null;
@@ -38973,6 +39018,7 @@ function parseWebSocketTicketAuth(authJson) {
38973
39018
  username: user.username,
38974
39019
  role: user.role,
38975
39020
  permissions,
39021
+ roles: Array.isArray(roles) ? roles : [],
38976
39022
  platform_user_id: typeof user.platform_user_id === "string" ? user.platform_user_id : null,
38977
39023
  email: typeof user.email === "string" ? user.email : null,
38978
39024
  display_name: typeof user.display_name === "string" ? user.display_name : null,
@@ -38996,7 +39042,19 @@ async function consumeWebSocketTicket(request, env) {
38996
39042
  ticket_hash: await hashToken(ticket),
38997
39043
  pathname: url.pathname
38998
39044
  });
38999
- return typeof authJson === "string" ? parseWebSocketTicketAuth(authJson) : null;
39045
+ const context = typeof authJson === "string" ? parseWebSocketTicketAuth(authJson) : null;
39046
+ if (!context || context.authType === "super_admin") return context;
39047
+ const user = await getAgentBuilder(env).getUserById(context.user.id);
39048
+ if (!user) return null;
39049
+ return {
39050
+ ...context,
39051
+ user: {
39052
+ ...context.user,
39053
+ role: user.role,
39054
+ permissions: parsePermissions(user.permissions),
39055
+ roles: user.roles ?? []
39056
+ }
39057
+ };
39000
39058
  }
39001
39059
  async function authenticate(request, env) {
39002
39060
  const ticketAuth = await consumeWebSocketTicket(request, env);
@@ -39019,7 +39077,8 @@ async function authenticate(request, env) {
39019
39077
  user: {
39020
39078
  id: "super_admin",
39021
39079
  username: "admin",
39022
- role: "admin"
39080
+ role: "admin",
39081
+ roles: []
39023
39082
  },
39024
39083
  authType: "super_admin"
39025
39084
  };
@@ -39040,6 +39099,7 @@ async function authenticate(request, env) {
39040
39099
  username: user.username,
39041
39100
  role: user.role,
39042
39101
  permissions: parsePermissions(user.permissions),
39102
+ roles: user.roles ?? [],
39043
39103
  platform_user_id: user.platform_user_id ?? null,
39044
39104
  email: user.email ?? null,
39045
39105
  display_name: user.display_name ?? null,
@@ -39063,6 +39123,7 @@ async function authenticate(request, env) {
39063
39123
  username: user.username,
39064
39124
  role: user.role,
39065
39125
  permissions: parsePermissions(user.permissions),
39126
+ roles: user.roles ?? [],
39066
39127
  platform_user_id: user.platform_user_id ?? null,
39067
39128
  email: user.email ?? null,
39068
39129
  display_name: user.display_name ?? null,
@@ -39466,6 +39527,7 @@ var UserStateImpl = class {
39466
39527
  username: user.username,
39467
39528
  role: user.role,
39468
39529
  permissions: user.permissions ?? null,
39530
+ roles: user.roles ?? [],
39469
39531
  email: user.email ?? null,
39470
39532
  display_name: user.display_name ?? null,
39471
39533
  avatar_url: user.avatar_url ?? null