@opengeni/api-router 3.1.3-canary.38890816741001 → 3.3.0

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.
Files changed (47) hide show
  1. package/dist/app.js +1 -1
  2. package/dist/{chunk-OT56OY4V.js → chunk-6CECHDZP.js} +1569 -399
  3. package/dist/{chunk-OT56OY4V.js.map → chunk-6CECHDZP.js.map} +1 -1
  4. package/dist/index.js +50 -2
  5. package/dist/index.js.map +1 -1
  6. package/dist/integrations/external-vault-providers.d.ts +29 -0
  7. package/dist/interaction-secrets-vault.d.ts +2 -2
  8. package/dist/mcp/action-descriptions.d.ts +1 -1
  9. package/dist/mcp/scheduled-task-view.d.ts +4 -4
  10. package/dist/routes/vault-providers.d.ts +4 -2
  11. package/dist/sandbox/channel-a.d.ts +10 -1
  12. package/dist/shutdown.d.ts +14 -0
  13. package/dist/site-publishing/agent-data-tools.d.ts +5 -5
  14. package/dist/site-publishing/agent-session.d.ts +3 -2
  15. package/dist/site-publishing/runtime.d.ts +7 -6
  16. package/dist/site-publishing/service.d.ts +8 -11
  17. package/dist/site-publishing/session-request-authority.d.ts +3 -0
  18. package/dist/workspace-tool-gateway-secrets.d.ts +1 -1
  19. package/package.json +25 -22
  20. package/src/access-grant-rls.ts +1 -0
  21. package/src/app.ts +14 -2
  22. package/src/http/sse.ts +5 -1
  23. package/src/index.ts +13 -1
  24. package/src/integrations/external-vault-providers.ts +136 -0
  25. package/src/interaction-secrets-vault.ts +6 -2
  26. package/src/mcp/action-catalog.gen.ts +253 -4
  27. package/src/mcp/action-descriptions.ts +32 -2
  28. package/src/mcp/action-schema-imports.gen.ts +3 -1
  29. package/src/routes/browser-sessions.ts +61 -17
  30. package/src/routes/computer-sessions.ts +102 -39
  31. package/src/routes/connections.ts +17 -0
  32. package/src/routes/insights-usage.ts +22 -0
  33. package/src/routes/sessions.ts +22 -4
  34. package/src/routes/site-runtime.ts +62 -20
  35. package/src/routes/vault-providers.ts +788 -29
  36. package/src/routes/vaults.ts +5 -1
  37. package/src/sandbox/channel-a.ts +18 -1
  38. package/src/sandbox/metrics-ingestion.ts +1 -0
  39. package/src/shutdown.ts +54 -0
  40. package/src/site-frame-guard.ts +11 -2
  41. package/src/site-publishing/agent-data-tools.ts +16 -8
  42. package/src/site-publishing/agent-session.ts +24 -6
  43. package/src/site-publishing/runtime.ts +29 -7
  44. package/src/site-publishing/service.ts +65 -77
  45. package/src/site-publishing/session-request-authority.ts +14 -0
  46. package/src/workspace-tool-gateway-secrets.ts +9 -2
  47. package/src/workspace-tool-gateway.ts +6 -2
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-OGQDXVXY.js";
4
4
 
5
5
  // src/app.ts
6
- import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
6
+ import { AsyncLocalStorage as AsyncLocalStorage4 } from "async_hooks";
7
7
 
8
8
  // src/routes/claude-subscription-accounts.ts
9
9
  import { createHmac as createHmac2 } from "crypto";
@@ -4435,7 +4435,7 @@ import {
4435
4435
  setMcpOAuthRequestOrganizationAccess
4436
4436
  } from "@opengeni/db";
4437
4437
  import {
4438
- hasPermission as hasPermission14,
4438
+ hasPermission as hasPermission15,
4439
4439
  requireAccessContext as requireAccessContext2,
4440
4440
  requireAccessGrantAuthorization as requireAccessGrantAuthorization6
4441
4441
  } from "@opengeni/core";
@@ -4631,7 +4631,7 @@ import {
4631
4631
  buildApiIntegrationMcpServers,
4632
4632
  expandApiIntegrationAccountRoutes,
4633
4633
  expandMcpAccountRoutes,
4634
- hasPermission as hasPermission13,
4634
+ hasPermission as hasPermission14,
4635
4635
  externalActorContinuationForAuthorization as externalActorContinuationForAuthorization5,
4636
4636
  isVerifiedOrganizationServiceAuthorization as isVerifiedOrganizationServiceAuthorization2,
4637
4637
  externalContinuationCommitAuthorizer,
@@ -7916,9 +7916,11 @@ async function deleteSiteDataFile(deps, grant, siteId3, fileId, surface3 = {}) {
7916
7916
 
7917
7917
  // src/site-publishing/agent-data-tools.ts
7918
7918
  import {
7919
- siteHostname as siteHostname3
7919
+ siteHostname as siteHostname3,
7920
+ permissionsRequiredByFirstPartyTools
7920
7921
  } from "@opengeni/contracts";
7921
7922
  import { resolveFirstPartyMcpToolPolicy } from "@opengeni/config";
7923
+ import { hasPermission as hasPermission5 } from "@opengeni/core";
7922
7924
  import {
7923
7925
  consumeSiteRuntimeRate as consumeSiteRuntimeRate2,
7924
7926
  findSiteRuntimeAgentConversation,
@@ -8033,7 +8035,10 @@ import {
8033
8035
  siteHostname as siteHostname2,
8034
8036
  SITE_NOT_AVAILABLE_FOR_VIEWER_ERROR_CODE
8035
8037
  } from "@opengeni/contracts";
8036
- import { sessionUsageLimitsProducerEnabled } from "@opengeni/core";
8038
+ import {
8039
+ sessionUsageLimitsProducerEnabled,
8040
+ stampSiteViewerSessionAuthorization
8041
+ } from "@opengeni/core";
8037
8042
  import {
8038
8043
  consumeSiteRuntimeRate,
8039
8044
  findSiteHostname,
@@ -8056,6 +8061,15 @@ import {
8056
8061
  withWorkspaceSessionActivityRls
8057
8062
  } from "@opengeni/db";
8058
8063
 
8064
+ // src/site-publishing/session-request-authority.ts
8065
+ var authorities = /* @__PURE__ */ new WeakMap();
8066
+ function bindSiteSessionRequestAuthority(request, reauthorize) {
8067
+ authorities.set(request, reauthorize);
8068
+ }
8069
+ async function reauthorizeSiteSessionRequest(request) {
8070
+ await authorities.get(request)?.();
8071
+ }
8072
+
8059
8073
  // src/site-publishing/limits.ts
8060
8074
  import {
8061
8075
  DEFAULT_SITE_LIMITS,
@@ -8251,6 +8265,7 @@ function storedSiteLimitProfileKind(kind) {
8251
8265
 
8252
8266
  // src/site-publishing/service.ts
8253
8267
  import { randomBytes as randomBytes2 } from "crypto";
8268
+ import { AsyncLocalStorage } from "async_hooks";
8254
8269
  import {
8255
8270
  normalizeSitesDomain,
8256
8271
  OPENGENI_API_CONTRACT_HEADER,
@@ -8282,7 +8297,7 @@ import {
8282
8297
  readSiteRuntimeUsage,
8283
8298
  recordSitePublicationScan,
8284
8299
  getPublishedSite as getPublishedSite2,
8285
- listActiveSiteRuntimeConversations,
8300
+ listSiteRuntimeCancellationCandidates,
8286
8301
  revokeSiteViewerSessions,
8287
8302
  SitePublishingError,
8288
8303
  SITE_RUNTIME_SITE_PRINCIPAL,
@@ -10014,12 +10029,9 @@ async function runSitePublishing(fn) {
10014
10029
  var SITE_EFFECT_CONCURRENCY = 4;
10015
10030
  var SITE_EFFECT_QUEUE_LIMIT = 2e3;
10016
10031
  var effectsBySettings = /* @__PURE__ */ new WeakMap();
10017
- var dispatchBySettings = /* @__PURE__ */ new WeakMap();
10018
- function setSitePublishingDispatch(settings, dispatch) {
10019
- dispatchBySettings.set(settings, dispatch);
10020
- }
10021
- function sitePublishingDispatch(settings) {
10022
- return dispatchBySettings.get(settings) ?? null;
10032
+ var cancellationBySettings = /* @__PURE__ */ new WeakMap();
10033
+ function setSitePublishingCancellation(settings, cancel) {
10034
+ cancellationBySettings.set(settings, cancel);
10023
10035
  }
10024
10036
  function createEffects(settings, options = {}) {
10025
10037
  const queueLimit = options.queueLimit ?? SITE_EFFECT_QUEUE_LIMIT;
@@ -10297,14 +10309,18 @@ async function siteServiceSessionRequest(deps, scope, site, input) {
10297
10309
  "x-opengeni-site-id": site.id
10298
10310
  });
10299
10311
  if (site.versionId) headers.set("x-opengeni-site-version", site.versionId);
10300
- if (input.body !== void 0) headers.set("content-type", "application/json");
10312
+ const body5 = input.body === void 0 ? void 0 : JSON.stringify(input.body);
10313
+ if (body5 !== void 0) {
10314
+ headers.set("content-type", "application/json");
10315
+ headers.set("content-length", String(Buffer.byteLength(body5)));
10316
+ }
10301
10317
  return new Request(new URL(input.path, input.origin), {
10302
10318
  method: input.method,
10303
10319
  headers,
10304
- ...input.body === void 0 ? {} : { body: JSON.stringify(input.body) }
10320
+ ...body5 === void 0 ? {} : { body: body5 }
10305
10321
  });
10306
10322
  }
10307
- var STOP_CONVERSATIONS_LIMIT = 200;
10323
+ var STOP_CONVERSATIONS_PAGE_SIZE = 200;
10308
10324
  async function stopSiteViewers(deps, scope, siteId3, options) {
10309
10325
  let revokedSessions = 0;
10310
10326
  if (options.revokeSessions !== false) {
@@ -10318,67 +10334,53 @@ async function stopSiteViewers(deps, scope, siteId3, options) {
10318
10334
  }
10319
10335
  }
10320
10336
  if (options.cancelConversations === false) return { revokedSessions };
10321
- const dispatch = sitePublishingDispatch(deps.settings);
10322
- if (!dispatch) {
10323
- console.warn("[site-publishing] conversation cancel skipped: no in-process dispatch", {
10337
+ const cancel = cancellationBySettings.get(deps.settings);
10338
+ if (!cancel) {
10339
+ console.warn("[site-publishing] conversation cancel unavailable: no lifecycle adapter", {
10324
10340
  siteId: siteId3
10325
10341
  });
10326
10342
  return { revokedSessions };
10327
10343
  }
10328
10344
  const effects = sitePublishingEffects(deps.settings);
10329
- const origin = deps.settings.publicBaseUrl ?? "http://localhost";
10330
- effects.schedule("cancel conversations", async () => {
10331
- const sessionIds = await listActiveSiteRuntimeConversations(deps.db, scope, {
10332
- siteId: siteId3,
10333
- limit: STOP_CONVERSATIONS_LIMIT,
10334
- ...options.toolsNarrowedTo ? { toolsNarrowedTo: options.toolsNarrowedTo } : {}
10335
- });
10336
- if (sessionIds.length === 0) return;
10337
- const versionId = (await getPublishedSite2(deps.db, scope, siteId3))?.currentVersionId ?? null;
10338
- if (!versionId) {
10339
- console.warn("[site-publishing] conversation cancel skipped: the Site has no version", {
10340
- siteId: siteId3
10345
+ const runInContext = AsyncLocalStorage.snapshot();
10346
+ const operation = crypto.randomUUID();
10347
+ const startedBefore = /* @__PURE__ */ new Date();
10348
+ const run2 = () => runInContext(async () => {
10349
+ let after;
10350
+ let failed = 0;
10351
+ for (; ; ) {
10352
+ const sessionIds = await listSiteRuntimeCancellationCandidates(deps.db, scope, {
10353
+ siteId: siteId3,
10354
+ limit: STOP_CONVERSATIONS_PAGE_SIZE,
10355
+ startedBefore,
10356
+ ...after ? { after } : {},
10357
+ ...options.toolsNarrowedTo ? { toolsNarrowedTo: options.toolsNarrowedTo } : {}
10341
10358
  });
10342
- return;
10343
- }
10344
- const operation = crypto.randomUUID();
10345
- for (const sessionId of sessionIds) {
10346
- try {
10347
- const response = await dispatch(
10348
- await siteServiceSessionRequest(
10349
- deps,
10350
- scope,
10351
- { id: siteId3, versionId },
10352
- {
10353
- origin,
10354
- method: "POST",
10355
- path: `/v1/workspaces/${scope.workspaceId}/sessions/${sessionId}/control`,
10356
- body: {
10357
- action: "cancel",
10358
- clientEventId: `site-stop:${operation}:${sessionId}`.slice(0, 200),
10359
- reason: options.reason.slice(0, 500)
10360
- },
10361
- label: "Published Site"
10362
- }
10363
- )
10364
- );
10365
- if (!response.ok)
10359
+ if (sessionIds.length === 0) break;
10360
+ for (const sessionId of sessionIds) {
10361
+ try {
10362
+ await cancel({
10363
+ ...scope,
10364
+ siteId: siteId3,
10365
+ sessionId,
10366
+ operationKey: `site-stop:${operation}:${sessionId}`,
10367
+ reason: options.reason.slice(0, 500)
10368
+ });
10369
+ } catch (error) {
10370
+ failed += 1;
10366
10371
  console.warn("[site-publishing] could not cancel a Site conversation", {
10367
10372
  siteId: siteId3,
10368
10373
  sessionId,
10369
- status: response.status,
10370
- body: (await response.text().catch(() => "")).slice(0, 300)
10374
+ error: error instanceof Error ? error.message : String(error)
10371
10375
  });
10372
- else await response.body?.cancel().catch(() => void 0);
10373
- } catch (error) {
10374
- console.warn("[site-publishing] could not cancel a Site conversation", {
10375
- siteId: siteId3,
10376
- sessionId,
10377
- error: error instanceof Error ? error.message : String(error)
10378
- });
10376
+ }
10379
10377
  }
10378
+ after = sessionIds.at(-1);
10380
10379
  }
10380
+ if (failed > 0)
10381
+ throw new Error(`Site lifecycle cancellation failed for ${failed} conversations`);
10381
10382
  });
10383
+ if (!effects.schedule("cancel conversations", run2)) await run2();
10382
10384
  return { revokedSessions };
10383
10385
  }
10384
10386
  var abuseNoticeHours = /* @__PURE__ */ new Map();
@@ -11192,12 +11194,24 @@ async function meterSiteRuntime(deps, host, event) {
11192
11194
  }
11193
11195
  }
11194
11196
  async function siteRuntimeSessionRequest(deps, host, viewer, input) {
11195
- return await siteServiceSessionRequest(
11197
+ const request = await siteServiceSessionRequest(
11196
11198
  deps,
11197
11199
  host.scope,
11198
11200
  { id: host.site.id, versionId: host.versionId },
11199
11201
  { ...input, label: `${siteRuntimeViewerLabel(viewer)} on ${host.hostname}` }
11200
11202
  );
11203
+ bindSiteSessionRequestAuthority(request, input.reauthorize);
11204
+ if (viewer.kind === "member" && viewer.subjectId && viewer.sessionId) {
11205
+ stampSiteViewerSessionAuthorization(request, {
11206
+ organizationId: host.scope.accountId,
11207
+ subjectId: viewer.subjectId,
11208
+ permissions: [
11209
+ .../* @__PURE__ */ new Set([...SITE_RUNTIME_AGENT_PERMISSIONS, ...input.extraPermissions ?? []])
11210
+ ],
11211
+ workspaceId: host.scope.workspaceId
11212
+ });
11213
+ }
11214
+ return request;
11201
11215
  }
11202
11216
  function siteRuntimeForwardedResponse(response) {
11203
11217
  const headers = new Headers(response.headers);
@@ -11217,10 +11231,6 @@ var SITE_AGENT_SQL_TOOLS = Object.freeze([
11217
11231
  var SITE_AGENT_MEMBER_SQL_TOOLS = Object.freeze([
11218
11232
  "site_sql_query"
11219
11233
  ]);
11220
- var SITE_AGENT_DATA_TOOL_PERMISSIONS = Object.freeze([
11221
- "artifacts:read",
11222
- "artifacts:publish"
11223
- ]);
11224
11234
  var SITE_AGENT_OTHER_SITE_MESSAGE2 = "This Site's assistant can only use this Site's data";
11225
11235
  var SITE_AGENT_MANAGEMENT_MESSAGE = "This Site's assistant can use the Site's data, not manage the Site";
11226
11236
  function siteAgentDataToolNames(input) {
@@ -11229,18 +11239,23 @@ function siteAgentDataToolNames(input) {
11229
11239
  ...input.siteSql ? SITE_AGENT_SQL_TOOLS : [],
11230
11240
  ...input.siteSql && input.viewerKind === "member" ? SITE_AGENT_MEMBER_SQL_TOOLS : []
11231
11241
  ];
11232
- return names.filter((name) => input.allowed.includes(name));
11242
+ return names.filter(
11243
+ (name) => input.allowed.includes(name) && (input.viewerKind !== "member" || input.memberPermissions === void 0 || permissionsRequiredByFirstPartyTools([name]).every(
11244
+ (permission) => hasPermission5(input.memberPermissions, permission)
11245
+ ))
11246
+ );
11233
11247
  }
11234
11248
  async function siteAgentSiteSqlOn(deps, scope, siteId3) {
11235
11249
  if (!siteSqlOffered(deps.settings)) return false;
11236
11250
  const database = await getSiteSqlDatabase2(deps.db, { ...scope, siteId: siteId3 }).catch(() => null);
11237
11251
  return database?.enabled === true;
11238
11252
  }
11239
- async function siteAgentDataToolsForStart(deps, scope, siteId3, viewerKind) {
11253
+ async function siteAgentDataToolsForStart(deps, scope, siteId3, viewerKind, memberPermissions) {
11240
11254
  return siteAgentDataToolNames({
11241
11255
  viewerKind,
11242
11256
  siteSql: await siteAgentSiteSqlOn(deps, scope, siteId3),
11243
- allowed: resolveFirstPartyMcpToolPolicy(deps.settings).allowed
11257
+ allowed: resolveFirstPartyMcpToolPolicy(deps.settings).allowed,
11258
+ ...memberPermissions === void 0 ? {} : { memberPermissions }
11244
11259
  });
11245
11260
  }
11246
11261
  function sitePublishedDataViewer(host, principal, guest) {
@@ -12533,7 +12548,7 @@ import {
12533
12548
  editableArtifactId,
12534
12549
  editableArtifactReplicaId,
12535
12550
  editableArtifactScope,
12536
- hasPermission as hasPermission5,
12551
+ hasPermission as hasPermission6,
12537
12552
  requireAccessGrant as requireAccessGrant10,
12538
12553
  requireAccessGrantAuthorization as requireAccessGrantAuthorization2,
12539
12554
  externalActorContinuationForAuthorization as externalActorContinuationForAuthorization2,
@@ -12606,6 +12621,7 @@ async function withAccessGrantSessionRlsContext(deps, grant, fn) {
12606
12621
  {
12607
12622
  subjectId: actor.subjectId,
12608
12623
  initiatingHumanSubjectId: actor.initiatingHumanSubjectId,
12624
+ agentRootSessionId: actor.callerRootSessionId,
12609
12625
  privateFileOwnerSubjectId: learning.defaultScope === "personal" ? learning.subjectId : null
12610
12626
  },
12611
12627
  fn
@@ -12846,7 +12862,7 @@ function registerEditableArtifactRoutes(app, deps) {
12846
12862
  app.post(`${collection}/imports`, async (context) => {
12847
12863
  const workspaceId = context.req.param("workspaceId");
12848
12864
  const grant = await requireAccessGrant10(context, deps, workspaceId, "artifacts:publish");
12849
- if (!hasPermission5(grant.permissions, "files:read")) {
12865
+ if (!hasPermission6(grant.permissions, "files:read")) {
12850
12866
  throw applicationHttpError("forbidden");
12851
12867
  }
12852
12868
  const body5 = await parseBoundedImportRequest(context);
@@ -12943,7 +12959,7 @@ function registerEditableArtifactRoutes(app, deps) {
12943
12959
  snapshotVersion: body5.snapshotVersion,
12944
12960
  commandProtocolVersion: body5.commandProtocolVersion,
12945
12961
  committedTransactionProtocolVersion: body5.committedTransactionProtocolVersion,
12946
- allowEdit: hasPermission5(grant.permissions, "artifacts:publish"),
12962
+ allowEdit: hasPermission6(grant.permissions, "artifacts:publish"),
12947
12963
  ...body5.sourceSessionId ? {
12948
12964
  sourceSessionAuthority: {
12949
12965
  sessionId: body5.sourceSessionId,
@@ -12970,7 +12986,7 @@ function registerEditableArtifactRoutes(app, deps) {
12970
12986
  permissions: [
12971
12987
  "sessions:read",
12972
12988
  "artifacts:read",
12973
- ...hasPermission5(grant.permissions, "artifacts:publish") ? ["artifacts:publish"] : []
12989
+ ...hasPermission6(grant.permissions, "artifacts:publish") ? ["artifacts:publish"] : []
12974
12990
  ]
12975
12991
  },
12976
12992
  ...externalContinuation ? { externalContinuation } : {}
@@ -13789,7 +13805,90 @@ function registerSessionHistoryImportRoutes(app, deps) {
13789
13805
  }
13790
13806
 
13791
13807
  // src/routes/vault-providers.ts
13808
+ import { isDeepStrictEqual } from "util";
13792
13809
  import { HTTPException as HTTPException20 } from "hono/http-exception";
13810
+
13811
+ // src/integrations/external-vault-providers.ts
13812
+ import { pinnedFetch } from "@opengeni/network";
13813
+ import { VaultProviderError } from "@opengeni/vaults";
13814
+ function createNativeExternalVaultFactories(settings, options = {}) {
13815
+ const factories = {
13816
+ keeper: keeperFactory(settings, options.keeper ?? {})
13817
+ };
13818
+ const cliPath = settings.protonPassCliPath;
13819
+ if (cliPath) factories.protonpass = protonPassFactory(cliPath, options.protonpass ?? {});
13820
+ return factories;
13821
+ }
13822
+ async function closeNativeExternalVaultProviders() {
13823
+ const pools = [...protonPools.values()];
13824
+ protonPools.clear();
13825
+ await Promise.all(pools.map(async (pool) => (await pool.catch(() => null))?.close()));
13826
+ }
13827
+ function mismatch() {
13828
+ throw new VaultProviderError(
13829
+ "provider_unavailable",
13830
+ "The configured adapter does not match this connection."
13831
+ );
13832
+ }
13833
+ function nativeKeeperFetch(settings, pinned = {}) {
13834
+ return (input, init) => pinnedFetch(input, init, settings, {
13835
+ ...pinned,
13836
+ label: "Keeper Secrets Manager",
13837
+ requireHttpsOutsideLocalTest: true
13838
+ });
13839
+ }
13840
+ function keeperFactory(settings, seams) {
13841
+ const fetch2 = nativeKeeperFetch(settings);
13842
+ return async (input) => {
13843
+ const credentials = input.credentials;
13844
+ if (credentials.provider !== "keeper") mismatch();
13845
+ const persist = input.persistCredentials;
13846
+ const { openKeeperConnection } = await import("@opengeni/vaults-keeper");
13847
+ const opened = await openKeeperConnection({
13848
+ credentials: "oneTimeToken" in credentials ? {
13849
+ oneTimeToken: credentials.oneTimeToken,
13850
+ ...credentials.hostname ? { hostname: credentials.hostname } : {}
13851
+ } : { configuration: credentials.configuration },
13852
+ // Without it openKeeperConnection refuses: a redeemed token or rotated
13853
+ // key must never live only in memory.
13854
+ ...persist ? {
13855
+ persistConfiguration: (configuration) => persist({ provider: "keeper", configuration })
13856
+ } : {},
13857
+ ...input.operations ? { operations: input.operations } : {},
13858
+ // Cancels a pending bootstrap; a stored configuration opens without a request.
13859
+ ...input.signal ? { signal: input.signal } : {},
13860
+ fetch: fetch2,
13861
+ ...seams
13862
+ });
13863
+ const stored = {
13864
+ provider: "keeper",
13865
+ configuration: opened.configuration
13866
+ };
13867
+ return { provider: opened.provider, credentials: stored };
13868
+ };
13869
+ }
13870
+ var protonPools = /* @__PURE__ */ new Map();
13871
+ function protonPassFactory(binaryPath, seams) {
13872
+ return async (input) => {
13873
+ const credentials = input.credentials;
13874
+ if (credentials.provider !== "protonpass") mismatch();
13875
+ let pool = protonPools.get(binaryPath);
13876
+ if (!pool) {
13877
+ pool = import("@opengeni/vaults-protonpass").then(
13878
+ ({ createProtonPassProviderPool }) => createProtonPassProviderPool({ ...seams, binaryPath })
13879
+ );
13880
+ protonPools.set(binaryPath, pool);
13881
+ pool.catch(() => protonPools.delete(binaryPath));
13882
+ }
13883
+ const provider = (await pool).provider(credentials.token, {
13884
+ ...input.connectionId === void 0 ? {} : { connectionId: input.connectionId },
13885
+ ...input.operations ? { operations: input.operations } : {}
13886
+ });
13887
+ return { provider, credentials: { provider: "protonpass", token: credentials.token } };
13888
+ };
13889
+ }
13890
+
13891
+ // src/routes/vault-providers.ts
13793
13892
  import {
13794
13893
  CreateManagedProviderVaultRequest,
13795
13894
  DisconnectOnePasswordResponse,
@@ -13800,15 +13899,22 @@ import {
13800
13899
  OnePasswordConnectionSummary,
13801
13900
  ProviderVaultMeta,
13802
13901
  ReplaceOnePasswordTokenRequest,
13902
+ InstallVaultProviderRequest,
13903
+ InstallVaultProviderResponse,
13904
+ ListVaultProviderConnectionsResponse,
13905
+ ReplaceVaultProviderCredentialsRequest,
13906
+ DisconnectVaultProviderResponse,
13803
13907
  VAULT_ERROR_HTTP_STATUS
13804
13908
  } from "@opengeni/contracts";
13805
13909
  import {
13806
13910
  ONEPASSWORD_CREDENTIAL_ROLE,
13807
13911
  ONEPASSWORD_PROVIDER_DOMAIN,
13808
13912
  createWorkspaceVaultProviderRegistry,
13913
+ createRemoteExternalVaultFactories,
13809
13914
  externalActorContinuationForAuthorization as externalActorContinuationForAuthorization4,
13810
- hasPermission as hasPermission6,
13915
+ hasPermission as hasPermission7,
13811
13916
  isVaultError,
13917
+ VaultError,
13812
13918
  providerSecretName,
13813
13919
  requirePermission as requirePermission2,
13814
13920
  syncLinkedProviderVault,
@@ -13820,7 +13926,15 @@ import {
13820
13926
  onePasswordConnectionMetadata,
13821
13927
  requireAccessGrantAuthorization as requireAccessGrantAuthorization4,
13822
13928
  requireEnvironmentEncryption as requireEnvironmentEncryption3,
13823
- vaultErrorCodeForProvider
13929
+ vaultErrorCodeForProvider,
13930
+ externalVaultConnectionDetails,
13931
+ externalVaultConnectionMetadata,
13932
+ externalVaultProviderDomain,
13933
+ externalVaultProviderForConnection,
13934
+ isExternalVaultConnection,
13935
+ StoredVaultProviderCredentials,
13936
+ loadExternalVaultConnection,
13937
+ pendingVaultCredentialBundle
13824
13938
  } from "@opengeni/core";
13825
13939
  import {
13826
13940
  createConnection,
@@ -13829,6 +13943,7 @@ import {
13829
13943
  getConnectionMetadata,
13830
13944
  getVault,
13831
13945
  linkProviderVault,
13946
+ preflightProviderVaultLink,
13832
13947
  listConnectionsMetadata,
13833
13948
  listVaultsForSubject,
13834
13949
  revokeConnection,
@@ -13836,7 +13951,10 @@ import {
13836
13951
  } from "@opengeni/db";
13837
13952
  import {
13838
13953
  isVaultProviderError,
13839
- VaultProviderError
13954
+ VaultProviderError as VaultProviderError2,
13955
+ createProviderCallBudget,
13956
+ listProviderVaults,
13957
+ providerOperations
13840
13958
  } from "@opengeni/vaults";
13841
13959
 
13842
13960
  // src/connection-ownership.ts
@@ -14059,8 +14177,54 @@ function vaultProviderRegistryFor(deps, input) {
14059
14177
  workspaceId: input.workspaceId,
14060
14178
  subjectId: input.subjectId,
14061
14179
  hostVaultProvider: deps.connectionCredentials?.vaultProvider ?? null,
14062
- onePasswordVaultProvider: deps.onePasswordVaultProvider === null ? null : onePasswordFactoryFor(deps)
14063
- });
14180
+ onePasswordVaultProvider: deps.onePasswordVaultProvider === null ? null : onePasswordFactoryFor(deps),
14181
+ externalVaultProviders: externalVaultFactoriesFor(deps),
14182
+ ...input.executionContext ? { executionContext: input.executionContext } : {}
14183
+ });
14184
+ }
14185
+ var defaultExternalVaultFactories = /* @__PURE__ */ new WeakMap();
14186
+ function externalVaultFactoriesFor(deps) {
14187
+ if (deps.externalVaultProviders !== void 0) return deps.externalVaultProviders ?? {};
14188
+ let factories = defaultExternalVaultFactories.get(deps);
14189
+ if (!factories) {
14190
+ factories = {
14191
+ ...createRemoteExternalVaultFactories(deps.settings),
14192
+ ...createNativeExternalVaultFactories(deps.settings)
14193
+ };
14194
+ defaultExternalVaultFactories.set(deps, factories);
14195
+ }
14196
+ return factories;
14197
+ }
14198
+ async function providerForConnection(deps, input) {
14199
+ const connection = await getConnectionMetadata(
14200
+ deps.db,
14201
+ input.workspaceId,
14202
+ input.connectionId,
14203
+ input.subjectId
14204
+ );
14205
+ if (connection && isOnePasswordConnection(connection)) {
14206
+ return { ...await onePasswordProviderForConnection(deps, input), source: "onepassword" };
14207
+ }
14208
+ if (!connection || !isExternalVaultConnection(connection) || connection.status === "revoked") {
14209
+ throw new HTTPException20(404, { message: "Vault connection not found" });
14210
+ }
14211
+ const details = externalVaultConnectionDetails(connection.metadata);
14212
+ const factory = externalVaultFactoriesFor(deps)[details.provider];
14213
+ if (!factory)
14214
+ throw new VaultProviderError2(
14215
+ "provider_unavailable",
14216
+ "This vault provider is not available in this deployment."
14217
+ );
14218
+ return {
14219
+ source: details.provider,
14220
+ provider: await externalVaultProviderForConnection({
14221
+ ...input,
14222
+ db: deps.db,
14223
+ settings: deps.settings,
14224
+ provider: details.provider,
14225
+ factory
14226
+ })
14227
+ };
14064
14228
  }
14065
14229
  function vaultContextFor(authorization, workspaceId) {
14066
14230
  return {
@@ -14075,8 +14239,8 @@ function isAccountAdmin(authorization) {
14075
14239
  }
14076
14240
  function canManageOnePasswordConnection(authorization, connection, metadata) {
14077
14241
  const { grant } = authorization;
14078
- if (!hasPermission6(grant.permissions, "connections:write", grant.permissionMode)) return false;
14079
- if (!hasPermission6(grant.permissions, "secrets:write", grant.permissionMode)) return false;
14242
+ if (!hasPermission7(grant.permissions, "connections:write", grant.permissionMode)) return false;
14243
+ if (!hasPermission7(grant.permissions, "secrets:write", grant.permissionMode)) return false;
14080
14244
  if (connection.subjectId !== null) return connection.subjectId === grant.subjectId;
14081
14245
  if (metadata.ownership === "organization") return isAccountAdmin(authorization);
14082
14246
  return true;
@@ -14132,7 +14296,7 @@ function vaultRouteError(c, error, write = false) {
14132
14296
  function findProviderVault(vaults, externalVaultId) {
14133
14297
  const found = vaults.find((vault) => vault.externalVaultId === externalVaultId);
14134
14298
  if (!found) {
14135
- throw new VaultProviderError(
14299
+ throw new VaultProviderError2(
14136
14300
  "provider_not_found",
14137
14301
  "that vault does not exist or is not shared with this connection"
14138
14302
  );
@@ -14145,7 +14309,7 @@ function registerVaultProviderRoutes(app, deps, options = {}) {
14145
14309
  const rows3 = await listVaultsForSubject(db, context, { workspaceId });
14146
14310
  return new Map(
14147
14311
  rows3.filter(
14148
- (row) => row.source === "onepassword" && row.providerConnectionId === connectionId && row.providerVaultRef
14312
+ (row) => row.source !== "opengeni" && row.providerConnectionId === connectionId && row.providerVaultRef
14149
14313
  ).map((row) => [row.providerVaultRef, row.id])
14150
14314
  );
14151
14315
  });
@@ -14181,7 +14345,7 @@ function registerVaultProviderRoutes(app, deps, options = {}) {
14181
14345
  planTier: payload.planTier,
14182
14346
  allowFakeTokens: settings.onePasswordFakeTokens
14183
14347
  });
14184
- vaults = await provider.listVaults(routeProviderContext(null));
14348
+ vaults = await listProviderVaults(provider, routeProviderContext(null));
14185
14349
  } catch (error) {
14186
14350
  return providerErrorResponse(c, error);
14187
14351
  }
@@ -14244,13 +14408,13 @@ function registerVaultProviderRoutes(app, deps, options = {}) {
14244
14408
  );
14245
14409
  const { grant } = authorization;
14246
14410
  try {
14247
- const { provider } = await onePasswordProviderForConnection(deps, {
14411
+ const { provider } = await providerForConnection(deps, {
14248
14412
  workspaceId,
14249
14413
  connectionId,
14250
14414
  subjectId: grant.subjectId
14251
14415
  });
14252
14416
  const [vaults, linked] = await Promise.all([
14253
- provider.listVaults(routeProviderContext(connectionId)),
14417
+ listProviderVaults(provider, routeProviderContext(connectionId)),
14254
14418
  linkedVaults({
14255
14419
  workspaceId,
14256
14420
  connectionId,
@@ -14263,7 +14427,9 @@ function registerVaultProviderRoutes(app, deps, options = {}) {
14263
14427
  externalVaultId: vault.externalVaultId,
14264
14428
  name: vault.name,
14265
14429
  itemCount: vault.itemCount,
14266
- linkedVaultId: linked.get(vault.externalVaultId) ?? null
14430
+ linkedVaultId: linked.get(vault.externalVaultId) ?? null,
14431
+ writeAccess: vault.writeAccess ?? "unknown",
14432
+ operations: providerOperations(provider.capabilities(), vault)
14267
14433
  })
14268
14434
  )
14269
14435
  });
@@ -14282,33 +14448,38 @@ function registerVaultProviderRoutes(app, deps, options = {}) {
14282
14448
  const context = vaultContextFor(authorization, workspaceId);
14283
14449
  try {
14284
14450
  let provider;
14285
- if (payload.provider === "onepassword") {
14451
+ if (payload.provider !== "host") {
14286
14452
  if (!payload.connectionId) {
14287
- throw new HTTPException20(422, { message: "connectionId is required for 1Password" });
14453
+ throw new HTTPException20(422, {
14454
+ message: "connectionId is required for a connected provider"
14455
+ });
14288
14456
  }
14289
- ({ provider } = await onePasswordProviderForConnection(deps, {
14457
+ const resolved = await providerForConnection(deps, {
14290
14458
  workspaceId,
14291
14459
  connectionId: payload.connectionId,
14292
14460
  subjectId: authorization.grant.subjectId
14293
- }));
14461
+ });
14462
+ if (resolved.source !== payload.provider)
14463
+ throw new HTTPException20(422, { message: "Connection provider does not match" });
14464
+ provider = resolved.provider;
14294
14465
  } else {
14295
14466
  const host = deps.connectionCredentials?.vaultProvider;
14296
14467
  if (!host) {
14297
- throw new VaultProviderError(
14468
+ throw new VaultProviderError2(
14298
14469
  "provider_unavailable",
14299
14470
  "this deployment has no host vault provider"
14300
14471
  );
14301
14472
  }
14302
14473
  provider = host;
14303
14474
  }
14304
- const connectionId = payload.provider === "onepassword" ? payload.connectionId : null;
14475
+ const connectionId = payload.provider !== "host" ? payload.connectionId : null;
14305
14476
  const providerVault = findProviderVault(
14306
- await provider.listVaults(routeProviderContext(connectionId)),
14477
+ await listProviderVaults(provider, routeProviderContext(connectionId)),
14307
14478
  payload.externalVaultId
14308
14479
  );
14309
14480
  const row = await linkProviderVault(db, context, {
14310
14481
  ownerKind: payload.ownerKind,
14311
- name: payload.name ?? providerSecretName(providerVault.name, "1Password vault"),
14482
+ name: payload.name ?? providerSecretName(providerVault.name, "Connected vault"),
14312
14483
  source: payload.provider,
14313
14484
  providerConnectionId: connectionId,
14314
14485
  providerVaultRef: providerVault.externalVaultId,
@@ -14344,7 +14515,8 @@ function registerVaultProviderRoutes(app, deps, options = {}) {
14344
14515
  providers: vaultProviderRegistryFor(deps, {
14345
14516
  workspaceId,
14346
14517
  subjectId: authorization.grant.subjectId
14347
- })
14518
+ }),
14519
+ force: true
14348
14520
  });
14349
14521
  const rateLimitedUntil = result2.status === "skipped_rate_limited" || result2.status === "failed" && result2.rateLimitedUntil ? result2.rateLimitedUntil : null;
14350
14522
  if (rateLimitedUntil) {
@@ -14368,45 +14540,100 @@ function registerVaultProviderRoutes(app, deps, options = {}) {
14368
14540
  throw new HTTPException20(403, { message: "missing permission: account:admin" });
14369
14541
  }
14370
14542
  const context = vaultContextFor(authorization, workspaceId);
14543
+ let created;
14544
+ let linked;
14545
+ let sharingFailure;
14371
14546
  try {
14547
+ const { connection, metadata } = await requireOnePasswordConnection(
14548
+ deps,
14549
+ authorization,
14550
+ workspaceId,
14551
+ connectionId
14552
+ );
14553
+ const ownership = connection.subjectId !== null ? "user" : metadata.ownership;
14554
+ if (ownership !== payload.ownerKind || ownership === "user" && connection.subjectId !== authorization.grant.subjectId) {
14555
+ throw new VaultError(
14556
+ "vault_permission_denied",
14557
+ `A ${ownership} 1Password connection backs only ${ownership} vaults`,
14558
+ { connectionId, connectionOwnership: ownership, ownerKind: payload.ownerKind }
14559
+ );
14560
+ }
14561
+ const link = {
14562
+ ownerKind: payload.ownerKind,
14563
+ name: payload.name,
14564
+ source: "onepassword",
14565
+ providerConnectionId: connectionId,
14566
+ mode: "read_write",
14567
+ allowOrganization: isAccountAdmin(authorization)
14568
+ };
14569
+ await preflightProviderVaultLink(db, context, link);
14372
14570
  const { provider } = await onePasswordProviderForConnection(deps, {
14373
14571
  workspaceId,
14374
14572
  connectionId,
14375
14573
  subjectId: authorization.grant.subjectId
14376
14574
  });
14377
14575
  if (!provider.createVault || !provider.capabilities().createVault) {
14378
- throw new VaultProviderError(
14576
+ throw new VaultProviderError2(
14379
14577
  "provider_unavailable",
14380
14578
  "this 1Password connection cannot create vaults"
14381
14579
  );
14382
14580
  }
14383
- const created = await provider.createVault(routeProviderContext(connectionId), {
14384
- name: payload.name,
14385
- description: "Managed by Opengeni",
14386
- allowAdminsAccess: true,
14387
- ...payload.groupId ? { groupId: payload.groupId } : {}
14388
- });
14389
- const row = await linkProviderVault(db, context, {
14390
- ownerKind: payload.ownerKind,
14391
- name: payload.name,
14392
- source: "onepassword",
14393
- providerConnectionId: connectionId,
14394
- providerVaultRef: created.externalVaultId,
14395
- mode: "read_write",
14396
- allowOrganization: isAccountAdmin(authorization)
14581
+ const { OnePasswordVaultCreatedError } = await loadOnePasswordModule();
14582
+ try {
14583
+ created = await provider.createVault(routeProviderContext(connectionId), {
14584
+ name: payload.name,
14585
+ description: "Managed by Opengeni",
14586
+ allowAdminsAccess: true,
14587
+ ...payload.groupId ? { groupId: payload.groupId } : {}
14588
+ });
14589
+ } catch (error) {
14590
+ if (error instanceof OnePasswordVaultCreatedError) {
14591
+ created = error.createdVault;
14592
+ sharingFailure = error;
14593
+ } else if (isVaultProviderError(error)) {
14594
+ throw error;
14595
+ } else {
14596
+ throw new VaultProviderError2(
14597
+ "provider_outcome_unknown",
14598
+ "1Password did not confirm vault creation; it may have been applied. Check the connection's vault list before creating again."
14599
+ );
14600
+ }
14601
+ }
14602
+ linked = await linkProviderVault(db, context, {
14603
+ ...link,
14604
+ providerVaultRef: created.externalVaultId
14397
14605
  });
14398
14606
  await syncLinkedProviderVault({
14399
14607
  db,
14400
14608
  context,
14401
- vaultId: row.id,
14609
+ vaultId: linked.id,
14402
14610
  providers: vaultProviderRegistryFor(deps, {
14403
14611
  workspaceId,
14404
14612
  subjectId: authorization.grant.subjectId
14405
14613
  }),
14406
14614
  force: true
14407
14615
  });
14408
- return c.json(await vaultSummaryFor(deps, authorization, workspaceId, row.id), 201);
14616
+ if (sharingFailure) throw sharingFailure;
14617
+ return c.json(await vaultSummaryFor(deps, authorization, workspaceId, linked.id), 201);
14409
14618
  } catch (error) {
14619
+ if (created) {
14620
+ const local = isVaultError(error) ? error : vaultErrorFromDatabase(error);
14621
+ const code = local?.code ?? (isVaultProviderError(error) ? vaultErrorCodeForProvider(error.code, "write") : "provider_unavailable");
14622
+ const message = linked ? sharingFailure ? "The vault was created and linked, but its group access could not be confirmed. Check sharing in 1Password. Do not create it again." : "The vault was created and linked, but its refresh could not be confirmed. Refresh the linked vault. Do not create it again." : "The vault was created in 1Password, but its local link could not be confirmed. Use Link on the existing provider vault after resolving the local refusal. Do not create it again.";
14623
+ return vaultRouteError(
14624
+ c,
14625
+ new VaultError(code, message, {
14626
+ created: true,
14627
+ // A lost DB acknowledgement is not proof that the link rolled back.
14628
+ linked: linked ? true : local ? false : null,
14629
+ connectionId,
14630
+ externalVaultId: created.externalVaultId,
14631
+ ...linked ? { vaultId: linked.id } : {},
14632
+ ...sharingFailure ? { groupGrantConfirmed: false } : {}
14633
+ }),
14634
+ true
14635
+ );
14636
+ }
14410
14637
  return vaultRouteError(c, error, true);
14411
14638
  }
14412
14639
  });
@@ -14472,7 +14699,7 @@ function registerVaultProviderRoutes(app, deps, options = {}) {
14472
14699
  planTier,
14473
14700
  allowFakeTokens: settings.onePasswordFakeTokens
14474
14701
  });
14475
- vaults = await provider.listVaults(routeProviderContext(connectionId));
14702
+ vaults = await listProviderVaults(provider, routeProviderContext(connectionId));
14476
14703
  } catch (error) {
14477
14704
  return providerErrorResponse(c, error);
14478
14705
  }
@@ -14578,10 +14805,515 @@ function registerVaultProviderRoutes(app, deps, options = {}) {
14578
14805
  }
14579
14806
  return c.json(DisconnectOnePasswordResponse.parse({ unlinkedVaultIds }));
14580
14807
  });
14808
+ app.get("/v1/workspaces/:workspaceId/vault-providers/connections", async (c) => {
14809
+ const workspaceId = c.req.param("workspaceId");
14810
+ const authorization = await requireAccessGrantAuthorization4(
14811
+ c,
14812
+ deps,
14813
+ workspaceId,
14814
+ "secrets:list"
14815
+ );
14816
+ const factories = externalVaultFactoriesFor(deps);
14817
+ const rows3 = await listConnectionsMetadata(db, workspaceId, authorization.grant.subjectId);
14818
+ const connections = rows3.filter((row) => row.status !== "revoked").flatMap((row) => {
14819
+ if (isOnePasswordConnection(row)) {
14820
+ return [
14821
+ {
14822
+ ...onePasswordConnectionSummary(authorization, row),
14823
+ provider: "onepassword",
14824
+ // The published legacy 1Password port has no granular override.
14825
+ operations: providerOperations({
14826
+ write: true,
14827
+ createVault: true,
14828
+ totp: true,
14829
+ files: false,
14830
+ groupGrants: true,
14831
+ passkeys: false
14832
+ }),
14833
+ available: deps.onePasswordVaultProvider !== null
14834
+ }
14835
+ ];
14836
+ }
14837
+ if (!isExternalVaultConnection(row)) return [];
14838
+ const details = externalVaultConnectionDetails(row.metadata);
14839
+ return [
14840
+ {
14841
+ id: row.id,
14842
+ provider: details.provider,
14843
+ ownership: details.ownership,
14844
+ accountName: details.accountName,
14845
+ label: details.label,
14846
+ verifiedAt: details.verifiedAt,
14847
+ createdAt: row.createdAt,
14848
+ createdBySubjectId: row.createdBySubjectId,
14849
+ canManage: canManageExternal(authorization, row, details),
14850
+ operations: details.operations,
14851
+ available: Boolean(factories[details.provider]),
14852
+ verificationStatus: details.verificationStatus ?? "ready"
14853
+ }
14854
+ ];
14855
+ });
14856
+ const providers = ["onepassword", "external", "protonpass", "keeper", "bitwarden"].map((provider) => {
14857
+ const available = provider === "onepassword" ? deps.onePasswordVaultProvider !== null : Boolean(factories[provider]);
14858
+ return { provider, available, reason: available ? null : "not_enabled" };
14859
+ });
14860
+ return c.json(ListVaultProviderConnectionsResponse.parse({ connections, providers }));
14861
+ });
14862
+ app.post("/v1/workspaces/:workspaceId/vault-providers/connections", async (c) => {
14863
+ const workspaceId = c.req.param("workspaceId");
14864
+ const authorization = await requireSetupAuthority(c, workspaceId);
14865
+ const { grant } = authorization;
14866
+ const payload = await parseRequestJson(c, InstallVaultProviderRequest);
14867
+ requireOwnership(authorization, payload.ownership);
14868
+ const key2 = requireEnvironmentEncryption3(settings);
14869
+ if (!externalVaultFactoriesFor(deps)[payload.credentials.provider]) {
14870
+ return vaultRouteError(
14871
+ c,
14872
+ new VaultProviderError2(
14873
+ "provider_unavailable",
14874
+ "This vault provider is not available in this deployment."
14875
+ )
14876
+ );
14877
+ }
14878
+ const details = {
14879
+ version: 1,
14880
+ provider: payload.credentials.provider,
14881
+ ownership: payload.ownership,
14882
+ accountId: null,
14883
+ accountName: null,
14884
+ label: payload.label ?? null,
14885
+ verifiedAt: (/* @__PURE__ */ new Date()).toISOString(),
14886
+ verificationStatus: "pending",
14887
+ operations: providerOperations({
14888
+ write: false,
14889
+ createVault: false,
14890
+ totp: false,
14891
+ files: false,
14892
+ groupGrants: false,
14893
+ passkeys: false
14894
+ })
14895
+ };
14896
+ const continuation = externalActorContinuationForAuthorization4(authorization);
14897
+ const connection = await db.transaction(async (tx) => {
14898
+ await requireConnectOwnerAuthority(tx, {
14899
+ accountId: grant.accountId,
14900
+ workspaceId,
14901
+ subjectId: grant.subjectId,
14902
+ personalOwnerVerified: isPersonalConnectionOwnerPrincipal(authorization),
14903
+ ...continuation ? { externalContinuation: continuation } : {}
14904
+ });
14905
+ return createConnection(tx, {
14906
+ accountId: grant.accountId,
14907
+ workspaceId,
14908
+ subjectId: payload.ownership === "user" ? grant.subjectId : null,
14909
+ providerDomain: externalVaultProviderDomain(details.provider),
14910
+ kind: "api_key",
14911
+ status: "needs_reauth",
14912
+ credentialEncrypted: encryptEnvironmentValue2(key2, "{}"),
14913
+ grantedScopes: [],
14914
+ expiresAt: null,
14915
+ metadata: externalVaultConnectionMetadata(details),
14916
+ createdBySubjectId: grant.subjectId
14917
+ });
14918
+ });
14919
+ try {
14920
+ const result2 = await finishExternalSetup({
14921
+ authorization,
14922
+ workspaceId,
14923
+ connection,
14924
+ credentials: payload.credentials,
14925
+ currentCredentials: null,
14926
+ isNew: true
14927
+ });
14928
+ return c.json(result2.body, result2.status);
14929
+ } catch (error) {
14930
+ return vaultRouteError(c, error);
14931
+ }
14932
+ });
14933
+ app.put(
14934
+ "/v1/workspaces/:workspaceId/vault-providers/connections/:connectionId/credentials",
14935
+ async (c) => {
14936
+ const workspaceId = c.req.param("workspaceId");
14937
+ const connectionId = c.req.param("connectionId");
14938
+ const authorization = await requireSetupAuthority(c, workspaceId);
14939
+ const { grant } = authorization;
14940
+ const connection = await getConnectionMetadata(
14941
+ db,
14942
+ workspaceId,
14943
+ connectionId,
14944
+ grant.subjectId
14945
+ );
14946
+ if (!connection || !isExternalVaultConnection(connection) || connection.status === "revoked") {
14947
+ throw new HTTPException20(404, { message: "Vault connection not found" });
14948
+ }
14949
+ const details = externalVaultConnectionDetails(connection.metadata);
14950
+ if (!canManageExternal(authorization, connection, details))
14951
+ throw new HTTPException20(403, { message: "You cannot change this vault connection" });
14952
+ requireOwnership(authorization, details.ownership);
14953
+ const payload = await parseRequestJson(c, ReplaceVaultProviderCredentialsRequest);
14954
+ if (payload.credentials.provider !== details.provider)
14955
+ throw new HTTPException20(422, { message: "Connection provider does not match" });
14956
+ try {
14957
+ const loaded = await loadExternalVaultConnection(db, settings, {
14958
+ workspaceId,
14959
+ connectionId,
14960
+ subjectId: grant.subjectId,
14961
+ provider: details.provider,
14962
+ allowPendingVerification: true
14963
+ });
14964
+ const result2 = await finishExternalSetup({
14965
+ authorization,
14966
+ workspaceId,
14967
+ connection: loaded.connection,
14968
+ credentials: payload.credentials,
14969
+ currentCredentials: loaded.currentCredentials,
14970
+ pendingCredentials: loaded.pendingCredentials,
14971
+ isNew: false
14972
+ });
14973
+ return c.json(result2.body, result2.status);
14974
+ } catch (error) {
14975
+ return vaultRouteError(c, error);
14976
+ }
14977
+ }
14978
+ );
14979
+ app.post(
14980
+ "/v1/workspaces/:workspaceId/vault-providers/connections/:connectionId/verify",
14981
+ async (c) => {
14982
+ const workspaceId = c.req.param("workspaceId");
14983
+ const connectionId = c.req.param("connectionId");
14984
+ const authorization = await requireSetupAuthority(c, workspaceId);
14985
+ const connection = await getConnectionMetadata(
14986
+ db,
14987
+ workspaceId,
14988
+ connectionId,
14989
+ authorization.grant.subjectId
14990
+ );
14991
+ if (!connection || !isExternalVaultConnection(connection) || connection.status === "revoked")
14992
+ throw new HTTPException20(404, { message: "Vault connection not found" });
14993
+ const details = externalVaultConnectionDetails(connection.metadata);
14994
+ if (!canManageExternal(authorization, connection, details))
14995
+ throw new HTTPException20(403, { message: "You cannot verify this vault connection" });
14996
+ requireOwnership(authorization, details.ownership);
14997
+ try {
14998
+ const loaded = await loadExternalVaultConnection(db, settings, {
14999
+ workspaceId,
15000
+ connectionId,
15001
+ subjectId: authorization.grant.subjectId,
15002
+ provider: details.provider,
15003
+ allowPendingVerification: true
15004
+ });
15005
+ const result2 = await finishExternalSetup({
15006
+ authorization,
15007
+ workspaceId,
15008
+ connection: loaded.connection,
15009
+ credentials: loaded.credentials,
15010
+ currentCredentials: loaded.currentCredentials,
15011
+ pendingCredentials: loaded.pendingCredentials,
15012
+ isNew: false
15013
+ });
15014
+ return c.json(result2.body, result2.status);
15015
+ } catch (error) {
15016
+ return vaultRouteError(c, error);
15017
+ }
15018
+ }
15019
+ );
15020
+ app.delete("/v1/workspaces/:workspaceId/vault-providers/connections/:connectionId", async (c) => {
15021
+ const workspaceId = c.req.param("workspaceId");
15022
+ const connectionId = c.req.param("connectionId");
15023
+ const authorization = await requireSetupAuthority(c, workspaceId);
15024
+ const { grant } = authorization;
15025
+ const connection = await getConnectionMetadata(db, workspaceId, connectionId, grant.subjectId);
15026
+ if (!connection || connection.status === "revoked")
15027
+ throw new HTTPException20(404, { message: "Vault connection not found" });
15028
+ if (isOnePasswordConnection(connection)) {
15029
+ requireManageOnePasswordConnection(
15030
+ authorization,
15031
+ connection,
15032
+ onePasswordConnectionMetadata(connection.metadata)
15033
+ );
15034
+ } else {
15035
+ const details = externalVaultConnectionDetails(connection.metadata);
15036
+ if (!details || !isExternalVaultConnection(connection))
15037
+ throw new HTTPException20(404, { message: "Vault connection not found" });
15038
+ if (!canManageExternal(authorization, connection, details))
15039
+ throw new HTTPException20(403, { message: "You cannot disconnect this vault connection" });
15040
+ }
15041
+ try {
15042
+ const unlinkedVaultIds = await db.transaction(async (tx) => {
15043
+ const context = vaultContextFor(authorization, workspaceId);
15044
+ const rows3 = await listVaultsForSubject(tx, context, { workspaceId });
15045
+ const unlinked = [];
15046
+ for (const row of rows3.filter(
15047
+ (candidate) => candidate.providerConnectionId === connectionId
15048
+ )) {
15049
+ await deleteVault(tx, context, {
15050
+ vaultId: row.id,
15051
+ confirmName: row.name,
15052
+ allowOrganization: isAccountAdmin(authorization)
15053
+ });
15054
+ unlinked.push(row.id);
15055
+ }
15056
+ const revoked = await revokeConnection(
15057
+ tx,
15058
+ workspaceId,
15059
+ connectionId,
15060
+ grant.subjectId,
15061
+ connection.version
15062
+ );
15063
+ if (!revoked)
15064
+ throw new HTTPException20(409, {
15065
+ message: "This vault connection changed. Reload it before disconnecting."
15066
+ });
15067
+ return unlinked;
15068
+ });
15069
+ return c.json(DisconnectVaultProviderResponse.parse({ unlinkedVaultIds }));
15070
+ } catch (error) {
15071
+ return vaultRouteError(c, error);
15072
+ }
15073
+ });
15074
+ async function requireSetupAuthority(c, workspaceId) {
15075
+ const authorization = await requireAccessGrantAuthorization4(
15076
+ c,
15077
+ deps,
15078
+ workspaceId,
15079
+ "connections:write"
15080
+ );
15081
+ requirePermission2(authorization.grant, "secrets:write");
15082
+ return authorization;
15083
+ }
15084
+ function requireOwnership(authorization, ownership) {
15085
+ if (ownership === "organization" && !isAccountAdmin(authorization))
15086
+ throw new HTTPException20(403, { message: "missing permission: account:admin" });
15087
+ if (ownership === "user" && !isPersonalConnectionOwnerPrincipal(authorization))
15088
+ throw new HTTPException20(403, {
15089
+ message: "Only a signed-in person can manage a personal vault connection"
15090
+ });
15091
+ }
15092
+ function canManageExternal(authorization, connection, details) {
15093
+ const grant = authorization.grant;
15094
+ return hasPermission7(grant.permissions, "connections:write", grant.permissionMode) && hasPermission7(grant.permissions, "secrets:write", grant.permissionMode) && (connection.subjectId !== null ? connection.subjectId === grant.subjectId && isPersonalConnectionOwnerPrincipal(authorization) : details.ownership !== "organization" || isAccountAdmin(authorization));
15095
+ }
15096
+ function catalogVault(provider, vault, linkedVaultId) {
15097
+ return {
15098
+ externalVaultId: vault.externalVaultId,
15099
+ name: vault.name,
15100
+ itemCount: vault.itemCount,
15101
+ linkedVaultId,
15102
+ writeAccess: vault.writeAccess ?? "unknown",
15103
+ operations: providerOperations(provider.capabilities(), vault)
15104
+ };
15105
+ }
15106
+ async function finishExternalSetup(input) {
15107
+ const { authorization, workspaceId } = input;
15108
+ const { grant } = authorization;
15109
+ const key2 = requireEnvironmentEncryption3(settings);
15110
+ const details = externalVaultConnectionDetails(input.connection.metadata);
15111
+ const context = vaultContextFor(authorization, workspaceId);
15112
+ const linked = await linkedVaultRows(context, workspaceId, input.connection.id);
15113
+ let connection = input.connection;
15114
+ let saved = false;
15115
+ let hasPending = Boolean(input.pendingCredentials);
15116
+ let rejectedAccount;
15117
+ let storedBundle = input.pendingCredentials ? pendingVaultCredentialBundle(input.currentCredentials, input.pendingCredentials) : input.currentCredentials ?? {};
15118
+ const continuation = externalActorContinuationForAuthorization4(authorization);
15119
+ const persist = async (credentials, ready) => {
15120
+ const unchangedCurrent = input.currentCredentials !== null && isDeepStrictEqual(credentials, input.currentCredentials);
15121
+ const pending2 = !ready && !unchangedCurrent;
15122
+ const nextMetadata = ready ?? {
15123
+ ...details,
15124
+ verificationStatus: pending2 ? "pending" : "ready"
15125
+ };
15126
+ const nextBundle = pending2 ? pendingVaultCredentialBundle(input.currentCredentials, credentials) : credentials;
15127
+ const nextStatus = pending2 ? connection.status : "active";
15128
+ const previousDetails = externalVaultConnectionDetails(connection.metadata);
15129
+ const generationChanged = !isDeepStrictEqual(nextBundle, storedBundle) || nextStatus !== connection.status || !isDeepStrictEqual(previousDetails?.operations, nextMetadata.operations);
15130
+ if (!generationChanged && isDeepStrictEqual(previousDetails, nextMetadata)) {
15131
+ saved = true;
15132
+ hasPending = pending2;
15133
+ return;
15134
+ }
15135
+ const updated = await db.transaction(async (tx) => {
15136
+ await requireConnectOwnerAuthority(tx, {
15137
+ accountId: grant.accountId,
15138
+ workspaceId,
15139
+ subjectId: grant.subjectId,
15140
+ personalOwnerVerified: isPersonalConnectionOwnerPrincipal(authorization),
15141
+ ...continuation ? { externalContinuation: continuation } : {}
15142
+ });
15143
+ return updateConnection(tx, {
15144
+ workspaceId,
15145
+ connectionId: connection.id,
15146
+ visibleToSubjectId: grant.subjectId,
15147
+ expectedVersion: connection.version,
15148
+ status: nextStatus,
15149
+ ...generationChanged ? { credentialEncrypted: encryptEnvironmentValue2(key2, JSON.stringify(nextBundle)) } : {},
15150
+ metadata: { ...connection.metadata, ...externalVaultConnectionMetadata(nextMetadata) },
15151
+ updatedBySubjectId: grant.subjectId
15152
+ });
15153
+ });
15154
+ if (!updated)
15155
+ throw new HTTPException20(409, {
15156
+ message: "This vault connection changed. Reload it before continuing setup."
15157
+ });
15158
+ connection = updated;
15159
+ saved = true;
15160
+ hasPending = pending2;
15161
+ storedBundle = nextBundle;
15162
+ };
15163
+ try {
15164
+ const checked = await prepareExternal(
15165
+ input.credentials,
15166
+ authorization,
15167
+ workspaceId,
15168
+ connection.id,
15169
+ persist
15170
+ );
15171
+ const sameAccount = details.accountId !== null ? checked.accountId === details.accountId : linked.length === 0 || linked.every(
15172
+ (row) => checked.vaults.some((vault) => vault.externalVaultId === row.providerVaultRef)
15173
+ );
15174
+ if (!sameAccount) {
15175
+ rejectedAccount = new VaultProviderError2(
15176
+ "provider_conflict",
15177
+ "These credentials do not reach the same account and linked vaults. Connect them separately instead."
15178
+ );
15179
+ throw rejectedAccount;
15180
+ }
15181
+ const ready = {
15182
+ ...details,
15183
+ accountId: checked.accountId ?? details.accountId,
15184
+ accountName: checked.accountName,
15185
+ operations: checked.operations,
15186
+ verifiedAt: (/* @__PURE__ */ new Date()).toISOString(),
15187
+ verificationStatus: "ready"
15188
+ };
15189
+ await persist(checked.credentials, ready);
15190
+ const providers = vaultProviderRegistryFor(deps, { workspaceId, subjectId: grant.subjectId });
15191
+ for (const row of linked) {
15192
+ await syncLinkedProviderVault({
15193
+ db,
15194
+ context,
15195
+ vaultId: row.id,
15196
+ providers,
15197
+ force: true
15198
+ }).catch(() => void 0);
15199
+ }
15200
+ const linkedIds = new Map(linked.map((row) => [row.providerVaultRef, row.id]));
15201
+ return {
15202
+ status: input.isNew ? 201 : 200,
15203
+ body: InstallVaultProviderResponse.parse({
15204
+ connectionId: connection.id,
15205
+ provider: details.provider,
15206
+ accountName: ready.accountName,
15207
+ operations: ready.operations,
15208
+ vaults: checked.vaults.map(
15209
+ (vault) => catalogVault(checked.provider, vault, linkedIds.get(vault.externalVaultId) ?? null)
15210
+ )
15211
+ })
15212
+ };
15213
+ } catch (error) {
15214
+ if (rejectedAccount && error === rejectedAccount && hasPending) {
15215
+ if (input.currentCredentials) {
15216
+ await persist(input.currentCredentials, { ...details, verificationStatus: "ready" });
15217
+ } else {
15218
+ await revokeConnection(
15219
+ db,
15220
+ workspaceId,
15221
+ connection.id,
15222
+ grant.subjectId,
15223
+ connection.version
15224
+ );
15225
+ }
15226
+ throw error;
15227
+ }
15228
+ if (saved && hasPending && isVaultProviderError(error)) {
15229
+ return {
15230
+ status: 202,
15231
+ body: InstallVaultProviderResponse.parse({
15232
+ connectionId: connection.id,
15233
+ provider: details.provider,
15234
+ accountName: details.accountName,
15235
+ operations: details.operations,
15236
+ vaults: [],
15237
+ discoveryPending: true,
15238
+ errorCode: error.code
15239
+ })
15240
+ };
15241
+ }
15242
+ if (!saved && input.isNew) {
15243
+ await revokeConnection(db, workspaceId, connection.id, grant.subjectId, connection.version);
15244
+ }
15245
+ throw error;
15246
+ }
15247
+ }
15248
+ async function prepareExternal(credentials, authorization, workspaceId, connectionId, persistCredentials) {
15249
+ const factory = externalVaultFactoriesFor(deps)[credentials.provider];
15250
+ if (!factory)
15251
+ throw new VaultProviderError2(
15252
+ "provider_unavailable",
15253
+ "This vault provider is not available in this deployment."
15254
+ );
15255
+ let rotated;
15256
+ const signal = AbortSignal.timeout(3e4);
15257
+ const prepared = await factory({
15258
+ credentials,
15259
+ ...connectionId ? { connectionId } : {},
15260
+ signal,
15261
+ persistCredentials: async (next) => {
15262
+ const parsed = StoredVaultProviderCredentials.safeParse(next);
15263
+ if (!parsed.success || parsed.data.provider !== credentials.provider)
15264
+ throw new VaultProviderError2(
15265
+ "provider_unavailable",
15266
+ "The provider returned invalid connection state."
15267
+ );
15268
+ rotated = parsed.data;
15269
+ await persistCredentials(parsed.data);
15270
+ }
15271
+ });
15272
+ if (prepared.provider.id !== credentials.provider)
15273
+ throw new VaultProviderError2(
15274
+ "provider_unavailable",
15275
+ "The configured adapter does not match this connection."
15276
+ );
15277
+ const preparedCredentials = StoredVaultProviderCredentials.safeParse(prepared.credentials);
15278
+ if (!preparedCredentials.success || preparedCredentials.data.provider !== credentials.provider)
15279
+ throw new VaultProviderError2(
15280
+ "provider_unavailable",
15281
+ "The provider returned invalid connection state."
15282
+ );
15283
+ if (!rotated) await persistCredentials(preparedCredentials.data);
15284
+ const ctx = {
15285
+ connectionId,
15286
+ budget: createProviderCallBudget(50),
15287
+ signal,
15288
+ forceRefresh: true,
15289
+ authority: {
15290
+ accountId: authorization.grant.accountId,
15291
+ workspaceId,
15292
+ connectionWorkspaceId: workspaceId,
15293
+ subjectId: authorization.grant.subjectId
15294
+ }
15295
+ };
15296
+ const validated = await prepared.provider.validate(ctx);
15297
+ const vaults = await listProviderVaults(prepared.provider, ctx);
15298
+ const stored = StoredVaultProviderCredentials.safeParse(rotated ?? prepared.credentials);
15299
+ if (!stored.success || stored.data.provider !== credentials.provider)
15300
+ throw new VaultProviderError2(
15301
+ "provider_unavailable",
15302
+ "The provider returned invalid connection state."
15303
+ );
15304
+ return {
15305
+ provider: prepared.provider,
15306
+ credentials: stored.data,
15307
+ vaults,
15308
+ accountId: validated.accountId ?? null,
15309
+ accountName: validated.accountName,
15310
+ operations: providerOperations(prepared.provider.capabilities())
15311
+ };
15312
+ }
14581
15313
  async function linkedVaultRows(context, workspaceId, connectionId) {
14582
15314
  const rows3 = await listVaultsForSubject(db, context, { workspaceId });
14583
15315
  return rows3.filter(
14584
- (row) => row.source === "onepassword" && row.providerConnectionId === connectionId && row.providerVaultRef !== null
15316
+ (row) => row.source !== "opengeni" && row.providerConnectionId === connectionId && row.providerVaultRef !== null
14585
15317
  );
14586
15318
  }
14587
15319
  }
@@ -15017,12 +15749,12 @@ import {
15017
15749
  } from "@opengeni/contracts";
15018
15750
  import {
15019
15751
  encryptEnvironmentValue as encryptEnvironmentValue3,
15020
- VaultError
15752
+ VaultError as VaultError2
15021
15753
  } from "@opengeni/db";
15022
15754
  function encrypted(key2, plaintext) {
15023
15755
  const valueSize = Buffer.byteLength(plaintext, "utf8");
15024
15756
  if (valueSize > VAULT_LIMITS.textValueMaxBytes) {
15025
- throw new VaultError(
15757
+ throw new VaultError2(
15026
15758
  "secret_value_too_large",
15027
15759
  `the value is larger than ${VAULT_LIMITS.textValueMaxBytes} bytes`,
15028
15760
  { limit: VAULT_LIMITS.textValueMaxBytes }
@@ -15039,7 +15771,7 @@ function prepareSecretAnswers(settings, answers, source) {
15039
15771
  }
15040
15772
  const key2 = environmentsEncryptionKeyBytes3(settings);
15041
15773
  if (!key2) {
15042
- throw new VaultError(
15774
+ throw new VaultError2(
15043
15775
  "encryption_key_missing",
15044
15776
  "vaults require OPENGENI_ENVIRONMENTS_ENCRYPTION_KEY"
15045
15777
  );
@@ -15087,12 +15819,12 @@ import { isVaultError as isVaultError3, vaultErrorFromDatabase as vaultErrorFrom
15087
15819
  // src/mcp/first-party-tool-permissions.ts
15088
15820
  import {
15089
15821
  FIRST_PARTY_TOOL_AUTHORIZATION,
15090
- permissionsRequiredByFirstPartyTools
15822
+ permissionsRequiredByFirstPartyTools as permissionsRequiredByFirstPartyTools2
15091
15823
  } from "@opengeni/contracts";
15092
15824
 
15093
15825
  // src/mcp/server.ts
15094
15826
  import {
15095
- hasPermission as hasPermission10,
15827
+ hasPermission as hasPermission11,
15096
15828
  authorizedSocialConnectionsForGrant,
15097
15829
  buildCapabilityCatalog,
15098
15830
  CONNECTED_MACHINE_CAPABILITY_ID,
@@ -15316,10 +16048,10 @@ async function listWorkspaceGitHubRepositoryBranches(deps, input, services = wor
15316
16048
  }
15317
16049
 
15318
16050
  // src/github-browser-flow.ts
15319
- import { hasPermission as hasPermission7 } from "@opengeni/core";
16051
+ import { hasPermission as hasPermission8 } from "@opengeni/core";
15320
16052
  var githubBrowserGrantMaxAgeSeconds = 10 * 60;
15321
16053
  function githubBrowserGrantClaims(settings, grant, nowSeconds = Math.floor(Date.now() / 1e3)) {
15322
- if (settings.productAccessMode !== "configured" || !hasPermission7(grant.permissions, "github:manage")) {
16054
+ if (settings.productAccessMode !== "configured" || !hasPermission8(grant.permissions, "github:manage")) {
15323
16055
  return {};
15324
16056
  }
15325
16057
  return {
@@ -16057,7 +16789,7 @@ async function withChannelAOperation(services, ctx, readOnly, fn) {
16057
16789
  hasGitHubRepositorySelection(session.resources) ? githubAppBotIdentity(settings) : null
16058
16790
  );
16059
16791
  }
16060
- const runEstablished = async (routed, lease, homeSession) => {
16792
+ const runEstablished = async (routed, lease, homeSession, pinnedMachine = null) => {
16061
16793
  const emit = async (events) => {
16062
16794
  await appendAndPublishEvents2(
16063
16795
  db,
@@ -16088,6 +16820,7 @@ async function withChannelAOperation(services, ctx, readOnly, fn) {
16088
16820
  homeSession,
16089
16821
  routingSession,
16090
16822
  machineAuthority,
16823
+ pinnedMachine,
16091
16824
  requestId
16092
16825
  });
16093
16826
  await routingSession.finalizeOpStreamOps().catch(() => void 0);
@@ -16176,6 +16909,7 @@ async function withChannelAOperation(services, ctx, readOnly, fn) {
16176
16909
  operationResourcePolicySupported: enrollment.agentCapabilities.operationResourcePolicy === true,
16177
16910
  operationCpuQuotaSupported: enrollment.agentCapabilities.operationCpuQuota === true,
16178
16911
  transactionalFsWriteSupported: enrollment.agentCapabilities.transactionalFsWrite === true,
16912
+ browserControlHttpSupported: enrollment.agentCapabilities.browserControlHttp === true,
16179
16913
  ...settings.agentOpStreamEnabled === true && enrollment?.opStream === true && bus.getOpStreamConnection ? {
16180
16914
  opStream: {
16181
16915
  transport: new NatsOpStreamTransport(
@@ -16214,7 +16948,11 @@ async function withChannelAOperation(services, ctx, readOnly, fn) {
16214
16948
  },
16215
16949
  established2
16216
16950
  );
16217
- return await runEstablished(routed, null, established2.session);
16951
+ return await runEstablished(routed, null, established2.session, {
16952
+ sandboxId: sandbox.id,
16953
+ sandboxWorkspaceId: originWorkspaceId,
16954
+ enrollment
16955
+ });
16218
16956
  } catch (error) {
16219
16957
  observeChannelAOperationFailure(services, {
16220
16958
  workspaceId,
@@ -17934,7 +18672,7 @@ async function projectWorkspaceArtifactMutationProvenance(response, canReadSessi
17934
18672
  }
17935
18673
 
17936
18674
  // src/integrations/social-api.ts
17937
- import { OAUTH_MAX_RESPONSE_BYTES as OAUTH_MAX_RESPONSE_BYTES4, pinnedFetch as pinnedFetch3, readResponseJsonBounded as readResponseJsonBounded3 } from "@opengeni/network";
18675
+ import { OAUTH_MAX_RESPONSE_BYTES as OAUTH_MAX_RESPONSE_BYTES4, pinnedFetch as pinnedFetch4, readResponseJsonBounded as readResponseJsonBounded3 } from "@opengeni/network";
17938
18676
 
17939
18677
  // src/integrations/social-oauth.ts
17940
18678
  import { withOrganizationIntegrationAcquisition as withOrganizationIntegrationAcquisition2 } from "@opengeni/db/organization-integration-policy";
@@ -18002,7 +18740,7 @@ import {
18002
18740
  RequestDeadlineError,
18003
18741
  isLocalTestEnvironment,
18004
18742
  parseMcpOAuthChallenge,
18005
- pinnedFetch,
18743
+ pinnedFetch as pinnedFetch2,
18006
18744
  readResponseJsonBounded,
18007
18745
  resolveMcpOAuthDiscovery,
18008
18746
  validateHttpUrl
@@ -20425,7 +21163,7 @@ async function fetchOAuth(rawUrl, settings, init = {}, hop = 0) {
20425
21163
  let response;
20426
21164
  try {
20427
21165
  const endpoint = oauthEndpointUrl(rawUrl, settings, "OAuth endpoint");
20428
- response = await pinnedFetch(endpoint, init, settings, {
21166
+ response = await pinnedFetch2(endpoint, init, settings, {
20429
21167
  label: "OAuth discovery",
20430
21168
  requireHttpsOutsideLocalTest: true
20431
21169
  });
@@ -20559,7 +21297,7 @@ import { parseSocialOauthClientsJson } from "@opengeni/config";
20559
21297
  import {
20560
21298
  OAuthStartResponse as OAuthStartResponse2
20561
21299
  } from "@opengeni/contracts";
20562
- import { hasPermission as hasPermission8, requireEnvironmentEncryption as requireEnvironmentEncryption5 } from "@opengeni/core";
21300
+ import { hasPermission as hasPermission9, requireEnvironmentEncryption as requireEnvironmentEncryption5 } from "@opengeni/core";
20563
21301
  import {
20564
21302
  consumeIntegrationOAuthStateNonce as consumeIntegrationOAuthStateNonce2,
20565
21303
  decryptEnvironmentValue as decryptEnvironmentValue2,
@@ -20572,7 +21310,7 @@ import {
20572
21310
  getConnectAttempt as getConnectAttempt2
20573
21311
  } from "@opengeni/db";
20574
21312
  import { createSignedState as createSignedState3, readSignedState as readSignedState3 } from "@opengeni/github";
20575
- import { OAUTH_MAX_RESPONSE_BYTES as OAUTH_MAX_RESPONSE_BYTES3, pinnedFetch as pinnedFetch2, readResponseJsonBounded as readResponseJsonBounded2 } from "@opengeni/network";
21313
+ import { OAUTH_MAX_RESPONSE_BYTES as OAUTH_MAX_RESPONSE_BYTES3, pinnedFetch as pinnedFetch3, readResponseJsonBounded as readResponseJsonBounded2 } from "@opengeni/network";
20576
21314
  import { Buffer as Buffer3 } from "buffer";
20577
21315
  import { createHash as createHash8, randomBytes as randomBytes4 } from "crypto";
20578
21316
  import { HTTPException as HTTPException28 } from "hono/http-exception";
@@ -20613,7 +21351,7 @@ function socialProviderFetch(deps, url, init, label) {
20613
21351
  if (deps.providerFetch) {
20614
21352
  return deps.providerFetch(url, init, label);
20615
21353
  }
20616
- return pinnedFetch2(url, init, deps.settings, {
21354
+ return pinnedFetch3(url, init, deps.settings, {
20617
21355
  label,
20618
21356
  requireHttpsOutsideLocalTest: true
20619
21357
  });
@@ -20729,7 +21467,7 @@ async function completeSocialOAuthCallback(deps, input) {
20729
21467
  throw new HTTPException28(422, { message: PERSONAL_CONNECTION_PRINCIPAL_MESSAGE });
20730
21468
  }
20731
21469
  const grant = await getWorkspaceGrant2(db, state.subjectId, state.workspaceId);
20732
- if (!grant || grant.accountId !== state.accountId || state.ownership === "workspace" && !hasPermission8(grant.permissions, "workspace:admin")) {
21470
+ if (!grant || grant.accountId !== state.accountId || state.ownership === "workspace" && !hasPermission9(grant.permissions, "workspace:admin")) {
20733
21471
  throw new HTTPException28(403, {
20734
21472
  message: "OAuth subject no longer has permission to connect social accounts"
20735
21473
  });
@@ -21460,7 +22198,7 @@ function socialApiHeaders(bundle) {
21460
22198
  async function socialApiRequest(deps, ref, bundle, url, init) {
21461
22199
  const requestInit = { ...init, signal: AbortSignal.timeout(SOCIAL_TIMEOUT_MS) };
21462
22200
  const label = `social ${bundle.provider} API`;
21463
- const response = deps.providerFetch ? await deps.providerFetch(url.toString(), requestInit, label) : await pinnedFetch3(url.toString(), requestInit, deps.settings, {
22201
+ const response = deps.providerFetch ? await deps.providerFetch(url.toString(), requestInit, label) : await pinnedFetch4(url.toString(), requestInit, deps.settings, {
21464
22202
  label,
21465
22203
  requireHttpsOutsideLocalTest: true
21466
22204
  });
@@ -26992,7 +27730,7 @@ import {
26992
27730
  } from "@opengeni/contracts";
26993
27731
  import {
26994
27732
  fileOwnerContextForAgent as fileOwnerContextForAgent3,
26995
- hasPermission as hasPermission9,
27733
+ hasPermission as hasPermission10,
26996
27734
  requireOpenGeniSlackBotConnection as requireOpenGeniSlackBotConnection2,
26997
27735
  requirePermission as requirePermission3
26998
27736
  } from "@opengeni/core";
@@ -27291,7 +28029,7 @@ async function uploadSlackTaskFile(deps, input) {
27291
28029
  });
27292
28030
  }
27293
28031
  function slackTaskRequesterCanReceiveFile(permissions) {
27294
- return hasPermission9(permissions, "files:read") && hasPermission9(permissions, "sessions:read");
28032
+ return hasPermission10(permissions, "files:read") && hasPermission10(permissions, "sessions:read");
27295
28033
  }
27296
28034
  function assertSlackTaskUploadTarget(interaction) {
27297
28035
  if (interaction.visibility === "private" && (!interaction.slackChannelId.startsWith("D") || interaction.routeKey !== `${interaction.slackChannelId}:${interaction.slackThreadTs}` || interaction.ackSlackMessageTs !== null && interaction.ackSlackMessageTs !== interaction.slackThreadTs)) {
@@ -34305,7 +35043,10 @@ var ACTION_CATALOG = [
34305
35043
  "request": [],
34306
35044
  "response": [
34307
35045
  "DisconnectOnePasswordResponse",
35046
+ "DisconnectVaultProviderResponse",
34308
35047
  "InstallOnePasswordResponse",
35048
+ "InstallVaultProviderResponse",
35049
+ "ListVaultProviderConnectionsResponse",
34309
35050
  "OnePasswordConnectionSummary",
34310
35051
  "ProviderVaultMeta",
34311
35052
  "RevealVaultFieldResponse",
@@ -34313,6 +35054,7 @@ var ACTION_CATALOG = [
34313
35054
  "VaultFieldVersionMeta",
34314
35055
  "VaultItem",
34315
35056
  "VaultItemSummary",
35057
+ "VaultProviderConnectionSummary",
34316
35058
  "VaultSummary"
34317
35059
  ]
34318
35060
  },
@@ -34330,6 +35072,28 @@ var ACTION_CATALOG = [
34330
35072
  "request": [],
34331
35073
  "response": []
34332
35074
  },
35075
+ {
35076
+ "id": "DELETE /v1/workspaces/:workspaceId/vault-providers/connections/:connectionId",
35077
+ "method": "DELETE",
35078
+ "path": "/v1/workspaces/:workspaceId/vault-providers/connections/:connectionId",
35079
+ "request": [],
35080
+ "response": [
35081
+ "DisconnectOnePasswordResponse",
35082
+ "DisconnectVaultProviderResponse",
35083
+ "InstallOnePasswordResponse",
35084
+ "InstallVaultProviderResponse",
35085
+ "ListVaultProviderConnectionsResponse",
35086
+ "OnePasswordConnectionSummary",
35087
+ "ProviderVaultMeta",
35088
+ "RevealVaultFieldResponse",
35089
+ "SessionSecretsView",
35090
+ "VaultFieldVersionMeta",
35091
+ "VaultItem",
35092
+ "VaultItemSummary",
35093
+ "VaultProviderConnectionSummary",
35094
+ "VaultSummary"
35095
+ ]
35096
+ },
34333
35097
  {
34334
35098
  "id": "DELETE /v1/workspaces/:workspaceId/vaults/:vaultId",
34335
35099
  "method": "DELETE",
@@ -34337,7 +35101,10 @@ var ACTION_CATALOG = [
34337
35101
  "request": [],
34338
35102
  "response": [
34339
35103
  "DisconnectOnePasswordResponse",
35104
+ "DisconnectVaultProviderResponse",
34340
35105
  "InstallOnePasswordResponse",
35106
+ "InstallVaultProviderResponse",
35107
+ "ListVaultProviderConnectionsResponse",
34341
35108
  "OnePasswordConnectionSummary",
34342
35109
  "ProviderVaultMeta",
34343
35110
  "RevealVaultFieldResponse",
@@ -34345,6 +35112,7 @@ var ACTION_CATALOG = [
34345
35112
  "VaultFieldVersionMeta",
34346
35113
  "VaultItem",
34347
35114
  "VaultItemSummary",
35115
+ "VaultProviderConnectionSummary",
34348
35116
  "VaultSummary"
34349
35117
  ]
34350
35118
  },
@@ -34535,7 +35303,10 @@ var ACTION_CATALOG = [
34535
35303
  "request": [],
34536
35304
  "response": [
34537
35305
  "DisconnectOnePasswordResponse",
35306
+ "DisconnectVaultProviderResponse",
34538
35307
  "InstallOnePasswordResponse",
35308
+ "InstallVaultProviderResponse",
35309
+ "ListVaultProviderConnectionsResponse",
34539
35310
  "OnePasswordConnectionSummary",
34540
35311
  "ProviderVaultMeta",
34541
35312
  "RevealVaultFieldResponse",
@@ -34543,6 +35314,7 @@ var ACTION_CATALOG = [
34543
35314
  "VaultFieldVersionMeta",
34544
35315
  "VaultItem",
34545
35316
  "VaultItemSummary",
35317
+ "VaultProviderConnectionSummary",
34546
35318
  "VaultSummary"
34547
35319
  ]
34548
35320
  },
@@ -34834,8 +35606,11 @@ var ACTION_CATALOG = [
34834
35606
  ],
34835
35607
  "response": [
34836
35608
  "DisconnectOnePasswordResponse",
35609
+ "DisconnectVaultProviderResponse",
34837
35610
  "EnsureWorkspaceResponse",
34838
35611
  "InstallOnePasswordResponse",
35612
+ "InstallVaultProviderResponse",
35613
+ "ListVaultProviderConnectionsResponse",
34839
35614
  "OnePasswordConnectionSummary",
34840
35615
  "ProviderVaultMeta",
34841
35616
  "RevealVaultFieldResponse",
@@ -34843,6 +35618,7 @@ var ACTION_CATALOG = [
34843
35618
  "VaultFieldVersionMeta",
34844
35619
  "VaultItem",
34845
35620
  "VaultItemSummary",
35621
+ "VaultProviderConnectionSummary",
34846
35622
  "VaultSummary"
34847
35623
  ]
34848
35624
  },
@@ -35098,7 +35874,10 @@ var ACTION_CATALOG = [
35098
35874
  "request": [],
35099
35875
  "response": [
35100
35876
  "DisconnectOnePasswordResponse",
35877
+ "DisconnectVaultProviderResponse",
35101
35878
  "InstallOnePasswordResponse",
35879
+ "InstallVaultProviderResponse",
35880
+ "ListVaultProviderConnectionsResponse",
35102
35881
  "OnePasswordConnectionSummary",
35103
35882
  "ProviderVaultMeta",
35104
35883
  "RevealVaultFieldResponse",
@@ -35106,6 +35885,7 @@ var ACTION_CATALOG = [
35106
35885
  "VaultFieldVersionMeta",
35107
35886
  "VaultItem",
35108
35887
  "VaultItemSummary",
35888
+ "VaultProviderConnectionSummary",
35109
35889
  "VaultSummary"
35110
35890
  ]
35111
35891
  },
@@ -35116,7 +35896,10 @@ var ACTION_CATALOG = [
35116
35896
  "request": [],
35117
35897
  "response": [
35118
35898
  "DisconnectOnePasswordResponse",
35899
+ "DisconnectVaultProviderResponse",
35119
35900
  "InstallOnePasswordResponse",
35901
+ "InstallVaultProviderResponse",
35902
+ "ListVaultProviderConnectionsResponse",
35120
35903
  "OnePasswordConnectionSummary",
35121
35904
  "ProviderVaultMeta",
35122
35905
  "RevealVaultFieldResponse",
@@ -35124,6 +35907,7 @@ var ACTION_CATALOG = [
35124
35907
  "VaultFieldVersionMeta",
35125
35908
  "VaultItem",
35126
35909
  "VaultItemSummary",
35910
+ "VaultProviderConnectionSummary",
35127
35911
  "VaultSummary"
35128
35912
  ]
35129
35913
  },
@@ -35262,7 +36046,10 @@ var ACTION_CATALOG = [
35262
36046
  "request": [],
35263
36047
  "response": [
35264
36048
  "DisconnectOnePasswordResponse",
36049
+ "DisconnectVaultProviderResponse",
35265
36050
  "InstallOnePasswordResponse",
36051
+ "InstallVaultProviderResponse",
36052
+ "ListVaultProviderConnectionsResponse",
35266
36053
  "OnePasswordConnectionSummary",
35267
36054
  "ProviderVaultMeta",
35268
36055
  "RevealVaultFieldResponse",
@@ -35270,6 +36057,7 @@ var ACTION_CATALOG = [
35270
36057
  "VaultFieldVersionMeta",
35271
36058
  "VaultItem",
35272
36059
  "VaultItemSummary",
36060
+ "VaultProviderConnectionSummary",
35273
36061
  "VaultSummary"
35274
36062
  ]
35275
36063
  },
@@ -35311,6 +36099,28 @@ var ACTION_CATALOG = [
35311
36099
  "ToolGatewayDeclarationsResponse"
35312
36100
  ]
35313
36101
  },
36102
+ {
36103
+ "id": "GET /v1/workspaces/:workspaceId/vault-providers/connections",
36104
+ "method": "GET",
36105
+ "path": "/v1/workspaces/:workspaceId/vault-providers/connections",
36106
+ "request": [],
36107
+ "response": [
36108
+ "DisconnectOnePasswordResponse",
36109
+ "DisconnectVaultProviderResponse",
36110
+ "InstallOnePasswordResponse",
36111
+ "InstallVaultProviderResponse",
36112
+ "ListVaultProviderConnectionsResponse",
36113
+ "OnePasswordConnectionSummary",
36114
+ "ProviderVaultMeta",
36115
+ "RevealVaultFieldResponse",
36116
+ "SessionSecretsView",
36117
+ "VaultFieldVersionMeta",
36118
+ "VaultItem",
36119
+ "VaultItemSummary",
36120
+ "VaultProviderConnectionSummary",
36121
+ "VaultSummary"
36122
+ ]
36123
+ },
35314
36124
  {
35315
36125
  "id": "GET /v1/workspaces/:workspaceId/vaults",
35316
36126
  "method": "GET",
@@ -35318,7 +36128,10 @@ var ACTION_CATALOG = [
35318
36128
  "request": [],
35319
36129
  "response": [
35320
36130
  "DisconnectOnePasswordResponse",
36131
+ "DisconnectVaultProviderResponse",
35321
36132
  "InstallOnePasswordResponse",
36133
+ "InstallVaultProviderResponse",
36134
+ "ListVaultProviderConnectionsResponse",
35322
36135
  "OnePasswordConnectionSummary",
35323
36136
  "ProviderVaultMeta",
35324
36137
  "RevealVaultFieldResponse",
@@ -35326,6 +36139,7 @@ var ACTION_CATALOG = [
35326
36139
  "VaultFieldVersionMeta",
35327
36140
  "VaultItem",
35328
36141
  "VaultItemSummary",
36142
+ "VaultProviderConnectionSummary",
35329
36143
  "VaultSummary"
35330
36144
  ]
35331
36145
  },
@@ -35336,7 +36150,10 @@ var ACTION_CATALOG = [
35336
36150
  "request": [],
35337
36151
  "response": [
35338
36152
  "DisconnectOnePasswordResponse",
36153
+ "DisconnectVaultProviderResponse",
35339
36154
  "InstallOnePasswordResponse",
36155
+ "InstallVaultProviderResponse",
36156
+ "ListVaultProviderConnectionsResponse",
35340
36157
  "OnePasswordConnectionSummary",
35341
36158
  "ProviderVaultMeta",
35342
36159
  "RevealVaultFieldResponse",
@@ -35344,6 +36161,7 @@ var ACTION_CATALOG = [
35344
36161
  "VaultFieldVersionMeta",
35345
36162
  "VaultItem",
35346
36163
  "VaultItemSummary",
36164
+ "VaultProviderConnectionSummary",
35347
36165
  "VaultSummary"
35348
36166
  ]
35349
36167
  },
@@ -35373,7 +36191,22 @@ var ACTION_CATALOG = [
35373
36191
  "method": "GET",
35374
36192
  "path": "/v1/workspaces/external/:workspaceSource/:workspaceExternalId/allowance",
35375
36193
  "request": [],
35376
- "response": []
36194
+ "response": [
36195
+ "DisconnectOnePasswordResponse",
36196
+ "DisconnectVaultProviderResponse",
36197
+ "InstallOnePasswordResponse",
36198
+ "InstallVaultProviderResponse",
36199
+ "ListVaultProviderConnectionsResponse",
36200
+ "OnePasswordConnectionSummary",
36201
+ "ProviderVaultMeta",
36202
+ "RevealVaultFieldResponse",
36203
+ "SessionSecretsView",
36204
+ "VaultFieldVersionMeta",
36205
+ "VaultItem",
36206
+ "VaultItemSummary",
36207
+ "VaultProviderConnectionSummary",
36208
+ "VaultSummary"
36209
+ ]
35377
36210
  },
35378
36211
  {
35379
36212
  "id": "GET /v1/workspaces/external/:workspaceSource/:workspaceExternalId/allowance/state",
@@ -35387,7 +36220,22 @@ var ACTION_CATALOG = [
35387
36220
  "method": "GET",
35388
36221
  "path": "/v1/workspaces/external/:workspaceSource/:workspaceExternalId/usage",
35389
36222
  "request": [],
35390
- "response": []
36223
+ "response": [
36224
+ "DisconnectOnePasswordResponse",
36225
+ "DisconnectVaultProviderResponse",
36226
+ "InstallOnePasswordResponse",
36227
+ "InstallVaultProviderResponse",
36228
+ "ListVaultProviderConnectionsResponse",
36229
+ "OnePasswordConnectionSummary",
36230
+ "ProviderVaultMeta",
36231
+ "RevealVaultFieldResponse",
36232
+ "SessionSecretsView",
36233
+ "VaultFieldVersionMeta",
36234
+ "VaultItem",
36235
+ "VaultItemSummary",
36236
+ "VaultProviderConnectionSummary",
36237
+ "VaultSummary"
36238
+ ]
35391
36239
  },
35392
36240
  {
35393
36241
  "id": "GET /v1/workspaces/external/:workspaceSource/:workspaceExternalId/usage/me",
@@ -35609,7 +36457,10 @@ var ACTION_CATALOG = [
35609
36457
  "ConnectionMetadata",
35610
36458
  "ConnectionResponse",
35611
36459
  "DisconnectOnePasswordResponse",
36460
+ "DisconnectVaultProviderResponse",
35612
36461
  "InstallOnePasswordResponse",
36462
+ "InstallVaultProviderResponse",
36463
+ "ListVaultProviderConnectionsResponse",
35613
36464
  "OnePasswordConnectionSummary",
35614
36465
  "ProviderVaultMeta",
35615
36466
  "RevealVaultFieldResponse",
@@ -35617,6 +36468,7 @@ var ACTION_CATALOG = [
35617
36468
  "VaultFieldVersionMeta",
35618
36469
  "VaultItem",
35619
36470
  "VaultItemSummary",
36471
+ "VaultProviderConnectionSummary",
35620
36472
  "VaultSummary"
35621
36473
  ]
35622
36474
  },
@@ -36379,7 +37231,10 @@ var ACTION_CATALOG = [
36379
37231
  "request": [],
36380
37232
  "response": [
36381
37233
  "DisconnectOnePasswordResponse",
37234
+ "DisconnectVaultProviderResponse",
36382
37235
  "InstallOnePasswordResponse",
37236
+ "InstallVaultProviderResponse",
37237
+ "ListVaultProviderConnectionsResponse",
36383
37238
  "OnePasswordConnectionSummary",
36384
37239
  "ProviderVaultMeta",
36385
37240
  "RevealVaultFieldResponse",
@@ -36387,6 +37242,7 @@ var ACTION_CATALOG = [
36387
37242
  "VaultFieldVersionMeta",
36388
37243
  "VaultItem",
36389
37244
  "VaultItemSummary",
37245
+ "VaultProviderConnectionSummary",
36390
37246
  "VaultSummary",
36391
37247
  "Workspace"
36392
37248
  ]
@@ -36710,7 +37566,21 @@ var ACTION_CATALOG = [
36710
37566
  "ImportArchivedSessionRequest"
36711
37567
  ],
36712
37568
  "response": [
36713
- "ImportArchivedSessionResponse"
37569
+ "DisconnectOnePasswordResponse",
37570
+ "DisconnectVaultProviderResponse",
37571
+ "ImportArchivedSessionResponse",
37572
+ "InstallOnePasswordResponse",
37573
+ "InstallVaultProviderResponse",
37574
+ "ListVaultProviderConnectionsResponse",
37575
+ "OnePasswordConnectionSummary",
37576
+ "ProviderVaultMeta",
37577
+ "RevealVaultFieldResponse",
37578
+ "SessionSecretsView",
37579
+ "VaultFieldVersionMeta",
37580
+ "VaultItem",
37581
+ "VaultItemSummary",
37582
+ "VaultProviderConnectionSummary",
37583
+ "VaultSummary"
36714
37584
  ]
36715
37585
  },
36716
37586
  {
@@ -38125,7 +38995,10 @@ var ACTION_CATALOG = [
38125
38995
  "request": [],
38126
38996
  "response": [
38127
38997
  "DisconnectOnePasswordResponse",
38998
+ "DisconnectVaultProviderResponse",
38128
38999
  "InstallOnePasswordResponse",
39000
+ "InstallVaultProviderResponse",
39001
+ "ListVaultProviderConnectionsResponse",
38129
39002
  "OnePasswordConnectionSummary",
38130
39003
  "ProviderVaultMeta",
38131
39004
  "RevealVaultFieldResponse",
@@ -38133,6 +39006,7 @@ var ACTION_CATALOG = [
38133
39006
  "VaultFieldVersionMeta",
38134
39007
  "VaultItem",
38135
39008
  "VaultItemSummary",
39009
+ "VaultProviderConnectionSummary",
38136
39010
  "VaultSummary"
38137
39011
  ]
38138
39012
  },
@@ -38258,7 +39132,10 @@ var ACTION_CATALOG = [
38258
39132
  "request": [],
38259
39133
  "response": [
38260
39134
  "DisconnectOnePasswordResponse",
39135
+ "DisconnectVaultProviderResponse",
38261
39136
  "InstallOnePasswordResponse",
39137
+ "InstallVaultProviderResponse",
39138
+ "ListVaultProviderConnectionsResponse",
38262
39139
  "OnePasswordConnectionSummary",
38263
39140
  "ProviderVaultMeta",
38264
39141
  "RevealVaultFieldResponse",
@@ -38266,6 +39143,7 @@ var ACTION_CATALOG = [
38266
39143
  "VaultFieldVersionMeta",
38267
39144
  "VaultItem",
38268
39145
  "VaultItemSummary",
39146
+ "VaultProviderConnectionSummary",
38269
39147
  "VaultSummary"
38270
39148
  ]
38271
39149
  },
@@ -38276,7 +39154,10 @@ var ACTION_CATALOG = [
38276
39154
  "request": [],
38277
39155
  "response": [
38278
39156
  "DisconnectOnePasswordResponse",
39157
+ "DisconnectVaultProviderResponse",
38279
39158
  "InstallOnePasswordResponse",
39159
+ "InstallVaultProviderResponse",
39160
+ "ListVaultProviderConnectionsResponse",
38280
39161
  "OnePasswordConnectionSummary",
38281
39162
  "ProviderVaultMeta",
38282
39163
  "RevealVaultFieldResponse",
@@ -38284,6 +39165,7 @@ var ACTION_CATALOG = [
38284
39165
  "VaultFieldVersionMeta",
38285
39166
  "VaultItem",
38286
39167
  "VaultItemSummary",
39168
+ "VaultProviderConnectionSummary",
38287
39169
  "VaultSummary"
38288
39170
  ]
38289
39171
  },
@@ -38535,6 +39417,52 @@ var ACTION_CATALOG = [
38535
39417
  "ToolGatewayTargetApprovalResponse"
38536
39418
  ]
38537
39419
  },
39420
+ {
39421
+ "id": "POST /v1/workspaces/:workspaceId/vault-providers/connections",
39422
+ "method": "POST",
39423
+ "path": "/v1/workspaces/:workspaceId/vault-providers/connections",
39424
+ "request": [
39425
+ "InstallVaultProviderRequest"
39426
+ ],
39427
+ "response": [
39428
+ "DisconnectOnePasswordResponse",
39429
+ "DisconnectVaultProviderResponse",
39430
+ "InstallOnePasswordResponse",
39431
+ "InstallVaultProviderResponse",
39432
+ "ListVaultProviderConnectionsResponse",
39433
+ "OnePasswordConnectionSummary",
39434
+ "ProviderVaultMeta",
39435
+ "RevealVaultFieldResponse",
39436
+ "SessionSecretsView",
39437
+ "VaultFieldVersionMeta",
39438
+ "VaultItem",
39439
+ "VaultItemSummary",
39440
+ "VaultProviderConnectionSummary",
39441
+ "VaultSummary"
39442
+ ]
39443
+ },
39444
+ {
39445
+ "id": "POST /v1/workspaces/:workspaceId/vault-providers/connections/:connectionId/verify",
39446
+ "method": "POST",
39447
+ "path": "/v1/workspaces/:workspaceId/vault-providers/connections/:connectionId/verify",
39448
+ "request": [],
39449
+ "response": [
39450
+ "DisconnectOnePasswordResponse",
39451
+ "DisconnectVaultProviderResponse",
39452
+ "InstallOnePasswordResponse",
39453
+ "InstallVaultProviderResponse",
39454
+ "ListVaultProviderConnectionsResponse",
39455
+ "OnePasswordConnectionSummary",
39456
+ "ProviderVaultMeta",
39457
+ "RevealVaultFieldResponse",
39458
+ "SessionSecretsView",
39459
+ "VaultFieldVersionMeta",
39460
+ "VaultItem",
39461
+ "VaultItemSummary",
39462
+ "VaultProviderConnectionSummary",
39463
+ "VaultSummary"
39464
+ ]
39465
+ },
38538
39466
  {
38539
39467
  "id": "POST /v1/workspaces/:workspaceId/vaults",
38540
39468
  "method": "POST",
@@ -38542,7 +39470,10 @@ var ACTION_CATALOG = [
38542
39470
  "request": [],
38543
39471
  "response": [
38544
39472
  "DisconnectOnePasswordResponse",
39473
+ "DisconnectVaultProviderResponse",
38545
39474
  "InstallOnePasswordResponse",
39475
+ "InstallVaultProviderResponse",
39476
+ "ListVaultProviderConnectionsResponse",
38546
39477
  "OnePasswordConnectionSummary",
38547
39478
  "ProviderVaultMeta",
38548
39479
  "RevealVaultFieldResponse",
@@ -38550,6 +39481,7 @@ var ACTION_CATALOG = [
38550
39481
  "VaultFieldVersionMeta",
38551
39482
  "VaultItem",
38552
39483
  "VaultItemSummary",
39484
+ "VaultProviderConnectionSummary",
38553
39485
  "VaultSummary"
38554
39486
  ]
38555
39487
  },
@@ -38602,7 +39534,10 @@ var ACTION_CATALOG = [
38602
39534
  "request": [],
38603
39535
  "response": [
38604
39536
  "DisconnectOnePasswordResponse",
39537
+ "DisconnectVaultProviderResponse",
38605
39538
  "InstallOnePasswordResponse",
39539
+ "InstallVaultProviderResponse",
39540
+ "ListVaultProviderConnectionsResponse",
38606
39541
  "OnePasswordConnectionSummary",
38607
39542
  "ProviderVaultMeta",
38608
39543
  "RevealVaultFieldResponse",
@@ -38610,6 +39545,7 @@ var ACTION_CATALOG = [
38610
39545
  "VaultFieldVersionMeta",
38611
39546
  "VaultItem",
38612
39547
  "VaultItemSummary",
39548
+ "VaultProviderConnectionSummary",
38613
39549
  "VaultSummary"
38614
39550
  ]
38615
39551
  },
@@ -38820,7 +39756,10 @@ var ACTION_CATALOG = [
38820
39756
  "request": [],
38821
39757
  "response": [
38822
39758
  "DisconnectOnePasswordResponse",
39759
+ "DisconnectVaultProviderResponse",
38823
39760
  "InstallOnePasswordResponse",
39761
+ "InstallVaultProviderResponse",
39762
+ "ListVaultProviderConnectionsResponse",
38824
39763
  "OnePasswordConnectionSummary",
38825
39764
  "ProviderVaultMeta",
38826
39765
  "RevealVaultFieldResponse",
@@ -38828,6 +39767,7 @@ var ACTION_CATALOG = [
38828
39767
  "VaultFieldVersionMeta",
38829
39768
  "VaultItem",
38830
39769
  "VaultItemSummary",
39770
+ "VaultProviderConnectionSummary",
38831
39771
  "VaultSummary"
38832
39772
  ]
38833
39773
  },
@@ -38861,7 +39801,10 @@ var ACTION_CATALOG = [
38861
39801
  "request": [],
38862
39802
  "response": [
38863
39803
  "DisconnectOnePasswordResponse",
39804
+ "DisconnectVaultProviderResponse",
38864
39805
  "InstallOnePasswordResponse",
39806
+ "InstallVaultProviderResponse",
39807
+ "ListVaultProviderConnectionsResponse",
38865
39808
  "OnePasswordConnectionSummary",
38866
39809
  "ProviderVaultMeta",
38867
39810
  "RevealVaultFieldResponse",
@@ -38869,6 +39812,7 @@ var ACTION_CATALOG = [
38869
39812
  "VaultFieldVersionMeta",
38870
39813
  "VaultItem",
38871
39814
  "VaultItemSummary",
39815
+ "VaultProviderConnectionSummary",
38872
39816
  "VaultSummary"
38873
39817
  ]
38874
39818
  },
@@ -38879,12 +39823,51 @@ var ACTION_CATALOG = [
38879
39823
  "request": [],
38880
39824
  "response": []
38881
39825
  },
39826
+ {
39827
+ "id": "PUT /v1/workspaces/:workspaceId/vault-providers/connections/:connectionId/credentials",
39828
+ "method": "PUT",
39829
+ "path": "/v1/workspaces/:workspaceId/vault-providers/connections/:connectionId/credentials",
39830
+ "request": [
39831
+ "ReplaceVaultProviderCredentialsRequest"
39832
+ ],
39833
+ "response": [
39834
+ "DisconnectOnePasswordResponse",
39835
+ "DisconnectVaultProviderResponse",
39836
+ "InstallOnePasswordResponse",
39837
+ "InstallVaultProviderResponse",
39838
+ "ListVaultProviderConnectionsResponse",
39839
+ "OnePasswordConnectionSummary",
39840
+ "ProviderVaultMeta",
39841
+ "RevealVaultFieldResponse",
39842
+ "SessionSecretsView",
39843
+ "VaultFieldVersionMeta",
39844
+ "VaultItem",
39845
+ "VaultItemSummary",
39846
+ "VaultProviderConnectionSummary",
39847
+ "VaultSummary"
39848
+ ]
39849
+ },
38882
39850
  {
38883
39851
  "id": "PUT /v1/workspaces/external/:workspaceSource/:workspaceExternalId/allowance",
38884
39852
  "method": "PUT",
38885
39853
  "path": "/v1/workspaces/external/:workspaceSource/:workspaceExternalId/allowance",
38886
39854
  "request": [],
38887
- "response": []
39855
+ "response": [
39856
+ "DisconnectOnePasswordResponse",
39857
+ "DisconnectVaultProviderResponse",
39858
+ "InstallOnePasswordResponse",
39859
+ "InstallVaultProviderResponse",
39860
+ "ListVaultProviderConnectionsResponse",
39861
+ "OnePasswordConnectionSummary",
39862
+ "ProviderVaultMeta",
39863
+ "RevealVaultFieldResponse",
39864
+ "SessionSecretsView",
39865
+ "VaultFieldVersionMeta",
39866
+ "VaultItem",
39867
+ "VaultItemSummary",
39868
+ "VaultProviderConnectionSummary",
39869
+ "VaultSummary"
39870
+ ]
38888
39871
  },
38889
39872
  {
38890
39873
  "id": "PUT /v1/workspaces/external/:workspaceSource/:workspaceExternalId/members/:subjectId/allowance",
@@ -40882,7 +41865,10 @@ var ACTION_CATALOG = [
40882
41865
  ],
40883
41866
  "response": [
40884
41867
  "DisconnectOnePasswordResponse",
41868
+ "DisconnectVaultProviderResponse",
40885
41869
  "InstallOnePasswordResponse",
41870
+ "InstallVaultProviderResponse",
41871
+ "ListVaultProviderConnectionsResponse",
40886
41872
  "OnePasswordConnectionSummary",
40887
41873
  "ProviderVaultMeta",
40888
41874
  "RevealVaultFieldResponse",
@@ -40890,6 +41876,7 @@ var ACTION_CATALOG = [
40890
41876
  "VaultFieldVersionMeta",
40891
41877
  "VaultItem",
40892
41878
  "VaultItemSummary",
41879
+ "VaultProviderConnectionSummary",
40893
41880
  "VaultSummary",
40894
41881
  "Workspace"
40895
41882
  ]
@@ -41038,7 +42025,7 @@ var ACTION_CATALOG = [
41038
42025
  ];
41039
42026
 
41040
42027
  // src/mcp/action-schema-imports.gen.ts
41041
- import { AcceptOrganizationInvitationRequest, AcceptOrganizationRecoveryCustodyRequest, AcknowledgeStreamRequest, ActivateCodexRealtimeConnectionRequest, ActivateCompanyProfileRevisionRequest, ActivatePreferenceRegistryRevisionRequest, ActivateWorkspaceInstructionPolicyRequest, AddDocumentRequest, AddWorkspaceMemberRequest, AgentInstructionReviewRequest, AgentLearningContext, ApiIntegrationOAuthStartRequest, AppendArchivedSessionEventsRequest as AppendArchivedSessionEventsRequest2, ApplySessionGoalRevisionRequest, ApproveSlackUserLinkAccessRequest, ArtifactCatalogKind, AtlassianLifecycleActionRequest, AttachViewerRequest, BeginSessionRealtimeRequest, BrowserActionRequest, BrowserDomReadRequest, BrowserDownloadSaveRequest, BrowserOpenTargetRequest, BrowserSessionAttachmentRequest, BrowserSessionLifecycleRequest, ChangeMachineAudienceRequest, ChangePreferenceRegistryScopeRequest, ClaudeSubscriptionOAuthCompleteRequest, ClaudeSubscriptionOAuthStartRequest, ClaudeSubscriptionSetupTokenRequest as ClaudeSubscriptionSetupTokenRequest2, ClearWorkspaceAllowanceRequest, CodexAppsDesignationRequest as CodexAppsDesignationRequest2, CodexRealtimeWebrtcRequest, CodexSourceRequest as CodexSourceRequest2, CompanyProfileDiffRequest, ComputerActionRequest, ComputerNativeCallRequest, ComputerSessionAttachmentRequest, ComputerSessionLifecycleRequest, ConfigureOrganizationRecoveryPolicyRequest, CorrectPreferenceRegistryRequest, CreateAdditionalOrganizationRequest, CreateApiKeyRequest, CreateAutomationSourceRequest, CreateAutomationTriggerRequest, CreateBillingPortalRequest, CreateBrowserIdentityRequest, CreateBrowserSessionRequest, CreateCapabilityCatalogItemRequest, CreateChannelRequest, CreateCheckoutRequest, CreateComputerSessionRequest, CreateConnectionRequest, CreateDocumentBaseRequest, CreateFeedbackRequest, CreateFileUploadRequest as CreateFileUploadRequest2, CreateInteractionInterventionRequest, CreateKnowledgeDropRequest, CreateNetworkRouteRequest, CreateOrganizationApiKeyRequest, CreateOrganizationInvitationRequest, CreateOrganizationProviderCustomModelRequest, CreateOrganizationRequest, CreateOrganizationServiceAccountRequest, CreateOrganizationWebhookRequest, CreateOrganizationWorkspaceRequest, CreatePersonalApiKeyRequest, CreatePrReviewAppRegistrationRequest, CreatePrReviewRepositoryBindingRequest, CreatePreferenceRegistryProposalRequest, CreateRigRequest, CreateScheduledTaskRequest as CreateScheduledTaskRequest2, CreateSessionRequest, CreateSiteAuthConnectionRequest, CreateWorkspaceArtifactRequest, CreateWorkspaceGatewayCustomModelRequest as CreateWorkspaceGatewayCustomModelRequest2, CreateWorkspaceInstructionPolicyDraftRequest, CreateWorkspaceInstructionPolicyOnboardingProposalRequest, CreateWorkspaceOpenRouterCustomModelRequest, CreateWorkspaceOpperCustomModelRequest, CreateWorkspaceRequest, CreateWorkspaceWebhookRequest, DeactivatePreferenceRegistryRequest, DeleteOrganizationProviderCustomModelRequest, DeleteSessionQueueItemRequest, DeleteWorkspaceGatewayCustomModelRequest as DeleteWorkspaceGatewayCustomModelRequest2, DeleteWorkspaceOpenRouterCustomModelRequest, DeleteWorkspaceOpperCustomModelRequest, DeviceEnrollmentApproveRequest, DisableOrganizationRecoveryPolicyRequest, EditSessionQueueItemRequest, EnableCapabilityRequest, EndSessionRealtimeRequest, EnsureWorkspaceRequest, ExternalAuthInteractiveRequest, ExternalAuthRunRequest, FikenInstallRequest as FikenInstallRequest2, FikenOAuthStartRequest, FileListRequest as FileListRequest2, ForkSessionRequest, FsDeleteRequest, FsListBatchRequest, FsListRequest, FsMkdirRequest, FsMoveRequest, FsReadRequest, FsWriteRequest, GatewayRealtimeConnectRequest, GetMyUsageRequest, GetUsageRequest, GitDiffRequest, GitLogRequest, GitReadBatchRequest, GitShowRequest, GitStatusRequest, GrantSessionAdminAccessRequest, GrantWorkspaceCreditsRequest, ImportArchivedSessionRequest as ImportArchivedSessionRequest2, ImportLegacyWorkspaceInstructionPolicyDraftRequest, InboxItem, InboxSettings, InsightsRange, InstallApiIntegrationRequest, InstallLibrarySkillRequest, InstallPluginRequest, InstallSkillRequest, IssueUserResourceGrantRequest, KnowledgeEntryBatchReviewRequest, KnowledgeEntryListRequest as KnowledgeEntryListRequest3, KnowledgeEntryRestoreRequest, KnowledgeEntryReviewRequest, KnowledgeEntrySaveRequest as KnowledgeEntrySaveRequest2, KnowledgeReviewBatchListRequest, KnowledgeSavePreparationRequest as KnowledgeSavePreparationRequest2, MachineAudiencePreviewRequest, McpConnectionDecision, MemberNotificationsSetting, MemorySlackPublicationActionRequest, MintEnrollTokenRequest, ModelConnectionAccessPolicy, MoveDocumentRequest, MoveSessionQueueItemRequest, MutateIntegrationFacetRequest, OAuthStartRequest, OpenGeniSlackBotInstallRequest, OpenMachinePrivacySettingsRequest, OrganizationModelProviderKind, OrganizationRecoveryOperationCommandRequest, OrganizationUsagePeriod, PrepareSlackUserLinkAccessRequest, PreviewApiIntegrationRequest, PreviewPluginRequest, PreviewSkillImportRequest, ProposeRigChangeRequest, PtyCloseRequest, PtyOpenRequest, PtyResizeRequest, PtyWriteRequest, PublishBrowserRevisionRequest, PublishSandboxFileArtifactRequest, PublishWorkspaceArtifactVersionRequest, PutOrganizationCredentialProviderRequest, PutOrganizationWorkspaceMemberRequest, PutWorkspaceCredentialProviderRequest, ReclassifyDocumentAuthorityRequest, RefreshScheduledTaskAccessRequest, RejectPreferenceRegistryProposalRequest, RejectSessionGoalRevisionRequest, RemoveEnrollmentRequest, RenewSessionRealtimeRequest, ReorderChannelsRequest, ReportAuthRunRequest, ResolveInteractionInterventionRequest, RetryOrganizationUserSetupDeliveryRequest, RevokeOrganizationInvitationRequest, RevokeOrganizationModelProviderConnectionRequest, RevokeOrganizationWorkspaceMemberRequest, RollbackCompanyProfileRequest, RollbackSessionGoalRevisionRequest, RollbackWorkspaceArtifactRequest, RollbackWorkspaceInstructionPolicyRequest, RotateSessionMcpCredentialsRequest, RunDocumentDefaultCollectionBackfillRequest, SandboxRecoveryRequest, SaveAtlassianSourcesRequest as SaveAtlassianSourcesRequest2, SaveComposerDraftRequest, SaveNewSessionDraftRequest, SessionCodexAccountPinRequest, SessionControlRequest, SessionHumanInputRequest, SessionInboxMute, SessionMessageSearchRequest, SessionRetryRequest, SessionScopeSubjectId, SessionStatus, SessionVisibility, SetMemberAllowanceRequest, SetSessionModelAccountChoiceRequest, SetSessionUsageLimitRequest, SetWorkspaceAllowanceRequest, SetWorkspaceArtifactStatusRequest, SetWorkspaceDefaultRigRequest, SiteDataCollectionDefinitionRequest as SiteDataCollectionDefinitionRequest3, SiteDataImportRequest as SiteDataImportRequest3, SiteDataQueryRequest as SiteDataQueryRequest3, SiteDataWriteRequest as SiteDataWriteRequest3, SiteLimitProfile, SitePublishWarningFix as SitePublishWarningFix2, SiteSqlExportFormat as SiteSqlExportFormat3, SiteSqlImportRequest as SiteSqlImportRequest3, SiteSqlMigrationRequest as SiteSqlMigrationRequest2, SiteSqlQueryDefinitionRequest as SiteSqlQueryDefinitionRequest3, SiteSqlRunRequest as SiteSqlRunRequest3, SiteSqlSettingsRequest as SiteSqlSettingsRequest2, SiteSqlStatementRequest as SiteSqlStatementRequest3, SiteTakedownRequest, SlackUserLinkAccessMutationRequest, SocialOAuthStartRequest, StartAuthRunRequest, StartOrganizationRecoveryOperationRequest, SteerSessionQueueItemRequest, SubmitComposerDraftRequest, SubscriptionAccountRenameRequest as SubscriptionAccountRenameRequest2, SubscriptionAccountToggleRequest as SubscriptionAccountToggleRequest3, SubscriptionConnectPollRequest, SubscriptionRotationSettingsRequest as SubscriptionRotationSettingsRequest3, SupergrokConnectStartRequest, SupersedePreferenceRegistryRequest, SwapActiveSandboxRequest, SyncSessionRealtimeLedgerRequest, TerminalExecRequest, TriggerAutomationManuallyRequest, UninstallApiIntegrationRequest, UninstallPluginRequest, UninstallSkillRequest, UpdateAutomationSourceRequest, UpdateAutomationTriggerRequest, UpdateBrowserIdentityRequest, UpdateChannelRequest, UpdateCompanyProfileAgentPolicyRequest, UpdateCompanyProfileRequest, UpdateConnectionRequest, UpdateConnectorToolPermissionsRequest, UpdateGitHubActionPolicyRequest, UpdateMachineOperationPolicyRequest, UpdateMemorySlackPublicationConfigurationRequest, UpdateModelAccountPreferencesRequest, UpdateNetworkRouteRequest, UpdateOpenGeniSlackBotOrganizationAccess, UpdateOrganizationAgentAdminAccessRequest, UpdateOrganizationApiKeyRequest, UpdateOrganizationIntegrationPolicyRequest, UpdateOrganizationMcpConnectionRequest, UpdateOrganizationMemberRequest, UpdateOrganizationModelAccountSettingsRequest, UpdateOrganizationModelDefaultsRequest, UpdateOrganizationNameRequest, UpdateOrganizationPrivacySettingsRequest, UpdateOrganizationPrivateSessionSettingsRequest, UpdateOrganizationRetentionPolicyRequest, UpdateOrganizationServiceAccountRequest, UpdateOrganizationWebhookRequest, UpdateOrganizationWorkspaceRequest, UpdatePrReviewAppRegistrationRequest, UpdatePrReviewRepositoryBindingRequest, UpdateRigRequest, UpdateScheduledTaskRequest, UpdateSessionAgentRequest, UpdateSessionArchiveRequest, UpdateSessionAttentionRequest, UpdateSessionChannelRequest, UpdateSessionGoalRequest, UpdateSessionMcpApprovalPolicyRequest, UpdateSessionMcpToolPermissionsRequest, UpdateSessionPinRequest, UpdateSessionRequest, UpdateSessionRetentionRequest, UpdateSessionSkillsRequest, UpdateSessionToolPolicyRequest, UpdateSessionVisibilityRequest, UpdateSiteAuthConnectionRequest, UpdateSlackChannelRoutesRequest, UpdateVideoGenerationPolicyRequest, UpdateWorkspaceArtifactVisibilityRequest, UpdateWorkspaceMemberRequest, UpdateWorkspaceModelAccountSettingsRequest, UpdateWorkspaceModelPolicyRequest, UpdateWorkspaceRequest, UpdateWorkspaceSettingsRequest, UpdateWorkspaceWebhookRequest, UpsertIntegrationFacetRequest, UpsertOrganizationModelProviderConnectionRequest, UpsertSitePublicationRequest as UpsertSitePublicationRequest2, VerifyAuthRunRequest, ViewerHeartbeatRequest, WorkClaimSubjectType, WorkspaceInstructionPolicyDiffRequest, WorkspacePauseTimerRequest } from "@opengeni/contracts";
42028
+ import { AcceptOrganizationInvitationRequest, AcceptOrganizationRecoveryCustodyRequest, AcknowledgeStreamRequest, ActivateCodexRealtimeConnectionRequest, ActivateCompanyProfileRevisionRequest, ActivatePreferenceRegistryRevisionRequest, ActivateWorkspaceInstructionPolicyRequest, AddDocumentRequest, AddWorkspaceMemberRequest, AgentInstructionReviewRequest, AgentLearningContext, ApiIntegrationOAuthStartRequest, AppendArchivedSessionEventsRequest as AppendArchivedSessionEventsRequest2, ApplySessionGoalRevisionRequest, ApproveSlackUserLinkAccessRequest, ArtifactCatalogKind, AtlassianLifecycleActionRequest, AttachViewerRequest, BeginSessionRealtimeRequest, BrowserActionRequest, BrowserDomReadRequest, BrowserDownloadSaveRequest, BrowserOpenTargetRequest, BrowserSessionAttachmentRequest, BrowserSessionLifecycleRequest, ChangeMachineAudienceRequest, ChangePreferenceRegistryScopeRequest, ClaudeSubscriptionOAuthCompleteRequest, ClaudeSubscriptionOAuthStartRequest, ClaudeSubscriptionSetupTokenRequest as ClaudeSubscriptionSetupTokenRequest2, ClearWorkspaceAllowanceRequest, CodexAppsDesignationRequest as CodexAppsDesignationRequest2, CodexRealtimeWebrtcRequest, CodexSourceRequest as CodexSourceRequest2, CompanyProfileDiffRequest, ComputerActionRequest, ComputerNativeCallRequest, ComputerSessionAttachmentRequest, ComputerSessionLifecycleRequest, ConfigureOrganizationRecoveryPolicyRequest, CorrectPreferenceRegistryRequest, CreateAdditionalOrganizationRequest, CreateApiKeyRequest, CreateAutomationSourceRequest, CreateAutomationTriggerRequest, CreateBillingPortalRequest, CreateBrowserIdentityRequest, CreateBrowserSessionRequest, CreateCapabilityCatalogItemRequest, CreateChannelRequest, CreateCheckoutRequest, CreateComputerSessionRequest, CreateConnectionRequest, CreateDocumentBaseRequest, CreateFeedbackRequest, CreateFileUploadRequest as CreateFileUploadRequest2, CreateInteractionInterventionRequest, CreateKnowledgeDropRequest, CreateNetworkRouteRequest, CreateOrganizationApiKeyRequest, CreateOrganizationInvitationRequest, CreateOrganizationProviderCustomModelRequest, CreateOrganizationRequest, CreateOrganizationServiceAccountRequest, CreateOrganizationWebhookRequest, CreateOrganizationWorkspaceRequest, CreatePersonalApiKeyRequest, CreatePrReviewAppRegistrationRequest, CreatePrReviewRepositoryBindingRequest, CreatePreferenceRegistryProposalRequest, CreateRigRequest, CreateScheduledTaskRequest as CreateScheduledTaskRequest2, CreateSessionRequest, CreateSiteAuthConnectionRequest, CreateWorkspaceArtifactRequest, CreateWorkspaceGatewayCustomModelRequest as CreateWorkspaceGatewayCustomModelRequest2, CreateWorkspaceInstructionPolicyDraftRequest, CreateWorkspaceInstructionPolicyOnboardingProposalRequest, CreateWorkspaceOpenRouterCustomModelRequest, CreateWorkspaceOpperCustomModelRequest, CreateWorkspaceRequest, CreateWorkspaceWebhookRequest, DeactivatePreferenceRegistryRequest, DeleteOrganizationProviderCustomModelRequest, DeleteSessionQueueItemRequest, DeleteWorkspaceGatewayCustomModelRequest as DeleteWorkspaceGatewayCustomModelRequest2, DeleteWorkspaceOpenRouterCustomModelRequest, DeleteWorkspaceOpperCustomModelRequest, DeviceEnrollmentApproveRequest, DisableOrganizationRecoveryPolicyRequest, EditSessionQueueItemRequest, EnableCapabilityRequest, EndSessionRealtimeRequest, EnsureWorkspaceRequest, ExternalAuthInteractiveRequest, ExternalAuthRunRequest, FikenInstallRequest as FikenInstallRequest2, FikenOAuthStartRequest, FileListRequest as FileListRequest2, ForkSessionRequest, FsDeleteRequest, FsListBatchRequest, FsListRequest, FsMkdirRequest, FsMoveRequest, FsReadRequest, FsWriteRequest, GatewayRealtimeConnectRequest, GetMyUsageRequest, GetUsageRequest, GitDiffRequest, GitLogRequest, GitReadBatchRequest, GitShowRequest, GitStatusRequest, GrantSessionAdminAccessRequest, GrantWorkspaceCreditsRequest, ImportArchivedSessionRequest as ImportArchivedSessionRequest2, ImportLegacyWorkspaceInstructionPolicyDraftRequest, InboxItem, InboxSettings, InsightsRange, InstallApiIntegrationRequest, InstallLibrarySkillRequest, InstallPluginRequest, InstallSkillRequest, InstallVaultProviderRequest as InstallVaultProviderRequest2, IssueUserResourceGrantRequest, KnowledgeEntryBatchReviewRequest, KnowledgeEntryListRequest as KnowledgeEntryListRequest3, KnowledgeEntryRestoreRequest, KnowledgeEntryReviewRequest, KnowledgeEntrySaveRequest as KnowledgeEntrySaveRequest2, KnowledgeReviewBatchListRequest, KnowledgeSavePreparationRequest as KnowledgeSavePreparationRequest2, MachineAudiencePreviewRequest, McpConnectionDecision, MemberNotificationsSetting, MemorySlackPublicationActionRequest, MintEnrollTokenRequest, ModelConnectionAccessPolicy, MoveDocumentRequest, MoveSessionQueueItemRequest, MutateIntegrationFacetRequest, OAuthStartRequest, OpenGeniSlackBotInstallRequest, OpenMachinePrivacySettingsRequest, OrganizationModelProviderKind, OrganizationRecoveryOperationCommandRequest, OrganizationUsagePeriod, PrepareSlackUserLinkAccessRequest, PreviewApiIntegrationRequest, PreviewPluginRequest, PreviewSkillImportRequest, ProposeRigChangeRequest, PtyCloseRequest, PtyOpenRequest, PtyResizeRequest, PtyWriteRequest, PublishBrowserRevisionRequest, PublishSandboxFileArtifactRequest, PublishWorkspaceArtifactVersionRequest, PutOrganizationCredentialProviderRequest, PutOrganizationWorkspaceMemberRequest, PutWorkspaceCredentialProviderRequest, ReclassifyDocumentAuthorityRequest, RefreshScheduledTaskAccessRequest, RejectPreferenceRegistryProposalRequest, RejectSessionGoalRevisionRequest, RemoveEnrollmentRequest, RenewSessionRealtimeRequest, ReorderChannelsRequest, ReplaceVaultProviderCredentialsRequest as ReplaceVaultProviderCredentialsRequest2, ReportAuthRunRequest, ResolveInteractionInterventionRequest, RetryOrganizationUserSetupDeliveryRequest, RevokeOrganizationInvitationRequest, RevokeOrganizationModelProviderConnectionRequest, RevokeOrganizationWorkspaceMemberRequest, RollbackCompanyProfileRequest, RollbackSessionGoalRevisionRequest, RollbackWorkspaceArtifactRequest, RollbackWorkspaceInstructionPolicyRequest, RotateSessionMcpCredentialsRequest, RunDocumentDefaultCollectionBackfillRequest, SandboxRecoveryRequest, SaveAtlassianSourcesRequest as SaveAtlassianSourcesRequest2, SaveComposerDraftRequest, SaveNewSessionDraftRequest, SessionCodexAccountPinRequest, SessionControlRequest, SessionHumanInputRequest, SessionInboxMute, SessionMessageSearchRequest, SessionRetryRequest, SessionScopeSubjectId, SessionStatus, SessionVisibility, SetMemberAllowanceRequest, SetSessionModelAccountChoiceRequest, SetSessionUsageLimitRequest, SetWorkspaceAllowanceRequest, SetWorkspaceArtifactStatusRequest, SetWorkspaceDefaultRigRequest, SiteDataCollectionDefinitionRequest as SiteDataCollectionDefinitionRequest3, SiteDataImportRequest as SiteDataImportRequest3, SiteDataQueryRequest as SiteDataQueryRequest3, SiteDataWriteRequest as SiteDataWriteRequest3, SiteLimitProfile, SitePublishWarningFix as SitePublishWarningFix2, SiteSqlExportFormat as SiteSqlExportFormat3, SiteSqlImportRequest as SiteSqlImportRequest3, SiteSqlMigrationRequest as SiteSqlMigrationRequest2, SiteSqlQueryDefinitionRequest as SiteSqlQueryDefinitionRequest3, SiteSqlRunRequest as SiteSqlRunRequest3, SiteSqlSettingsRequest as SiteSqlSettingsRequest2, SiteSqlStatementRequest as SiteSqlStatementRequest3, SiteTakedownRequest, SlackUserLinkAccessMutationRequest, SocialOAuthStartRequest, StartAuthRunRequest, StartOrganizationRecoveryOperationRequest, SteerSessionQueueItemRequest, SubmitComposerDraftRequest, SubscriptionAccountRenameRequest as SubscriptionAccountRenameRequest2, SubscriptionAccountToggleRequest as SubscriptionAccountToggleRequest3, SubscriptionConnectPollRequest, SubscriptionRotationSettingsRequest as SubscriptionRotationSettingsRequest3, SupergrokConnectStartRequest, SupersedePreferenceRegistryRequest, SwapActiveSandboxRequest, SyncSessionRealtimeLedgerRequest, TerminalExecRequest, TriggerAutomationManuallyRequest, UninstallApiIntegrationRequest, UninstallPluginRequest, UninstallSkillRequest, UpdateAutomationSourceRequest, UpdateAutomationTriggerRequest, UpdateBrowserIdentityRequest, UpdateChannelRequest, UpdateCompanyProfileAgentPolicyRequest, UpdateCompanyProfileRequest, UpdateConnectionRequest, UpdateConnectorToolPermissionsRequest, UpdateGitHubActionPolicyRequest, UpdateMachineOperationPolicyRequest, UpdateMemorySlackPublicationConfigurationRequest, UpdateModelAccountPreferencesRequest, UpdateNetworkRouteRequest, UpdateOpenGeniSlackBotOrganizationAccess, UpdateOrganizationAgentAdminAccessRequest, UpdateOrganizationApiKeyRequest, UpdateOrganizationIntegrationPolicyRequest, UpdateOrganizationMcpConnectionRequest, UpdateOrganizationMemberRequest, UpdateOrganizationModelAccountSettingsRequest, UpdateOrganizationModelDefaultsRequest, UpdateOrganizationNameRequest, UpdateOrganizationPrivacySettingsRequest, UpdateOrganizationPrivateSessionSettingsRequest, UpdateOrganizationRetentionPolicyRequest, UpdateOrganizationServiceAccountRequest, UpdateOrganizationWebhookRequest, UpdateOrganizationWorkspaceRequest, UpdatePrReviewAppRegistrationRequest, UpdatePrReviewRepositoryBindingRequest, UpdateRigRequest, UpdateScheduledTaskRequest, UpdateSessionAgentRequest, UpdateSessionArchiveRequest, UpdateSessionAttentionRequest, UpdateSessionChannelRequest, UpdateSessionGoalRequest, UpdateSessionMcpApprovalPolicyRequest, UpdateSessionMcpToolPermissionsRequest, UpdateSessionPinRequest, UpdateSessionRequest, UpdateSessionRetentionRequest, UpdateSessionSkillsRequest, UpdateSessionToolPolicyRequest, UpdateSessionVisibilityRequest, UpdateSiteAuthConnectionRequest, UpdateSlackChannelRoutesRequest, UpdateVideoGenerationPolicyRequest, UpdateWorkspaceArtifactVisibilityRequest, UpdateWorkspaceMemberRequest, UpdateWorkspaceModelAccountSettingsRequest, UpdateWorkspaceModelPolicyRequest, UpdateWorkspaceRequest, UpdateWorkspaceSettingsRequest, UpdateWorkspaceWebhookRequest, UpsertIntegrationFacetRequest, UpsertOrganizationModelProviderConnectionRequest, UpsertSitePublicationRequest as UpsertSitePublicationRequest2, VerifyAuthRunRequest, ViewerHeartbeatRequest, WorkClaimSubjectType, WorkspaceInstructionPolicyDiffRequest, WorkspacePauseTimerRequest } from "@opengeni/contracts";
41042
42029
  var ACTION_REQUEST_SCHEMAS = {
41043
42030
  AcceptOrganizationInvitationRequest,
41044
42031
  AcceptOrganizationRecoveryCustodyRequest,
@@ -41166,6 +42153,7 @@ var ACTION_REQUEST_SCHEMAS = {
41166
42153
  InstallLibrarySkillRequest,
41167
42154
  InstallPluginRequest,
41168
42155
  InstallSkillRequest,
42156
+ InstallVaultProviderRequest: InstallVaultProviderRequest2,
41169
42157
  IssueUserResourceGrantRequest,
41170
42158
  KnowledgeEntryBatchReviewRequest,
41171
42159
  KnowledgeEntryListRequest: KnowledgeEntryListRequest3,
@@ -41211,6 +42199,7 @@ var ACTION_REQUEST_SCHEMAS = {
41211
42199
  RemoveEnrollmentRequest,
41212
42200
  RenewSessionRealtimeRequest,
41213
42201
  ReorderChannelsRequest,
42202
+ ReplaceVaultProviderCredentialsRequest: ReplaceVaultProviderCredentialsRequest2,
41214
42203
  ReportAuthRunRequest,
41215
42204
  ResolveInteractionInterventionRequest,
41216
42205
  RetryOrganizationUserSetupDeliveryRequest,
@@ -41348,6 +42337,31 @@ var PROVIDERS = {
41348
42337
  supergrok: "SuperGrok (xAI)"
41349
42338
  };
41350
42339
  var RULES = [
42340
+ {
42341
+ method: "GET",
42342
+ pattern: /\/vault-providers\/connections$/,
42343
+ text: () => "List connected password managers and deployment availability: 1Password, Proton Pass, Keeper, Bitwarden and external vaults. Returns connection metadata and setup status, not secret values; does not contact providers."
42344
+ },
42345
+ {
42346
+ method: "POST",
42347
+ pattern: /\/vault-providers\/connections$/,
42348
+ text: () => "Connect Proton Pass, Keeper Secrets Manager, a customer-controlled Bitwarden bridge or an external vault. Set ownership and provider-specific credentials. Saved-but-pending setup returns a connection ID; register it with a remote host if needed, then verify using the saved credentials."
42349
+ },
42350
+ {
42351
+ method: "PUT",
42352
+ pattern: /\/vault-providers\/connections\/:connectionId\/credentials$/,
42353
+ text: () => "Replace a connected password manager's credentials without changing its vault links. The same upstream account must verify successfully; pending verification keeps the previously working credential. Never repeat a consumed Keeper one-time token."
42354
+ },
42355
+ {
42356
+ method: "POST",
42357
+ pattern: /\/vault-providers\/connections\/:connectionId\/verify$/,
42358
+ text: () => "Finish a pending vault connection using its already saved credentials. Checks the provider and discovers available vaults without resubmitting a Keeper bootstrap token or remote signing key."
42359
+ },
42360
+ {
42361
+ method: "DELETE",
42362
+ pattern: /\/vault-providers\/connections\/:connectionId$/,
42363
+ text: () => "Disconnect a password manager and unlink its local vault mirrors. Removes Opengeni's stored access; never deletes upstream vaults or items."
42364
+ },
41351
42365
  {
41352
42366
  method: "GET",
41353
42367
  pattern: /\/(codex|claude|supergrok)\/accounts$/,
@@ -42307,7 +43321,7 @@ var PolicyMcpServer = class extends McpServer3 {
42307
43321
  holdsSelectableTool(toolName) {
42308
43322
  const policy = FIRST_PARTY_TOOL_AUTHORIZATION[toolName];
42309
43323
  if (policy.adminAccessRequired) return false;
42310
- const authorized = (policy.allOf?.every((permission) => hasPermission10(this.grant.permissions, permission)) ?? true) && (policy.anyOf?.some((permission) => hasPermission10(this.grant.permissions, permission)) ?? true);
43324
+ const authorized = (policy.allOf?.every((permission) => hasPermission11(this.grant.permissions, permission)) ?? true) && (policy.anyOf?.some((permission) => hasPermission11(this.grant.permissions, permission)) ?? true);
42311
43325
  return authorized && (this.selectedTools === null || this.selectedTools.has(toolName));
42312
43326
  }
42313
43327
  registerTool(name, config, cb) {
@@ -42415,7 +43429,7 @@ function buildOpenGeniMcpServer(deps, grant, options = {}) {
42415
43429
  const json2 = (value) => ({
42416
43430
  content: [{ type: "text", text: JSON.stringify(value, null, 2) }]
42417
43431
  });
42418
- const can = (permission) => hasPermission10(grant.permissions, permission);
43432
+ const can = (permission) => hasPermission11(grant.permissions, permission);
42419
43433
  let socialConnectionsPromise;
42420
43434
  const authorizedSocialConnections = () => socialConnectionsPromise ??= authorizedSocialConnectionsForGrant({
42421
43435
  db: deps.db,
@@ -47532,7 +48546,7 @@ function registerGitHubConnectTool(server, deps, grant, options, json2) {
47532
48546
  const installations = await listWorkspaceGitHubInstallationBindings(deps, grant.workspaceId);
47533
48547
  const status = githubBindingStatus(true, installations);
47534
48548
  const baseUrl = githubBrowserBaseUrl(settings, options.requestOrigin);
47535
- const state = baseUrl && hasPermission10(grant.permissions, "github:manage") ? createSignedState7(deps.githubStateSecret, {
48549
+ const state = baseUrl && hasPermission11(grant.permissions, "github:manage") ? createSignedState7(deps.githubStateSecret, {
47536
48550
  accountId: grant.accountId,
47537
48551
  workspaceId: grant.workspaceId,
47538
48552
  intent: "installation_authority",
@@ -48073,18 +49087,18 @@ function startWorkspaceToolGatewayObservation(observability, input) {
48073
49087
  }
48074
49088
 
48075
49089
  // src/workspace-tool-gateway-secrets.ts
48076
- import { AsyncLocalStorage } from "async_hooks";
49090
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
48077
49091
  import { environmentsEncryptionKeyBytes as environmentsEncryptionKeyBytes5 } from "@opengeni/config";
48078
49092
  import {
48079
49093
  SecretReferenceError,
48080
49094
  collectReferencesDeep
48081
49095
  } from "@opengeni/contracts";
48082
- import { createSecretResolver, hasPermission as hasPermission11 } from "@opengeni/core";
49096
+ import { createSecretResolver, hasPermission as hasPermission12 } from "@opengeni/core";
48083
49097
  import {
48084
49098
  createSecretArgumentResolver,
48085
49099
  secretArgumentMode
48086
49100
  } from "@opengeni/runtime/workspace-tool-gateway";
48087
- var siteSecretContexts = new AsyncLocalStorage();
49101
+ var siteSecretContexts = new AsyncLocalStorage2();
48088
49102
  function withSiteSecretContext(context, run2) {
48089
49103
  return siteSecretContexts.run(context, run2);
48090
49104
  }
@@ -48115,7 +49129,7 @@ function workspaceGatewaySecretArguments(input) {
48115
49129
  if (secretArgumentMode(call.entry) !== "literal") return call.arguments;
48116
49130
  const site = siteSecretContexts.getStore() ?? null;
48117
49131
  const references = collectReferencesDeep(call.arguments);
48118
- if (!site && references.length > 0 && !hasPermission11(input.grant.permissions, "secrets:use", input.grant.permissionMode)) {
49132
+ if (!site && references.length > 0 && !hasPermission12(input.grant.permissions, "secrets:use", input.grant.permissionMode)) {
48119
49133
  throw new SecretReferenceError(
48120
49134
  references.map((reference) => ({
48121
49135
  raw: reference.raw,
@@ -48129,7 +49143,9 @@ function workspaceGatewaySecretArguments(input) {
48129
49143
  workspaceGatewaySecretPrincipal(input.grant, site),
48130
49144
  {
48131
49145
  capabilityEnabled: true,
48132
- ...input.providersForSubject ? { providersForSubject: input.providersForSubject } : {}
49146
+ ...input.providersForSubject ? {
49147
+ providersForSubject: (subjectId) => input.providersForSubject(subjectId, site)
49148
+ } : {}
48133
49149
  }
48134
49150
  );
48135
49151
  const hook = createSecretArgumentResolver({
@@ -48223,7 +49239,7 @@ function workspaceToolGatewayIdentityKey(identity2) {
48223
49239
  }
48224
49240
 
48225
49241
  // src/site-publishing/page-tool-authority.ts
48226
- import { hasPermission as hasPermission12 } from "@opengeni/core";
49242
+ import { hasPermission as hasPermission13 } from "@opengeni/core";
48227
49243
  import {
48228
49244
  getPublishedSiteVersion as getPublishedSiteVersion4,
48229
49245
  getWorkspaceGrant as getWorkspaceGrant3,
@@ -48231,12 +49247,12 @@ import {
48231
49247
  withWorkspaceSubjectRls as withWorkspaceSubjectRls3
48232
49248
  } from "@opengeni/db";
48233
49249
  import { HTTPException as HTTPException37 } from "hono/http-exception";
48234
- var authorities = /* @__PURE__ */ new WeakMap();
49250
+ var authorities2 = /* @__PURE__ */ new WeakMap();
48235
49251
  function isPublishedSiteToolAuthorization(value) {
48236
- return authorities.has(value);
49252
+ return authorities2.has(value);
48237
49253
  }
48238
49254
  function publishedSiteToolAuthority(value) {
48239
- const authority = authorities.get(value);
49255
+ const authority = authorities2.get(value);
48240
49256
  if (!authority) throw new HTTPException37(403, { message: "site_tool_not_authorized" });
48241
49257
  return authority;
48242
49258
  }
@@ -48258,7 +49274,7 @@ async function authorizePublishedSiteTools(deps, domain, fields2) {
48258
49274
  });
48259
49275
  }
48260
49276
  );
48261
- if (!grant2 || !hasPermission12(grant2.permissions, "workspace:read")) throw denied2();
49277
+ if (!grant2 || !hasPermission13(grant2.permissions, "workspace:read")) throw denied2();
48262
49278
  return { host: host2, viewer, grant: grant2 };
48263
49279
  };
48264
49280
  const initial = await read();
@@ -48267,7 +49283,7 @@ async function authorizePublishedSiteTools(deps, domain, fields2) {
48267
49283
  if (!version2) throw new HTTPException37(403, { message: "site_tool_not_authorized" });
48268
49284
  const reauthorize = async () => {
48269
49285
  const live = await read();
48270
- if (live.host.site.id !== host.site.id || live.host.versionId !== version2.id || live.grant.accountId !== grant.accountId || live.grant.workspaceId !== grant.workspaceId || live.grant.subjectId !== grant.subjectId || live.viewer.sessionId !== initial.viewer.sessionId || grant.permissions.some((permission) => !hasPermission12(live.grant.permissions, permission)))
49286
+ if (live.host.site.id !== host.site.id || live.host.versionId !== version2.id || live.grant.accountId !== grant.accountId || live.grant.workspaceId !== grant.workspaceId || live.grant.subjectId !== grant.subjectId || live.viewer.sessionId !== initial.viewer.sessionId || grant.permissions.some((permission) => !hasPermission13(live.grant.permissions, permission)))
48271
49287
  throw new HTTPException37(403, { message: "site_tool_access_changed" });
48272
49288
  };
48273
49289
  Object.freeze(grant.permissions);
@@ -48276,7 +49292,7 @@ async function authorizePublishedSiteTools(deps, domain, fields2) {
48276
49292
  kind: "published_site_tools",
48277
49293
  grant
48278
49294
  });
48279
- authorities.set(authorization, {
49295
+ authorities2.set(authorization, {
48280
49296
  requestedTools: version2.requestedTools,
48281
49297
  origin: { siteId: host.site.id, versionId: version2.id, title: host.site.title },
48282
49298
  reauthorize,
@@ -48378,7 +49394,7 @@ async function prepareWorkspaceToolGateway(routeDeps, authorization, options = {
48378
49394
  );
48379
49395
  const workspace = await requireWorkspace2(tx, scope.workspaceId);
48380
49396
  if (!live || permissions.some(
48381
- (permission) => !hasPermission13(live.permissions, permission, live.permissionMode)
49397
+ (permission) => !hasPermission14(live.permissions, permission, live.permissionMode)
48382
49398
  ) || workspace.accountId !== scope.accountId || workspace.kind !== "shared")
48383
49399
  throw new HTTPException38(403, { message: "service gateway authority changed" });
48384
49400
  }
@@ -48767,7 +49783,7 @@ async function prepareWorkspaceToolGatewayForGrantInternal(routeDeps, grant, all
48767
49783
  const firstPartyServers = await Promise.all([
48768
49784
  ...gatewayServerIds.has("opengeni") ? [inMemoryMcpRegistration("opengeni", buildOpenGeniMcpServer(deps, grant))] : [],
48769
49785
  ...gatewayServerIds.has("files") ? [inMemoryMcpRegistration("files", buildFilesMcpServer(deps, grant))] : [],
48770
- ...gatewayServerIds.has("docs") && hasPermission13(grant.permissions, "documents:search") ? [
49786
+ ...gatewayServerIds.has("docs") && hasPermission14(grant.permissions, "documents:search") ? [
48771
49787
  inMemoryMcpRegistration(
48772
49788
  "docs",
48773
49789
  buildDocumentsMcpServer(
@@ -48854,7 +49870,11 @@ async function prepareWorkspaceToolGatewayForGrantInternal(routeDeps, grant, all
48854
49870
  db: routeDeps.db,
48855
49871
  settings: gatewaySettings,
48856
49872
  grant,
48857
- providersForSubject: (subjectId) => vaultProviderRegistryFor(routeDeps, { workspaceId: grant.workspaceId, subjectId })
49873
+ providersForSubject: (subjectId, site) => vaultProviderRegistryFor(routeDeps, {
49874
+ workspaceId: grant.workspaceId,
49875
+ subjectId,
49876
+ ...site ? { executionContext: { siteId: site.siteId } } : {}
49877
+ })
48858
49878
  }),
48859
49879
  mapDefinition: (definition) => {
48860
49880
  if (options.target && definition.approvalAuthorityDigest === void 0) {
@@ -48988,10 +50008,10 @@ function workspaceToolGatewaySettingsForGrant(settings, grant, allowedIdentities
48988
50008
  ...settings,
48989
50009
  mcpServers: settings.mcpServers.filter((server) => {
48990
50010
  if (allowedServerIds && !allowedServerIds.has(server.id)) return false;
48991
- if (server.id === "docs" && !hasPermission13(grant.permissions, "documents:search")) {
50011
+ if (server.id === "docs" && !hasPermission14(grant.permissions, "documents:search")) {
48992
50012
  return false;
48993
50013
  }
48994
- if (server.id === "files" && !hasPermission13(grant.permissions, "files:read")) return false;
50014
+ if (server.id === "files" && !hasPermission14(grant.permissions, "files:read")) return false;
48995
50015
  return true;
48996
50016
  })
48997
50017
  };
@@ -50046,10 +51066,10 @@ function renderMcpOAuthExpiredPage(message) {
50046
51066
  async function listConsentWorkspaces(deps, context) {
50047
51067
  const readableWorkspaceIds = [
50048
51068
  ...new Set(
50049
- context.workspaceGrants.filter((grant) => hasPermission14(grant.permissions, "workspace:read")).map((grant) => grant.workspaceId)
51069
+ context.workspaceGrants.filter((grant) => hasPermission15(grant.permissions, "workspace:read")).map((grant) => grant.workspaceId)
50050
51070
  )
50051
51071
  ];
50052
- const readableAccountIds = context.accountGrants.filter((grant) => hasPermission14(grant.permissions, "workspace:read")).map((grant) => grant.accountId);
51072
+ const readableAccountIds = context.accountGrants.filter((grant) => hasPermission15(grant.permissions, "workspace:read")).map((grant) => grant.accountId);
50053
51073
  const [fromGrants, memberships, shared] = await Promise.all([
50054
51074
  Promise.all(readableWorkspaceIds.map((workspaceId) => getWorkspace2(deps.db, workspaceId))),
50055
51075
  listWorkspacesForSubject(deps.db, context.subjectId),
@@ -50156,7 +51176,7 @@ async function consentOrganizations(deps, context) {
50156
51176
  personal: workspace.kind === "personal"
50157
51177
  })),
50158
51178
  grantable: canonical.filter(
50159
- (permission) => accountGrant !== void 0 && hasPermission14(accountGrant.permissions, permission) || workspaceGrants.some((grant) => hasPermission14(grant.permissions, permission))
51179
+ (permission) => accountGrant !== void 0 && hasPermission15(accountGrant.permissions, permission) || workspaceGrants.some((grant) => hasPermission15(grant.permissions, permission))
50160
51180
  )
50161
51181
  };
50162
51182
  });
@@ -51271,7 +52291,7 @@ import {
51271
52291
  } from "@opengeni/contracts";
51272
52292
  import {
51273
52293
  DestinationPolicyError as DestinationPolicyError2,
51274
- pinnedFetch as pinnedFetch4
52294
+ pinnedFetch as pinnedFetch5
51275
52295
  } from "@opengeni/network";
51276
52296
  var RESPONSE_EXCERPT_BYTES = 1024;
51277
52297
  var PROVIDER_RESPONSE_BYTES = 5 * 1024 * 1024;
@@ -51393,7 +52413,7 @@ async function sendIntegrationEndpointTest(input) {
51393
52413
  const base = { request: input.body, credentials: null };
51394
52414
  let response;
51395
52415
  try {
51396
- response = await (input.fetch ?? pinnedFetch4)(
52416
+ response = await (input.fetch ?? pinnedFetch5)(
51397
52417
  input.url,
51398
52418
  {
51399
52419
  method: "POST",
@@ -52021,7 +53041,7 @@ import { HTTPException as HTTPException45 } from "hono/http-exception";
52021
53041
  import {
52022
53042
  accountScopedApiKeyWorkspaceAuthority as accountScopedApiKeyWorkspaceAuthority2,
52023
53043
  organizationApiKeyAccess,
52024
- hasPermission as hasPermission15,
53044
+ hasPermission as hasPermission16,
52025
53045
  organizationWorkspaceInScope,
52026
53046
  requireAccessContext as requireAccessContext4,
52027
53047
  requireAccessGrantAuthorization as requireAccessGrantAuthorization7,
@@ -52256,7 +53276,7 @@ function ensureOrganizationPolicyDelegable(context, policy, legacy = false) {
52256
53276
  const authority = accountScopedApiKeyWorkspaceAuthority2(context);
52257
53277
  const source = context.credential?.policy;
52258
53278
  if (!authority || authority.permissionMode !== "explicit" || !source) return;
52259
- const requested = legacy ? Permission2.options.filter((permission) => hasPermission15(policy.permissions, permission)) : policy.permissions;
53279
+ const requested = legacy ? Permission2.options.filter((permission) => hasPermission16(policy.permissions, permission)) : policy.permissions;
52260
53280
  if (requested.some((permission) => !source.permissions.includes(permission)))
52261
53281
  throw new HTTPException45(403, {
52262
53282
  message: "cannot delegate permissions beyond organization key policy"
@@ -52574,7 +53594,7 @@ import { HTTPException as HTTPException48 } from "hono/http-exception";
52574
53594
  // src/workspace-tool-target-fence.ts
52575
53595
  import {
52576
53596
  externalContinuationCommitAuthorizer as externalContinuationCommitAuthorizer2,
52577
- hasPermission as hasPermission16,
53597
+ hasPermission as hasPermission17,
52578
53598
  isVerifiedOrganizationServiceAuthorization as isVerifiedOrganizationServiceAuthorization3
52579
53599
  } from "@opengeni/core";
52580
53600
  import {
@@ -52629,7 +53649,7 @@ function targetFenceCaller(deps, authorization, reauthorize) {
52629
53649
  grant.workspaceId
52630
53650
  );
52631
53651
  if (!live || permissions.some(
52632
- (permission) => !hasPermission16(live.permissions, permission, live.permissionMode)
53652
+ (permission) => !hasPermission17(live.permissions, permission, live.permissionMode)
52633
53653
  ))
52634
53654
  throw new HTTPException47(403, { message: "service gateway authority changed" });
52635
53655
  }
@@ -53184,7 +54204,7 @@ import {
53184
54204
  CodemodeCallRequest,
53185
54205
  CodemodeCallSubmission
53186
54206
  } from "@opengeni/contracts";
53187
- import { hasPermission as hasPermission17, isDeveloperSetupGrant, requireSessionAuthorization as requireSessionAuthorization6 } from "@opengeni/core";
54207
+ import { hasPermission as hasPermission18, isDeveloperSetupGrant, requireSessionAuthorization as requireSessionAuthorization6 } from "@opengeni/core";
53188
54208
  import {
53189
54209
  CodemodeToolApprovalRequiredError,
53190
54210
  getActiveSessionTurnForExecution,
@@ -53228,7 +54248,7 @@ function codemodeSessionProxyPermissions(settings, session) {
53228
54248
  const selection = allowedFirstPartyMcpToolsForSession2(settings, session.firstPartyMcpTools);
53229
54249
  const requiredBySelection = /* @__PURE__ */ new Set([
53230
54250
  "workspace:read",
53231
- ...permissionsRequiredByFirstPartyTools(selection)
54251
+ ...permissionsRequiredByFirstPartyTools2(selection)
53232
54252
  ]);
53233
54253
  return CODEMODE_SESSION_PROXY_PERMISSION_CEILING.filter(
53234
54254
  (permission) => requiredBySelection.has(permission) && sessionPermissions.includes(permission)
@@ -53349,7 +54369,7 @@ function codemodeAuthorityForGrant(grant) {
53349
54369
  };
53350
54370
  }
53351
54371
  function isCodemodeGrant(grant) {
53352
- return hasPermission17(grant.permissions, "codemode:call") && codemodeAuthorityForGrant(grant) !== null;
54372
+ return hasPermission18(grant.permissions, "codemode:call") && codemodeAuthorityForGrant(grant) !== null;
53353
54373
  }
53354
54374
  function requireMatchingCodemodeCatalog(authority, catalog) {
53355
54375
  if (!catalog) throw new CodemodeCatalogNotReadyError();
@@ -53720,7 +54740,7 @@ import {
53720
54740
  siteSessionOriginFromMetadata,
53721
54741
  withSiteSessionOrigin as withSiteSessionOrigin4
53722
54742
  } from "@opengeni/core";
53723
- import { getSession as getSession7 } from "@opengeni/db";
54743
+ import { getSession as getSession7, getSessionAuthorityProjection as getSessionAuthorityProjection2 } from "@opengeni/db";
53724
54744
  import { HTTPException as HTTPException50 } from "hono/http-exception";
53725
54745
  var CODEMODE_SDK_PROXY = /^\/v1\/workspaces\/[^/]+\/codemode\/sdk(?:\/|$)/u;
53726
54746
  var SITE_DATA = /^\/v1\/workspaces\/[^/]+\/published-artifacts\/([^/]+)\/(?:data|files)(?:\/|$)/u;
@@ -53752,10 +54772,15 @@ function siteFrameGuard(deps) {
53752
54772
  throw new HTTPException50(404, { message: "Unsupported Site session API path" });
53753
54773
  }
53754
54774
  if (match.sessionId !== null) {
54775
+ const authority = await getSessionAuthorityProjection2(
54776
+ deps.db,
54777
+ grant.workspaceId,
54778
+ match.sessionId
54779
+ );
53755
54780
  const session = await getSession7(deps.db, grant.workspaceId, match.sessionId).catch(
53756
54781
  () => null
53757
54782
  );
53758
- if (!session || !siteOriginsMatch(origin, siteSessionOriginFromMetadata(session.metadata)))
54783
+ if (!authority?.siteAccessRootId || !session || !siteOriginsMatch(origin, siteSessionOriginFromMetadata(session.metadata)))
53759
54784
  throw new HTTPException50(404, { message: "session not found" });
53760
54785
  }
53761
54786
  if (c.req.method !== "GET" && match.operation.id !== "sessions.create") {
@@ -54589,7 +55614,7 @@ import { sessionUsageLimitsProducerEnabled as sessionUsageLimitsProducerEnabled2
54589
55614
  import {
54590
55615
  CodexCompactionV2ProviderLockedError,
54591
55616
  ManagedAuthActorLeaseOutcomeUnknownError,
54592
- hasPermission as hasPermission43,
55617
+ hasPermission as hasPermission44,
54593
55618
  requireAccessGrant as requireAccessGrant64,
54594
55619
  requireAccessGrantAuthorization as requireAccessGrantAuthorization42,
54595
55620
  requireFreshAccessGrant as requireFreshAccessGrant5,
@@ -54607,7 +55632,7 @@ import {
54607
55632
  validateManagedAuthRequestActorLease,
54608
55633
  requireSessionAuthorization as requireSessionAuthorization21,
54609
55634
  SessionAuthorizationDeniedError as SessionAuthorizationDeniedError21,
54610
- withSessionAuthorizationReadReuse,
55635
+ withSessionAuthorizationReadReuse as withSessionAuthorizationReadReuse3,
54611
55636
  SessionAuthorizationUnavailableError as SessionAuthorizationUnavailableError19,
54612
55637
  createUserPresenceRecorder,
54613
55638
  registerProductUsageMetricBaselines,
@@ -56062,9 +57087,9 @@ import {
56062
57087
  import { getOAuthState } from "better-auth/api";
56063
57088
 
56064
57089
  // src/auth/managed-auth-attempt-context.ts
56065
- import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
56066
- var managedAuthAttemptStorage = new AsyncLocalStorage2();
56067
- var managedLinkIntentStorage = new AsyncLocalStorage2();
57090
+ import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
57091
+ var managedAuthAttemptStorage = new AsyncLocalStorage3();
57092
+ var managedLinkIntentStorage = new AsyncLocalStorage3();
56068
57093
  function runManagedSignInConnect(intentId, action) {
56069
57094
  return managedLinkIntentStorage.run(intentId, action);
56070
57095
  }
@@ -88505,10 +89530,11 @@ import {
88505
89530
  isPersonalGitHubConnection as isPersonalGitHubConnection2
88506
89531
  } from "@opengeni/contracts/personal-github";
88507
89532
  import {
88508
- hasPermission as hasPermission18,
89533
+ hasPermission as hasPermission19,
88509
89534
  listOwnConnectionAccountsForGrant,
88510
89535
  hasReservedFikenMetadata,
88511
89536
  ONEPASSWORD_CREDENTIAL_ROLE as ONEPASSWORD_CREDENTIAL_ROLE2,
89537
+ EXTERNAL_VAULT_CREDENTIAL_ROLE,
88512
89538
  hasReservedOpenGeniSlackBotMetadata,
88513
89539
  isOpenGeniSlackBotConnection as isOpenGeniSlackBotConnection3,
88514
89540
  openGeniSlackBotMetadata as openGeniSlackBotMetadata2,
@@ -88574,7 +89600,7 @@ import {
88574
89600
  import { createSignedState as createSignedState10, readSignedState as readSignedState9 } from "@opengeni/github";
88575
89601
  import {
88576
89602
  OAUTH_MAX_RESPONSE_BYTES as OAUTH_MAX_RESPONSE_BYTES5,
88577
- pinnedFetch as pinnedFetch5,
89603
+ pinnedFetch as pinnedFetch6,
88578
89604
  readResponseJsonBounded as readResponseJsonBounded10
88579
89605
  } from "@opengeni/network";
88580
89606
  import { HTTPException as HTTPException62 } from "hono/http-exception";
@@ -89145,7 +90171,7 @@ async function verifyProviderIdentity(deps, definition, token) {
89145
90171
  }
89146
90172
  async function providerFetch3(deps, url, init) {
89147
90173
  try {
89148
- return await pinnedFetch5(
90174
+ return await pinnedFetch6(
89149
90175
  url,
89150
90176
  {
89151
90177
  ...init,
@@ -90489,7 +91515,7 @@ function registerConnectionRoutes(app, deps) {
90489
91515
  connectionId: c.req.param("connectionId"),
90490
91516
  payload: await c.req.json(),
90491
91517
  canManageOrganizationDestination: authorization.accountGrant?.permissions.includes("account:admin") === true,
90492
- canManageWorkspaceDestination: hasPermission18(grant.permissions, "workspace:admin"),
91518
+ canManageWorkspaceDestination: hasPermission19(grant.permissions, "workspace:admin"),
90493
91519
  canManagePersonalDestination: authorization.contextIntegrity && authorization.authenticatedSubjectId === grant.subjectId
90494
91520
  });
90495
91521
  return c.json(ConnectionResponse.parse({ connection }));
@@ -90567,7 +91593,7 @@ function registerConnectionRoutes(app, deps) {
90567
91593
  connectionId: c.req.param("connectionId"),
90568
91594
  payload: await c.req.json(),
90569
91595
  canManageOrganizationDestination: authorization.accountGrant?.permissions.includes("account:admin") === true,
90570
- canManageWorkspaceDestination: hasPermission18(grant.permissions, "workspace:admin"),
91596
+ canManageWorkspaceDestination: hasPermission19(grant.permissions, "workspace:admin"),
90571
91597
  canManagePersonalDestination: authorization.contextIntegrity && authorization.authenticatedSubjectId === grant.subjectId
90572
91598
  });
90573
91599
  return c.json(ConnectionResponse.parse({ connection }));
@@ -90630,6 +91656,7 @@ function registerConnectionRoutes(app, deps) {
90630
91656
  c.req.param("connectionId"),
90631
91657
  grant.subjectId
90632
91658
  );
91659
+ assertNotReservedExternalVaultMetadata(existing?.metadata);
90633
91660
  if (existing && isOpenGeniSlackBotConnection3(existing)) {
90634
91661
  const destination = ConnectorDocumentDestinationSelection.safeParse(
90635
91662
  payload.metadata?.documentDestination
@@ -90644,7 +91671,7 @@ function registerConnectionRoutes(app, deps) {
90644
91671
  if (destinationSelection.authorityKind === "organization" && authorization.accountGrant?.permissions.includes("account:admin") !== true) {
90645
91672
  throw new HTTPException64(403, { message: "missing permission: account:admin" });
90646
91673
  }
90647
- if (destinationSelection.authorityKind === "workspace" && !hasPermission18(grant.permissions, "workspace:admin")) {
91674
+ if (destinationSelection.authorityKind === "workspace" && !hasPermission19(grant.permissions, "workspace:admin")) {
90648
91675
  throw new HTTPException64(403, { message: "missing permission: workspace:admin" });
90649
91676
  }
90650
91677
  if (destinationSelection.authorityKind === "personal" && (!authorization.contextIntegrity || authorization.authenticatedSubjectId !== grant.subjectId)) {
@@ -90863,6 +91890,7 @@ function registerConnectionRoutes(app, deps) {
90863
91890
  if (!existing) {
90864
91891
  throw new HTTPException64(404, { message: "connection not found" });
90865
91892
  }
91893
+ assertNotReservedExternalVaultMetadata(existing.metadata);
90866
91894
  const expectedVersion = c.req.query("expectedVersion");
90867
91895
  if (expectedVersion !== void 0) {
90868
91896
  if (!/^[1-9]\d*$/.test(expectedVersion) || !Number.isSafeInteger(Number(expectedVersion))) {
@@ -91305,12 +92333,20 @@ function assertNotReservedFikenMetadata(metadata) {
91305
92333
  }
91306
92334
  }
91307
92335
  function assertNotReservedOnePasswordMetadata(metadata) {
92336
+ assertNotReservedExternalVaultMetadata(metadata);
91308
92337
  if (metadata?.credentialRole === ONEPASSWORD_CREDENTIAL_ROLE2) {
91309
92338
  throw new HTTPException64(422, {
91310
92339
  message: "1Password connections are created by the verified 1Password install flow"
91311
92340
  });
91312
92341
  }
91313
92342
  }
92343
+ function assertNotReservedExternalVaultMetadata(metadata) {
92344
+ if (metadata?.credentialRole === EXTERNAL_VAULT_CREDENTIAL_ROLE || metadata?.vaultProvider !== void 0) {
92345
+ throw new HTTPException64(422, {
92346
+ message: "Vault connections are managed through the verified vault connection flow"
92347
+ });
92348
+ }
92349
+ }
91314
92350
  function assertNotReservedApiIntegrationOAuthMetadata(metadata) {
91315
92351
  if (metadata?.credentialRole === API_INTEGRATION_OAUTH_CREDENTIAL_ROLE3) {
91316
92352
  throw new HTTPException64(422, {
@@ -91413,7 +92449,7 @@ import {
91413
92449
  import {
91414
92450
  externalActorContinuationForAuthorization as externalActorContinuationForAuthorization10,
91415
92451
  requireAccessGrantAuthorization as requireAccessGrantAuthorization11,
91416
- hasPermission as hasPermission20,
92452
+ hasPermission as hasPermission21,
91417
92453
  requireEnvironmentEncryption as requireEnvironmentEncryption15,
91418
92454
  isFikenConnection as isFikenConnection2,
91419
92455
  isOpenGeniSlackBotConnection as isOpenGeniSlackBotConnection4,
@@ -92922,7 +93958,7 @@ import {
92922
93958
  import { withOrganizationIntegrationPolicyFence as withOrganizationIntegrationPolicyFence6 } from "@opengeni/db/organization-integration-policy";
92923
93959
  import {
92924
93960
  externalActorContinuationForAuthorization as externalActorContinuationForAuthorization9,
92925
- hasPermission as hasPermission19,
93961
+ hasPermission as hasPermission20,
92926
93962
  isDeveloperSetupGrant as isDeveloperSetupGrant2,
92927
93963
  requireSessionAuthorization as requireSessionAuthorization8
92928
93964
  } from "@opengeni/core";
@@ -92948,7 +93984,7 @@ async function connectRequestActor(deps, authorization) {
92948
93984
  preparedOnly: false
92949
93985
  };
92950
93986
  const authority = codemodeAuthorityForGrant(grant);
92951
- if (!authority || isDeveloperSetupGrant2(grant) || PREPARED_MCP_PERMISSIONS.some((permission) => !hasPermission19(grant.permissions, permission)))
93987
+ if (!authority || isDeveloperSetupGrant2(grant) || PREPARED_MCP_PERMISSIONS.some((permission) => !hasPermission20(grant.permissions, permission)))
92952
93988
  throw new HTTPException68(403, { message: "Prepared MCP setup authority required" });
92953
93989
  await requireSessionAuthorization8(deps, grant, {
92954
93990
  sessionId: authority.sessionId,
@@ -93010,7 +94046,7 @@ function assertAgentPreparedConnect(actor, attempt) {
93010
94046
 
93011
94047
  // src/routes/connect.ts
93012
94048
  function registerConnectRoutes(app, deps) {
93013
- const canReadAttempt = (permissions, providerId) => ["x", "reddit", "mcp-install"].includes(providerId) ? hasPermission20(permissions, "workspace:read") : providerId === "github-app" ? hasPermission20(permissions, "github:use") || hasPermission20(permissions, "github:manage") : providerId === "github-lens" ? hasPermission20(permissions, "workspace:read") : hasPermission20(permissions, "connections:read");
94049
+ const canReadAttempt = (permissions, providerId) => ["x", "reddit", "mcp-install"].includes(providerId) ? hasPermission21(permissions, "workspace:read") : providerId === "github-app" ? hasPermission21(permissions, "github:use") || hasPermission21(permissions, "github:manage") : providerId === "github-lens" ? hasPermission21(permissions, "workspace:read") : hasPermission21(permissions, "connections:read");
93014
94050
  app.get("/v1/workspaces/:workspaceId/connect/catalog", async (c) => {
93015
94051
  const authorization = await requireAccessGrantAuthorization11(
93016
94052
  c,
@@ -93024,7 +94060,7 @@ function registerConnectRoutes(app, deps) {
93024
94060
  authorization.grant,
93025
94061
  async (_tx, current) => current
93026
94062
  );
93027
- const canWrite2 = hasPermission20(authorization.grant.permissions, "connections:write");
94063
+ const canWrite2 = hasPermission21(authorization.grant.permissions, "connections:write");
93028
94064
  const personal = isPersonalConnectionOwnerPrincipal(authorization);
93029
94065
  let mcpConfigured = false;
93030
94066
  let credentialConfigured = false;
@@ -93044,7 +94080,7 @@ function registerConnectRoutes(app, deps) {
93044
94080
  configured2 = false;
93045
94081
  }
93046
94082
  const ownership = [
93047
- ...hasPermission20(authorization.grant.permissions, "workspace:admin") ? ["workspace"] : [],
94083
+ ...hasPermission21(authorization.grant.permissions, "workspace:admin") ? ["workspace"] : [],
93048
94084
  ...personal ? ["personal"] : []
93049
94085
  ];
93050
94086
  return ConnectProvider.parse({
@@ -93060,7 +94096,7 @@ function registerConnectRoutes(app, deps) {
93060
94096
  id: "mcp-install",
93061
94097
  label: "Install MCP capability",
93062
94098
  family: "mcp",
93063
- readiness: !external || !hasPermission20(authorization.grant.permissions, "capabilities:manage") ? "unsupported" : deps.settings.integrationsEnabled ? "available" : "needs_configuration",
94099
+ readiness: !external || !hasPermission21(authorization.grant.permissions, "capabilities:manage") ? "unsupported" : deps.settings.integrationsEnabled ? "available" : "needs_configuration",
93064
94100
  ownership: ["workspace"],
93065
94101
  setup: ["installation"]
93066
94102
  }),
@@ -93122,7 +94158,7 @@ function registerConnectRoutes(app, deps) {
93122
94158
  id: "github-app",
93123
94159
  label: "GitHub App installation",
93124
94160
  family: "github",
93125
- readiness: !external || !hasPermission20(authorization.grant.permissions, "github:manage") ? "unsupported" : githubAppMissingSettings3(deps.settings).length === 0 && deps.settings.githubAppSlug?.trim() ? "available" : "needs_configuration",
94161
+ readiness: !external || !hasPermission21(authorization.grant.permissions, "github:manage") ? "unsupported" : githubAppMissingSettings3(deps.settings).length === 0 && deps.settings.githubAppSlug?.trim() ? "available" : "needs_configuration",
93126
94162
  ownership: ["workspace"],
93127
94163
  setup: ["oauth", "installation"]
93128
94164
  }),
@@ -93130,7 +94166,7 @@ function registerConnectRoutes(app, deps) {
93130
94166
  id: "github-lens",
93131
94167
  label: "Opengeni Lens PR review",
93132
94168
  family: "github-lens",
93133
- readiness: !external || !hasPermission20(authorization.grant.permissions, "workspace:admin") || !hasPermission20(authorization.grant.permissions, "secrets:write") ? "unsupported" : credentialConfigured && deps.settings.sandboxBackend !== "selfhosted" && prReviewGitHubAppMissingSettings2(deps.settings).length === 0 ? "available" : "needs_configuration",
94169
+ readiness: !external || !hasPermission21(authorization.grant.permissions, "workspace:admin") || !hasPermission21(authorization.grant.permissions, "secrets:write") ? "unsupported" : credentialConfigured && deps.settings.sandboxBackend !== "selfhosted" && prReviewGitHubAppMissingSettings2(deps.settings).length === 0 ? "available" : "needs_configuration",
93134
94170
  ownership: ["workspace"],
93135
94171
  setup: ["oauth", "installation"]
93136
94172
  }),
@@ -93196,8 +94232,8 @@ function registerConnectRoutes(app, deps) {
93196
94232
  app.get("/v1/workspaces/:workspaceId/connect/accounts", async (c) => {
93197
94233
  const workspaceId = c.req.param("workspaceId");
93198
94234
  const { grant } = await requireAccessGrantAuthorization11(c, deps, workspaceId, "workspace:read");
93199
- const connections = hasPermission20(grant.permissions, "connections:read") ? await listConnectionsMetadata6(deps.db, workspaceId, grant.subjectId) : [];
93200
- const githubInstallations = hasPermission20(grant.permissions, "github:use") || hasPermission20(grant.permissions, "github:manage") ? await listGitHubInstallationAccessForWorkspace2(deps.db, workspaceId) : [];
94235
+ const connections = hasPermission21(grant.permissions, "connections:read") ? await listConnectionsMetadata6(deps.db, workspaceId, grant.subjectId) : [];
94236
+ const githubInstallations = hasPermission21(grant.permissions, "github:use") || hasPermission21(grant.permissions, "github:manage") ? await listGitHubInstallationAccessForWorkspace2(deps.db, workspaceId) : [];
93201
94237
  const lensRegistrations = await listPrReviewAppRegistrations(
93202
94238
  deps.db,
93203
94239
  grant.accountId,
@@ -93346,9 +94382,9 @@ function registerConnectRoutes(app, deps) {
93346
94382
  const before = stored.attempt;
93347
94383
  assertAgentPreparedConnect(actor, before);
93348
94384
  const advancePermission = before.providerId === "mcp-install" ? "capabilities:manage" : permission;
93349
- if (!hasPermission20(authorization.grant.permissions, advancePermission))
94385
+ if (!hasPermission21(authorization.grant.permissions, advancePermission))
93350
94386
  throw new HTTPException69(403, { message: `${advancePermission} required` });
93351
- if (before.mcpSetup && !hasPermission20(authorization.grant.permissions, "capabilities:manage"))
94387
+ if (before.mcpSetup && !hasPermission21(authorization.grant.permissions, "capabilities:manage"))
93352
94388
  throw new HTTPException69(403, { message: "capabilities:manage required" });
93353
94389
  if (before.providerId === "mcp-install") {
93354
94390
  if (action.type !== "credentials")
@@ -93394,7 +94430,7 @@ function registerConnectRoutes(app, deps) {
93394
94430
  }
93395
94431
  if (["github-app", "github-lens"].includes(before.providerId)) {
93396
94432
  const installationPermission = before.providerId === "github-lens" ? "workspace:admin" : "github:manage";
93397
- if (!hasPermission20(authorization.grant.permissions, installationPermission) || before.providerId === "github-lens" && !hasPermission20(authorization.grant.permissions, "secrets:write"))
94433
+ if (!hasPermission21(authorization.grant.permissions, installationPermission) || before.providerId === "github-lens" && !hasPermission21(authorization.grant.permissions, "secrets:write"))
93398
94434
  throw new HTTPException69(403, { message: "Installation management permission required" });
93399
94435
  return c.json(
93400
94436
  await executeConnectOperation({
@@ -93885,7 +94921,7 @@ function registerConnectRoutes(app, deps) {
93885
94921
  authorize: async (tx, attempt, origin) => {
93886
94922
  assertAgentPreparedConnect(actor, attempt);
93887
94923
  const permission = attempt.providerId === "mcp-install" ? "capabilities:manage" : ["x", "reddit"].includes(attempt.providerId) ? attempt.ownership === "workspace" ? "workspace:admin" : "workspace:read" : attempt.providerId === "github-app" ? "github:manage" : attempt.providerId === "github-lens" ? "workspace:admin" : "connections:write";
93888
- if (!hasPermission20(authorization.grant.permissions, permission) || attempt.providerId === "github-lens" && !hasPermission20(authorization.grant.permissions, "secrets:write"))
94924
+ if (!hasPermission21(authorization.grant.permissions, permission) || attempt.providerId === "github-lens" && !hasPermission21(authorization.grant.permissions, "secrets:write"))
93889
94925
  throw new HTTPException69(403, { message: "Connect management permission required" });
93890
94926
  await requireConnectOwnerAuthority(tx, scope, permission, origin);
93891
94927
  if (attempt.providerId === "github-lens")
@@ -93919,7 +94955,7 @@ function registerConnectRoutes(app, deps) {
93919
94955
  throw new HTTPException69(403, {
93920
94956
  message: "Verified Connect authority required"
93921
94957
  });
93922
- if (input.mcpSetup && !hasPermission20(authorization.grant.permissions, "capabilities:manage"))
94958
+ if (input.mcpSetup && !hasPermission21(authorization.grant.permissions, "capabilities:manage"))
93923
94959
  throw new HTTPException69(403, { message: "capabilities:manage required" });
93924
94960
  if (input.providerId === "atlassian")
93925
94961
  throw new HTTPException69(410, { message: ATLASSIAN_NATIVE_RETIRED_MESSAGE2 });
@@ -94101,7 +95137,7 @@ function registerConnectRoutes(app, deps) {
94101
95137
  message: "GitHub App setup requires workspace ownership and explicit installation selection"
94102
95138
  });
94103
95139
  if (input.providerId === "github-lens") {
94104
- if (!hasPermission20(authorization.grant.permissions, "secrets:write"))
95140
+ if (!hasPermission21(authorization.grant.permissions, "secrets:write"))
94105
95141
  throw new HTTPException69(403, { message: "secrets:write required" });
94106
95142
  await requireConnectOwnerAuthority(tx, scope, "secrets:write");
94107
95143
  await requireGitHubLensConnect({ ...deps, db: tx });
@@ -94140,7 +95176,7 @@ function registerConnectRoutes(app, deps) {
94140
95176
  throw new HTTPException69(422, { message: "Select the service connection during setup" });
94141
95177
  if (input.ownership === "personal" && !scope.personalOwnerVerified)
94142
95178
  throw new HTTPException69(403, { message: "personal ownership unavailable" });
94143
- const choices = hasPermission20(authorization.grant.permissions, "connections:read") ? (await listConnectionsMetadata6(tx, workspaceId, scope.subjectId)).filter(
95179
+ const choices = hasPermission21(authorization.grant.permissions, "connections:read") ? (await listConnectionsMetadata6(tx, workspaceId, scope.subjectId)).filter(
94144
95180
  (connection) => connection.status === "active" && (input.ownership === "workspace" ? connection.subjectId === null : connection.subjectId === scope.subjectId)
94145
95181
  ).map((connection) => ({
94146
95182
  value: connection.id,
@@ -94477,7 +95513,7 @@ import {
94477
95513
  requireAccessGrantAuthorization as requireAccessGrantAuthorization12,
94478
95514
  externalActorContinuationForAuthorization as externalActorContinuationForAuthorization11,
94479
95515
  externalContinuationCommitAuthorizer as externalContinuationCommitAuthorizer4,
94480
- hasPermission as hasPermission21
95516
+ hasPermission as hasPermission22
94481
95517
  } from "@opengeni/core";
94482
95518
  function nativeConfirmation(authorization) {
94483
95519
  if (!authorization.contextIntegrity || !authorization.canonicalManagedHumanSession || authorization.authenticatedSubjectId !== authorization.grant.subjectId || !authorization.grant.subjectId.startsWith("user:"))
@@ -94591,7 +95627,7 @@ function registerExternalIdentityLinkRoutes(app, deps) {
94591
95627
  principalKind: "human_session"
94592
95628
  });
94593
95629
  if (!current || current.accountId !== grant.accountId || request.permissions.some(
94594
- (permission) => !hasPermission21(grant.permissions, permission) || !hasPermission21(current.permissions, permission)
95630
+ (permission) => !hasPermission22(grant.permissions, permission) || !hasPermission22(current.permissions, permission)
94595
95631
  ))
94596
95632
  throw new HTTPException70(403, {
94597
95633
  message: "Link permissions exceed your authority in this workspace"
@@ -95466,7 +96502,7 @@ import {
95466
96502
  KnowledgeVectorCreditsDisabledError,
95467
96503
  KnowledgeVectorFundingError,
95468
96504
  KnowledgeVectorQueryRejectedError,
95469
- hasPermission as hasPermission22,
96505
+ hasPermission as hasPermission23,
95470
96506
  knowledgeContextForAccess as knowledgeContextForAccess2,
95471
96507
  requireAccessGrantAuthorization as requireAccessGrantAuthorization14,
95472
96508
  requireSessionAuthorization as requireSessionAuthorization9,
@@ -95562,7 +96598,7 @@ function registerKnowledgeRoutes(app, deps) {
95562
96598
  c.req.param("workspaceId"),
95563
96599
  write ? "documents:manage" : readPermission === "workspace:read" ? void 0 : readPermission
95564
96600
  );
95565
- const permission = write ? "documents:manage" : readPermission === "workspace:read" && hasPermission22(access.grant.permissions, "documents:search") ? "documents:search" : readPermission;
96601
+ const permission = write ? "documents:manage" : readPermission === "workspace:read" && hasPermission23(access.grant.permissions, "documents:search") ? "documents:search" : readPermission;
95566
96602
  return await withAccessGrantSessionRlsContext(deps, access.grant, async () => {
95567
96603
  const context = await knowledgeContextForAccess2(deps, access, permission);
95568
96604
  c.header("cache-control", "private, no-store");
@@ -95892,7 +96928,7 @@ function registerKnowledgeRoutes(app, deps) {
95892
96928
  throw new HTTPException72(403, { message: "Agents cannot change learning settings" });
95893
96929
  const access = await requireAccessGrantAuthorization14(c, deps, context.workspaceId);
95894
96930
  if (request.source?.kind === "chat") {
95895
- if (!hasPermission22(access.grant.permissions, "sessions:control"))
96931
+ if (!hasPermission23(access.grant.permissions, "sessions:control"))
95896
96932
  throw new HTTPException72(403, { message: "Chat settings require session control" });
95897
96933
  await requireSessionAuthorization9(deps, access.grant, {
95898
96934
  sessionId: request.source.id,
@@ -95901,7 +96937,7 @@ function registerKnowledgeRoutes(app, deps) {
95901
96937
  });
95902
96938
  context.actor.settingsScopes = [request.scope];
95903
96939
  } else if (request.source?.kind === "scheduled_task") {
95904
- if (!hasPermission22(access.grant.permissions, "scheduled_tasks:manage"))
96940
+ if (!hasPermission23(access.grant.permissions, "scheduled_tasks:manage"))
95905
96941
  throw new HTTPException72(403, {
95906
96942
  message: "Scheduled task settings require task management"
95907
96943
  });
@@ -97677,7 +98713,7 @@ import {
97677
98713
  requireSessionAuthorization as requireSessionAuthorization11,
97678
98714
  SessionAuthorizationDeniedError as SessionAuthorizationDeniedError10,
97679
98715
  SessionAuthorizationUnavailableError as SessionAuthorizationUnavailableError9,
97680
- VaultError as VaultError2,
98716
+ VaultError as VaultError3,
97681
98717
  vaultErrorFromDatabase as vaultErrorFromDatabase4
97682
98718
  } from "@opengeni/core";
97683
98719
  var PREFIX = "/v1/workspaces/:workspaceId";
@@ -97696,7 +98732,7 @@ function requireRevealAuthority(grant) {
97696
98732
  return;
97697
98733
  }
97698
98734
  if (grant.principalKind !== "human_session" || grant.serviceInitiator) {
97699
- throw new VaultError2(
98735
+ throw new VaultError3(
97700
98736
  "vault_reveal_requires_human",
97701
98737
  "revealing a value needs a person signed in, or an API key with secrets:read"
97702
98738
  );
@@ -97762,7 +98798,7 @@ function registerVaultRoutes(app, deps) {
97762
98798
  async function itemInVault(actor, workspaceId, vaultId, itemId) {
97763
98799
  const item = await vaults().getItem(actor, workspaceId, itemId);
97764
98800
  if (item.vaultId !== vaultId) {
97765
- throw new VaultError2("vault_item_not_found", "item not found", { itemId });
98801
+ throw new VaultError3("vault_item_not_found", "item not found", { itemId });
97766
98802
  }
97767
98803
  return item;
97768
98804
  }
@@ -97908,7 +98944,9 @@ function registerVaultRoutes(app, deps) {
97908
98944
  const payload = await parseRequestJson(c, MoveVaultItemRequest);
97909
98945
  const itemId = c.req.param("itemId");
97910
98946
  await itemInVault(actor, workspaceId, c.req.param("vaultId"), itemId);
97911
- return c.json(await vaults().moveItem(actor, workspaceId, itemId, payload));
98947
+ return c.json(
98948
+ await vaultsWithProviders(actor, workspaceId).moveItem(actor, workspaceId, itemId, payload)
98949
+ );
97912
98950
  })
97913
98951
  );
97914
98952
  app.post(
@@ -97947,7 +98985,7 @@ function registerVaultRoutes(app, deps) {
97947
98985
  );
97948
98986
  const fieldId = c.req.param("fieldId");
97949
98987
  if (!item.fields.some((field) => field.id === fieldId)) {
97950
- throw new VaultError2("vault_field_not_found", "field not found", { fieldId });
98988
+ throw new VaultError3("vault_field_not_found", "field not found", { fieldId });
97951
98989
  }
97952
98990
  return c.json({ versions: await vaults().listFieldVersions(actor, workspaceId, fieldId) });
97953
98991
  })
@@ -98021,7 +99059,7 @@ import {
98021
99059
  revokeOrganizationMcpConnection,
98022
99060
  updateOrganizationMcpConnectionAccess
98023
99061
  } from "@opengeni/db";
98024
- import { hasPermission as hasPermission23, requireAccessContext as requireAccessContext8 } from "@opengeni/core";
99062
+ import { hasPermission as hasPermission24, requireAccessContext as requireAccessContext8 } from "@opengeni/core";
98025
99063
  import { HTTPException as HTTPException77 } from "hono/http-exception";
98026
99064
  import { z as z49 } from "zod";
98027
99065
  function registerOrganizationMcpConnectionRoutes(app, deps) {
@@ -98106,7 +99144,7 @@ async function requireOrganizationPerson2(c, deps) {
98106
99144
  if (context.mode !== "managed" || !context.subjectId.startsWith("user:") || !grant) {
98107
99145
  throw new HTTPException77(404, { message: "organization not found" });
98108
99146
  }
98109
- return { context, organizationId: organizationId2, admin: hasPermission23(grant.permissions, "account:admin") };
99147
+ return { context, organizationId: organizationId2, admin: hasPermission24(grant.permissions, "account:admin") };
98110
99148
  }
98111
99149
  async function requireConnection(deps, organizationId2, connectionId) {
98112
99150
  if (!z49.string().uuid().safeParse(connectionId).success) {
@@ -98174,7 +99212,7 @@ import {
98174
99212
  revokePersonalApiKey
98175
99213
  } from "@opengeni/db";
98176
99214
  import {
98177
- hasPermission as hasPermission24,
99215
+ hasPermission as hasPermission25,
98178
99216
  PERSONAL_API_KEY_TOKEN_PREFIX,
98179
99217
  requireAccessContext as requireAccessContext9
98180
99218
  } from "@opengeni/core";
@@ -98264,7 +99302,7 @@ async function requireOrganizationPerson3(c, deps, mutation) {
98264
99302
  if (context.mode !== "managed" || !context.subjectId.startsWith("user:") || !grant) {
98265
99303
  throw new HTTPException78(404, { message: "organization not found" });
98266
99304
  }
98267
- return { context, organizationId: organizationId2, admin: hasPermission24(grant.permissions, "account:admin") };
99305
+ return { context, organizationId: organizationId2, admin: hasPermission25(grant.permissions, "account:admin") };
98268
99306
  }
98269
99307
  async function projectKeys(deps, keys2) {
98270
99308
  const userIds = [...new Set(keys2.map((key2) => key2.ownerSubjectId.slice("user:".length)))];
@@ -99622,6 +100660,7 @@ import {
99622
100660
  import {
99623
100661
  requireAccessGrant as requireAccessGrant31,
99624
100662
  requireSessionAuthorization as requireSessionAuthorization13,
100663
+ withSessionAuthorizationReadReuse,
99625
100664
  recordWorkspaceUsage as recordWorkspaceUsage5,
99626
100665
  requireLimit as requireLimit6,
99627
100666
  relayConfigFromSettings as relayConfigFromSettings3,
@@ -101632,7 +102671,7 @@ function registerBrowserSessionRoutes(app, deps, options = {}) {
101632
102671
  fileIds: workspaceFileIds
101633
102672
  });
101634
102673
  const ordered = requireAuthorizedBrowserUploadFiles(workspaceFileIds, files);
101635
- const authorities2 = await Promise.all(
102674
+ const authorities3 = await Promise.all(
101636
102675
  ordered.map(async (file) => {
101637
102676
  const signed = await deps.objectStorage.createGetUrl({
101638
102677
  key: file.objectKey,
@@ -101653,7 +102692,7 @@ function registerBrowserSessionRoutes(app, deps, options = {}) {
101653
102692
  );
101654
102693
  await sessionClient.stageWorkspaceFiles({
101655
102694
  operationId: request.operationId,
101656
- files: authorities2
102695
+ files: authorities3
101657
102696
  });
101658
102697
  }
101659
102698
  }
@@ -103126,6 +104165,7 @@ function registerBrowserSessionRoutes(app, deps, options = {}) {
103126
104165
  operationResourcePolicySupported: enrollment.agentCapabilities.operationResourcePolicy === true,
103127
104166
  operationCpuQuotaSupported: enrollment.agentCapabilities.operationCpuQuota === true,
103128
104167
  transactionalFsWriteSupported: enrollment.agentCapabilities.transactionalFsWrite === true,
104168
+ browserControlHttpSupported: enrollment.agentCapabilities.browserControlHttp === true,
103129
104169
  ...deps.settings.agentOpStreamEnabled === true && enrollment.opStream === true && deps.bus.getOpStreamConnection ? {
103130
104170
  opStream: {
103131
104171
  transport: new NatsOpStreamTransport2(
@@ -103369,6 +104409,22 @@ function registerBrowserSessionRoutes(app, deps, options = {}) {
103369
104409
  });
103370
104410
  }
103371
104411
  async function withActiveBrowserController(context, grant, workspaceId, browserSessionId, authorizationOperation, channelOperation, callback, recoverMissing = true, stages) {
104412
+ return await withSessionAuthorizationReadReuse(
104413
+ (authorizationReads) => withActiveBrowserControllerReads(
104414
+ context,
104415
+ grant,
104416
+ workspaceId,
104417
+ browserSessionId,
104418
+ authorizationOperation,
104419
+ channelOperation,
104420
+ callback,
104421
+ recoverMissing,
104422
+ stages,
104423
+ authorizationReads
104424
+ )
104425
+ );
104426
+ }
104427
+ async function withActiveBrowserControllerReads(context, grant, workspaceId, browserSessionId, authorizationOperation, channelOperation, callback, recoverMissing, stages, authorizationReads) {
103372
104428
  try {
103373
104429
  const record8 = await getBrowserSessionControlRecord(deps.db, {
103374
104430
  accountId: grant.accountId,
@@ -103376,17 +104432,18 @@ function registerBrowserSessionRoutes(app, deps, options = {}) {
103376
104432
  browserSessionId
103377
104433
  });
103378
104434
  stages?.mark("record");
103379
- const sourceAuthorization = await authorizeSourceSession2(
103380
- deps,
103381
- grant,
103382
- record8.sourceSessionId,
103383
- authorizationOperation
103384
- );
104435
+ const sourceSessionNeeded = record8.session.placement?.kind === "connected_machine" || !record8.controllerHostSandboxGroupId;
104436
+ const [authorized, sourceRead] = await Promise.allSettled([
104437
+ authorizeSourceSession2(deps, grant, record8.sourceSessionId, authorizationOperation),
104438
+ sourceSessionNeeded ? requireSourceSession(deps, workspaceId, record8.sourceSessionId) : Promise.resolve(null)
104439
+ ]);
104440
+ if (authorized.status === "rejected") throw authorized.reason;
104441
+ if (sourceRead.status === "rejected") throw sourceRead.reason;
104442
+ const sourceAuthorization = authorized.value;
103385
104443
  stages?.mark("authorize");
103386
- let sourceSession = null;
104444
+ let sourceSession = sourceRead.value;
103387
104445
  if (record8.session.placement?.kind === "connected_machine") {
103388
- sourceSession = await requireSourceSession(deps, workspaceId, record8.sourceSessionId);
103389
- if (sourceSession.activeSandboxId !== record8.session.placement.sandboxId) {
104446
+ if (sourceSession?.activeSandboxId !== record8.session.placement.sandboxId) {
103390
104447
  return await throwBrowserSourcePlacementChanged(
103391
104448
  grant,
103392
104449
  record8.sourceSessionId,
@@ -103413,6 +104470,7 @@ function registerBrowserSessionRoutes(app, deps, options = {}) {
103413
104470
  let controllerTransportFailed = false;
103414
104471
  const controllerRecoveryState = { attempted: false };
103415
104472
  const run2 = async (placement, provisionedClient) => {
104473
+ authorizationReads.handOffToToolDispatch();
103416
104474
  const client = provisionedClient ?? connectController(deps, grant, record8, placement);
103417
104475
  const tokens = (0, browser_controller_authority_exports.deriveBrowserSessionControllerTokens)({
103418
104476
  rootSecret: browserAuthorityRoot(deps),
@@ -105087,9 +106145,10 @@ import {
105087
106145
  touchComputerSessionController
105088
106146
  } from "@opengeni/db";
105089
106147
  import {
105090
- hasPermission as hasPermission25,
106148
+ hasPermission as hasPermission26,
105091
106149
  requireAccessGrant as requireAccessGrant32,
105092
106150
  requireSessionAuthorization as requireSessionAuthorization14,
106151
+ withSessionAuthorizationReadReuse as withSessionAuthorizationReadReuse2,
105093
106152
  relayConfigFromSettings as relayConfigFromSettings4,
105094
106153
  resolveChannelAMachineConnection as resolveChannelAMachineConnection2,
105095
106154
  resolveSessionSandboxRuntime as resolveSessionSandboxRuntime4,
@@ -105812,7 +106871,7 @@ function registerComputerSessionRoutes(app, deps, options = {}) {
105812
106871
  }
105813
106872
  );
105814
106873
  async function authorizeHumanFrameInput(grant, record8, placement) {
105815
- if ((record8.session.placement.kind === "connected_machine" || record8.session.placement.kind === "attached_device") && placement.screenControlAllowed !== true || record8.session.placement.kind === "sandbox_group" && deps.settings.sandboxDesktopInteractive === false || grant.principalKind === "agent_attempt" || !hasPermission25(grant.permissions, "sessions:control"))
106874
+ if ((record8.session.placement.kind === "connected_machine" || record8.session.placement.kind === "attached_device") && placement.screenControlAllowed !== true || record8.session.placement.kind === "sandbox_group" && deps.settings.sandboxDesktopInteractive === false || grant.principalKind === "agent_attempt" || !hasPermission26(grant.permissions, "sessions:control"))
105816
106875
  return false;
105817
106876
  try {
105818
106877
  await requireSessionAuthorization14(deps, grant, {
@@ -105983,6 +107042,32 @@ function registerComputerSessionRoutes(app, deps, options = {}) {
105983
107042
  }
105984
107043
  }
105985
107044
  );
107045
+ async function routedMachineConnection(handle, grant, sourceSession, sandboxId) {
107046
+ const machineAuthority = await handle.machineAuthority();
107047
+ const sandbox = await getSandbox5(
107048
+ deps.db,
107049
+ {
107050
+ accountId: grant.accountId,
107051
+ workspaceId: sourceSession.workspaceId,
107052
+ subjectId: machineAuthority.subjectId
107053
+ },
107054
+ sandboxId
107055
+ );
107056
+ if (sandbox?.kind !== "selfhosted" || !sandbox.enrollmentId) {
107057
+ throw new ComputerSessionStateError("Connected Machine placement is unavailable");
107058
+ }
107059
+ return await resolveChannelAMachineConnection2(
107060
+ deps.db,
107061
+ {
107062
+ accountId: grant.accountId,
107063
+ workspaceId: sourceSession.workspaceId,
107064
+ sessionId: sourceSession.id,
107065
+ machineWorkspaceId: sandbox.workspaceId,
107066
+ enrollmentId: sandbox.enrollmentId
107067
+ },
107068
+ machineAuthority
107069
+ );
107070
+ }
105986
107071
  async function withComputerPlacement(sourceSession, grant, expectedPlacement, expectedPlacementInstanceId, operation, waitSignal, callback) {
105987
107072
  if (expectedPlacement?.kind === "external_provider") {
105988
107073
  throw new BrowserControlUnsupportedError3(
@@ -106030,6 +107115,7 @@ function registerComputerSessionRoutes(app, deps, options = {}) {
106030
107115
  operationResourcePolicySupported: enrollment.agentCapabilities.operationResourcePolicy === true,
106031
107116
  operationCpuQuotaSupported: enrollment.agentCapabilities.operationCpuQuota === true,
106032
107117
  transactionalFsWriteSupported: enrollment.agentCapabilities.transactionalFsWrite === true,
107118
+ browserControlHttpSupported: enrollment.agentCapabilities.browserControlHttp === true,
106033
107119
  ...deps.settings.agentOpStreamEnabled === true && enrollment.opStream === true && deps.bus.getOpStreamConnection ? {
106034
107120
  opStream: {
106035
107121
  transport: new NatsOpStreamTransport3(
@@ -106077,30 +107163,7 @@ function registerComputerSessionRoutes(app, deps, options = {}) {
106077
107163
  const resolved = await handle.routingSession.prime();
106078
107164
  let screenControlAllowed = false;
106079
107165
  if (operation !== "computer.end" && resolved.kind === "selfhosted" && resolved.sandboxId) {
106080
- const machineAuthority = await handle.machineAuthority();
106081
- const sandbox = await getSandbox5(
106082
- deps.db,
106083
- {
106084
- accountId: grant.accountId,
106085
- workspaceId: sourceSession.workspaceId,
106086
- subjectId: machineAuthority.subjectId
106087
- },
106088
- resolved.sandboxId
106089
- );
106090
- if (sandbox?.kind !== "selfhosted" || !sandbox.enrollmentId) {
106091
- throw new ComputerSessionStateError("Connected Machine placement is unavailable");
106092
- }
106093
- const enrollment = await resolveChannelAMachineConnection2(
106094
- deps.db,
106095
- {
106096
- accountId: grant.accountId,
106097
- workspaceId: sourceSession.workspaceId,
106098
- sessionId: sourceSession.id,
106099
- machineWorkspaceId: sandbox.workspaceId,
106100
- enrollmentId: sandbox.enrollmentId
106101
- },
106102
- machineAuthority
106103
- );
107166
+ const enrollment = handle.pinnedMachine?.sandboxId === resolved.sandboxId ? handle.pinnedMachine.enrollment : await routedMachineConnection(handle, grant, sourceSession, resolved.sandboxId);
106104
107167
  if (!enrollment?.connectionInstanceId) {
106105
107168
  throw new ComputerSessionStateError("Connected Machine is unavailable");
106106
107169
  }
@@ -106262,17 +107325,37 @@ function registerComputerSessionRoutes(app, deps, options = {}) {
106262
107325
  });
106263
107326
  }
106264
107327
  async function withActiveComputerController(context, grant, workspaceId, computerSessionId, authorizationOperation, channelOperation, callback, recoverMissing = true) {
107328
+ return await withSessionAuthorizationReadReuse2(
107329
+ (authorizationReads) => withActiveComputerControllerReads(
107330
+ context,
107331
+ grant,
107332
+ workspaceId,
107333
+ computerSessionId,
107334
+ authorizationOperation,
107335
+ channelOperation,
107336
+ callback,
107337
+ recoverMissing,
107338
+ authorizationReads
107339
+ )
107340
+ );
107341
+ }
107342
+ async function withActiveComputerControllerReads(context, grant, workspaceId, computerSessionId, authorizationOperation, channelOperation, callback, recoverMissing, authorizationReads) {
106265
107343
  try {
106266
107344
  const record8 = await getComputerSessionControlRecord2(deps.db, {
106267
107345
  accountId: grant.accountId,
106268
107346
  workspaceId,
106269
107347
  computerSessionId
106270
107348
  });
106271
- await authorizeSourceSession3(deps, grant, record8.sourceSessionId, authorizationOperation);
106272
- let sourceSession = null;
107349
+ const sourceSessionNeeded = record8.session.placement?.kind !== "sandbox_group";
107350
+ const [authorized, sourceRead] = await Promise.allSettled([
107351
+ authorizeSourceSession3(deps, grant, record8.sourceSessionId, authorizationOperation),
107352
+ sourceSessionNeeded ? requireSourceSession2(deps, workspaceId, record8.sourceSessionId) : Promise.resolve(null)
107353
+ ]);
107354
+ if (authorized.status === "rejected") throw authorized.reason;
107355
+ if (sourceRead.status === "rejected") throw sourceRead.reason;
107356
+ let sourceSession = sourceRead.value;
106273
107357
  if (record8.session.placement?.kind === "connected_machine") {
106274
- sourceSession = await requireSourceSession2(deps, workspaceId, record8.sourceSessionId);
106275
- if (sourceSession.activeSandboxId !== record8.session.placement.sandboxId) {
107358
+ if (sourceSession?.activeSandboxId !== record8.session.placement.sandboxId) {
106276
107359
  return await throwComputerSourcePlacementChanged(
106277
107360
  grant,
106278
107361
  record8.sourceSessionId,
@@ -106294,6 +107377,7 @@ function registerComputerSessionRoutes(app, deps, options = {}) {
106294
107377
  throw new ComputerSessionStateError("ComputerSession controller authority changed");
106295
107378
  }
106296
107379
  const run2 = async (placement) => {
107380
+ authorizationReads.handOffToToolDispatch();
106297
107381
  const client = connectController2(grant, record8, placement);
106298
107382
  const tokens = (0, browser_controller_authority_exports.deriveComputerSessionControllerTokens)({
106299
107383
  rootSecret: controllerAuthorityRoot(deps),
@@ -106929,7 +108013,7 @@ function createVaultInteractionSecretsPort(deps) {
106929
108013
  return createSecretResolver2({ db: deps.db, encryptionKey }, principal, {
106930
108014
  capabilityEnabled: await secretsEnabled(principal),
106931
108015
  ...providersFor ? {
106932
- providersForSubject: (subjectId) => providersFor(principal.workspaceId, subjectId)
108016
+ providersForSubject: (subjectId) => providersFor(principal.workspaceId, subjectId, principal)
106933
108017
  } : {}
106934
108018
  });
106935
108019
  },
@@ -106983,7 +108067,7 @@ import { deleteCookie, setCookie } from "hono/cookie";
106983
108067
  import { HTTPException as HTTPException87 } from "hono/http-exception";
106984
108068
  import {
106985
108069
  githubAppActionPolicyActor,
106986
- hasPermission as hasPermission27,
108070
+ hasPermission as hasPermission28,
106987
108071
  listGitHubActionPolicyActors,
106988
108072
  personalGitHubActionPolicyActor,
106989
108073
  requireAccessGrant as requireAccessGrant33,
@@ -106999,7 +108083,7 @@ import { HTTPException as HTTPException86 } from "hono/http-exception";
106999
108083
  import {
107000
108084
  externalActorContinuationForAuthorization as externalActorContinuationForAuthorization12,
107001
108085
  requireConnectOwnerAuthority as requireConnectOwnerAuthority3,
107002
- hasPermission as hasPermission26
108086
+ hasPermission as hasPermission27
107003
108087
  } from "@opengeni/core";
107004
108088
  async function integrationCommitGrant(authorization, permissions, request) {
107005
108089
  const grant = structuredClone(authorization.grant);
@@ -107016,7 +108100,7 @@ async function integrationCommitGrant(authorization, permissions, request) {
107016
108100
  const secret = resolveFirstPartyDelegationSecret6(request.settings);
107017
108101
  const signed = token && secret ? await verifyDelegatedAccessToken2(secret, token) : null;
107018
108102
  if (signed) {
107019
- const matches = (value) => value.accountId === state.accountId && value.workspaceId === state.workspaceId && value.subjectId === state.subjectId && required.every((permission) => hasPermission26(value.permissions, permission));
108103
+ const matches = (value) => value.accountId === state.accountId && value.workspaceId === state.workspaceId && value.subjectId === state.subjectId && required.every((permission) => hasPermission27(value.permissions, permission));
107020
108104
  if (!matches(signed))
107021
108105
  throw new HTTPException86(403, { message: "Integration bearer authority mismatch" });
107022
108106
  return {
@@ -107094,7 +108178,7 @@ function registerGitHubRoutes(app, deps) {
107094
108178
  const installations = missing.length === 0 ? await listWorkspaceGitHubInstallationBindings(deps, grant.workspaceId) : [];
107095
108179
  const status = githubBindingStatus(missing.length === 0, installations);
107096
108180
  const setupMode = settings.productAccessMode === "managed" ? "platform" : "operator";
107097
- const canManage = !externalActorContinuationForAuthorization13(access) && hasPermission27(grant.permissions, "github:manage");
108181
+ const canManage = !externalActorContinuationForAuthorization13(access) && hasPermission28(grant.permissions, "github:manage");
107098
108182
  const returnPath = githubSessionReturnPath(c.req.query("returnPath"), grant.workspaceId);
107099
108183
  const connectState = missing.length === 0 && slug && canManage ? createSignedState13(githubStateSecret, {
107100
108184
  accountId: grant.accountId,
@@ -107888,7 +108972,7 @@ function githubRepositoryBranchesRouteError(error) {
107888
108972
  return new HTTPException87(502, { message: "GitHub branch discovery is unavailable" });
107889
108973
  }
107890
108974
  function requirePublicGitHubRepositoryVerificationPermission(grant) {
107891
- if (hasPermission27(grant.permissions, "sessions:create") || hasPermission27(grant.permissions, "sessions:control")) {
108975
+ if (hasPermission28(grant.permissions, "sessions:create") || hasPermission28(grant.permissions, "sessions:control")) {
107892
108976
  return;
107893
108977
  }
107894
108978
  throw new HTTPException87(403, {
@@ -108763,7 +109847,7 @@ import {
108763
109847
  buildConnectionTokenResolver as buildConnectionTokenResolver8,
108764
109848
  getConnectionMetadata as getConnectionMetadata13,
108765
109849
  getPersonalGitHubRepositorySelectionState as getPersonalGitHubRepositorySelectionState3,
108766
- getSessionAuthorityProjection as getSessionAuthorityProjection2,
109850
+ getSessionAuthorityProjection as getSessionAuthorityProjection3,
108767
109851
  getSessionTurnForAttempt,
108768
109852
  resolveAcceptedConnectionUse
108769
109853
  } from "@opengeni/db";
@@ -108946,7 +110030,7 @@ async function resolveBrokerAuthority(deps, secret, claims, routeId) {
108946
110030
  claims.sessionId,
108947
110031
  claims.attemptId
108948
110032
  );
108949
- const session = await getSessionAuthorityProjection2(
110033
+ const session = await getSessionAuthorityProjection3(
108950
110034
  deps.db,
108951
110035
  claims.workspaceId,
108952
110036
  claims.sessionId
@@ -109286,7 +110370,7 @@ import {
109286
110370
  import { withOrganizationIntegrationPolicyFence as withOrganizationIntegrationPolicyFence8 } from "@opengeni/db/organization-integration-policy";
109287
110371
  import { CORE_INTEGRATION_DEFINITIONS as CORE_INTEGRATION_DEFINITIONS5 } from "@opengeni/capabilities";
109288
110372
  import {
109289
- hasPermission as hasPermission28,
110373
+ hasPermission as hasPermission29,
109290
110374
  requireAccessGrant as requireAccessGrant35,
109291
110375
  requireAccessGrantAuthorization as requireAccessGrantAuthorization20
109292
110376
  } from "@opengeni/core";
@@ -109352,7 +110436,7 @@ function registerIntegrationFacetRoutes(app, deps) {
109352
110436
  facetKey: decoded(c.req.param("facetKey")),
109353
110437
  payload: await c.req.json(),
109354
110438
  canManageOrganizationDestination: authorization.accountGrant?.permissions.includes("account:admin") === true,
109355
- canManageWorkspaceDestination: hasPermission28(
110439
+ canManageWorkspaceDestination: hasPermission29(
109356
110440
  grant.permissions,
109357
110441
  "capabilities:manage"
109358
110442
  ),
@@ -109623,6 +110707,7 @@ import {
109623
110707
  getWorkspaceInteractionRevisionState,
109624
110708
  listSessionEventPage as listSessionEventPage2,
109625
110709
  listWorkspaceControlEvents,
110710
+ getWorkspaceControlEvent,
109626
110711
  readSessionEventStorageGapEnd
109627
110712
  } from "@opengeni/db";
109628
110713
  import {
@@ -110152,7 +111237,8 @@ async function sseWorkspaceControlStream(db, bus, workspaceId, after, signal, op
110152
111237
  }
110153
111238
  }
110154
111239
  }
110155
- await writeFrame(formatWorkspaceControlEventSse(event));
111240
+ const visible = await getWorkspaceControlEvent(db, workspaceId, event.id);
111241
+ if (visible) await writeFrame(formatWorkspaceControlEventSse(visible));
110156
111242
  lastSent = event.sequence;
110157
111243
  };
110158
111244
  delivery = createLatestWinsDelivery(send, fail);
@@ -111181,7 +112267,7 @@ import { HTTPException as HTTPException94 } from "hono/http-exception";
111181
112267
 
111182
112268
  // src/integrations/pr-review-provider.ts
111183
112269
  import {
111184
- pinnedFetch as pinnedFetch6,
112270
+ pinnedFetch as pinnedFetch7,
111185
112271
  readResponseJsonBounded as readResponseJsonBounded12,
111186
112272
  readResponseTextBounded as readResponseTextBounded3
111187
112273
  } from "@opengeni/network";
@@ -111273,7 +112359,7 @@ async function providerJson2(input, url, headers) {
111273
112359
  headers: { accept: "application/json", ...headers },
111274
112360
  signal
111275
112361
  };
111276
- response = input.fetchImpl ? await input.fetchImpl(url, requestInit) : await pinnedFetch6(url, requestInit, input.settings, {
112362
+ response = input.fetchImpl ? await input.fetchImpl(url, requestInit) : await pinnedFetch7(url, requestInit, input.settings, {
111277
112363
  label: `${input.provider} PR Review repository verification`,
111278
112364
  requireHttpsOutsideLocalTest: true
111279
112365
  });
@@ -111373,7 +112459,7 @@ import {
111373
112459
  } from "@opengeni/contracts";
111374
112460
  import {
111375
112461
  automationRequestDigest as automationRequestDigest2,
111376
- hasPermission as hasPermission29,
112462
+ hasPermission as hasPermission30,
111377
112463
  requireAutomationAdapter as requireAutomationAdapter2,
111378
112464
  requireAccessGrantAuthorization as requireAccessGrantAuthorization21,
111379
112465
  externalActorContinuationForAuthorization as externalActorContinuationForAuthorization14,
@@ -112178,7 +113264,7 @@ function registerPrReviewGitHubRoutes(app, deps) {
112178
113264
  grant.accountId,
112179
113265
  workspaceId
112180
113266
  );
112181
- const canManage = !externalActorContinuationForAuthorization14(access) && hasPermission29(grant.permissions, "workspace:admin") && hasPermission29(grant.permissions, "secrets:write");
113267
+ const canManage = !externalActorContinuationForAuthorization14(access) && hasPermission30(grant.permissions, "workspace:admin") && hasPermission30(grant.permissions, "secrets:write");
112182
113268
  const connectState = configured2 && canManage ? createSignedState14(deps.githubStateSecret, {
112183
113269
  accountId: grant.accountId,
112184
113270
  workspaceId,
@@ -112544,7 +113630,7 @@ async function requirePrReviewManageGrant(c, deps, workspaceId, state) {
112544
113630
  return grant;
112545
113631
  }
112546
113632
  function prReviewBrowserGrantClaims(deps, grant) {
112547
- if (deps.settings.productAccessMode !== "configured" || !hasPermission29(grant.permissions, "workspace:admin") || !hasPermission29(grant.permissions, "secrets:write")) {
113633
+ if (deps.settings.productAccessMode !== "configured" || !hasPermission30(grant.permissions, "workspace:admin") || !hasPermission30(grant.permissions, "secrets:write")) {
112548
113634
  return {};
112549
113635
  }
112550
113636
  return {
@@ -114185,7 +115271,7 @@ import {
114185
115271
  SupersedePreferenceRegistryRequest as SupersedePreferenceRegistryRequest2
114186
115272
  } from "@opengeni/contracts";
114187
115273
  import {
114188
- hasPermission as hasPermission30,
115274
+ hasPermission as hasPermission31,
114189
115275
  requireAccessGrant as requireAccessGrant40,
114190
115276
  requireAccessGrantAuthorization as requireAccessGrantAuthorization24
114191
115277
  } from "@opengeni/core";
@@ -114265,7 +115351,7 @@ function authorizePreferenceRegistryScopeMutation(access, scope) {
114265
115351
  }
114266
115352
  return;
114267
115353
  }
114268
- if (scope === "workspace" && !hasPermission30(grant.permissions, "workspace:admin")) {
115354
+ if (scope === "workspace" && !hasPermission31(grant.permissions, "workspace:admin")) {
114269
115355
  throw new HTTPException98(403, { message: "missing permission: workspace:admin" });
114270
115356
  }
114271
115357
  }
@@ -115532,7 +116618,7 @@ function registerScheduledTaskRoutes(app, deps) {
115532
116618
  settings: catalogSettings,
115533
116619
  authorization,
115534
116620
  tasks,
115535
- permissionsRequiredByTools: permissionsRequiredByFirstPartyTools,
116621
+ permissionsRequiredByTools: permissionsRequiredByFirstPartyTools2,
115536
116622
  onError: (error) => {
115537
116623
  deps.observability?.warn("Scheduled task access drift could not be computed", {
115538
116624
  errorClass: error instanceof Error ? error.name : "ScheduledTaskPolicyDriftError",
@@ -115718,7 +116804,7 @@ function registerScheduledTaskRoutes(app, deps) {
115718
116804
  authorization,
115719
116805
  taskId: c.req.param("taskId"),
115720
116806
  request: parsed.data,
115721
- permissionsRequiredByTools: permissionsRequiredByFirstPartyTools,
116807
+ permissionsRequiredByTools: permissionsRequiredByFirstPartyTools2,
115722
116808
  sessionAuthorization: deps.sessionAuthorization,
115723
116809
  authorizationSurface: "http"
115724
116810
  });
@@ -116485,7 +117571,12 @@ import {
116485
117571
  SITE_FRAME_SESSION_CREATE_FIELDS,
116486
117572
  siteFrameBodyRefusal as siteFrameBodyRefusal2
116487
117573
  } from "@opengeni/contracts/site-session-http";
116488
- import { requireWorkspace as requireWorkspace5, scheduledSessionIds } from "@opengeni/db";
117574
+ import {
117575
+ requireWorkspace as requireWorkspace5,
117576
+ scheduledSessionIds,
117577
+ currentSiteViewerRlsContext,
117578
+ nestedPostgresSqlState as nestedPostgresSqlState12
117579
+ } from "@opengeni/db";
116489
117580
  import {
116490
117581
  currentSiteSessionOrigin as currentSiteSessionOrigin4,
116491
117582
  isVerifiedDelegatedHumanAuthorization as isVerifiedDelegatedHumanAuthorization4,
@@ -116977,7 +118068,7 @@ import {
116977
118068
  import { HTTPException as HTTPException105 } from "hono/http-exception";
116978
118069
  import {
116979
118070
  getManagedAuthRequestActorEpoch as getManagedAuthRequestActorEpoch2,
116980
- hasPermission as hasPermission31,
118071
+ hasPermission as hasPermission32,
116981
118072
  requireAccessGrant as requireAccessGrant46,
116982
118073
  requireAccessGrantAuthorization as requireAccessGrantAuthorization29,
116983
118074
  requireFreshAccessGrant as requireFreshAccessGrant3,
@@ -117319,7 +118410,7 @@ function childRequiresActionRespondedByKindForGrant(grant) {
117319
118410
  return "human";
117320
118411
  }
117321
118412
  function requireViewerLifecyclePermission(grant) {
117322
- if (VIEWER_LIFECYCLE_PERMISSIONS.some((permission) => hasPermission31(grant.permissions, permission))) {
118413
+ if (VIEWER_LIFECYCLE_PERMISSIONS.some((permission) => hasPermission32(grant.permissions, permission))) {
117323
118414
  return;
117324
118415
  }
117325
118416
  throw new HTTPException105(403, {
@@ -117585,7 +118676,7 @@ function registerSessionRoutes(app, deps) {
117585
118676
  )
117586
118677
  );
117587
118678
  const siteOrigin = origin ?? currentSiteSessionOrigin4();
117588
- if (siteOrigin && grant.subjectId !== `site:${siteOrigin.siteId}`) {
118679
+ if (siteOrigin && currentSiteViewerRlsContext()?.siteId !== siteOrigin.siteId) {
117589
118680
  const refused4 = siteFrameBodyRefusal2("sessions.create", "/sessions", payload);
117590
118681
  if (refused4)
117591
118682
  return c.json(
@@ -117601,6 +118692,8 @@ function registerSessionRoutes(app, deps) {
117601
118692
  siteId: siteOrigin.siteId,
117602
118693
  versionId: siteOrigin.versionId ?? null
117603
118694
  });
118695
+ if (grant.principalKind !== "agent_attempt")
118696
+ payload.visibility = "private";
117604
118697
  }
117605
118698
  const create = () => createSessionForRequest(deps, grant, workspaceId, payload, authorization);
117606
118699
  session = await measureSessionCreatePhase(
@@ -117838,7 +118931,7 @@ function registerSessionRoutes(app, deps) {
117838
118931
  workspaceId,
117839
118932
  sessionIds: [...page2.pinned, ...page2.sessions].map((session) => session.id)
117840
118933
  });
117841
- const scheduleTargets = hasPermission31(grant.permissions, "scheduled_tasks:run") && hasPermission31(grant.permissions, "sessions:control") ? await scheduledSessionIds(
118934
+ const scheduleTargets = hasPermission32(grant.permissions, "scheduled_tasks:run") && hasPermission32(grant.permissions, "sessions:control") ? await scheduledSessionIds(
117842
118935
  db,
117843
118936
  workspaceId,
117844
118937
  [...page2.pinned, ...page2.sessions].map((session) => session.id)
@@ -118074,7 +119167,7 @@ function registerSessionRoutes(app, deps) {
118074
119167
  workspaceId,
118075
119168
  sessionIds: [sessionId]
118076
119169
  }),
118077
- hasPermission31(grant.permissions, "scheduled_tasks:run") && hasPermission31(grant.permissions, "sessions:control") ? scheduledSessionIds(db, workspaceId, [sessionId]) : Promise.resolve(/* @__PURE__ */ new Set()),
119170
+ hasPermission32(grant.permissions, "scheduled_tasks:run") && hasPermission32(grant.permissions, "sessions:control") ? scheduledSessionIds(db, workspaceId, [sessionId]) : Promise.resolve(/* @__PURE__ */ new Set()),
118078
119171
  loadEffectivePolicyContext(deps, workspaceId, grant.subjectId, [session])
118079
119172
  ]);
118080
119173
  const usageLimit = await sessionUsageLimitForRead(db, session, {
@@ -119145,7 +120238,7 @@ function registerSessionRoutes(app, deps) {
119145
120238
  }
119146
120239
  };
119147
120240
  collect(lineage.children);
119148
- const targets = hasPermission31(grant.permissions, "scheduled_tasks:run") && hasPermission31(grant.permissions, "sessions:control") ? await scheduledSessionIds(db, workspaceId, sessionIds) : /* @__PURE__ */ new Set();
120241
+ const targets = hasPermission32(grant.permissions, "scheduled_tasks:run") && hasPermission32(grant.permissions, "sessions:control") ? await scheduledSessionIds(db, workspaceId, sessionIds) : /* @__PURE__ */ new Set();
119149
120242
  const decorateNodes = (nodes) => nodes.map((node) => ({
119150
120243
  ...node,
119151
120244
  session: { ...node.session, hasSchedules: targets.has(node.session.id) },
@@ -120148,6 +121241,7 @@ function registerSessionRoutes(app, deps) {
120148
121241
  actorEpoch: getManagedAuthRequestActorEpoch2(c.req.raw) ?? void 0,
120149
121242
  reauthorizeAfterMs: authorization?.reauthorizeAfterMs ?? SESSION_AUTHORIZATION_DEFAULT_REAUTHORIZE_MS,
120150
121243
  reauthorize: async () => {
121244
+ await reauthorizeSiteSessionRequest(c.req.raw);
120151
121245
  const freshGrant = await requireFreshAccessGrant3(c, deps, workspaceId, "sessions:read");
120152
121246
  await requireSessionAuthorization16(deps, freshGrant, {
120153
121247
  sessionId,
@@ -121868,7 +122962,7 @@ function sessionTenancyHttpError(error) {
121868
122962
  retryable: false
121869
122963
  });
121870
122964
  }
121871
- if (error instanceof SessionTenancyNotActivatedError2) {
122965
+ if (error instanceof SessionTenancyNotActivatedError2 || nestedPostgresSqlState12(error) === "P0793") {
121872
122966
  return new ApiHttpError(409, {
121873
122967
  code: "conflict",
121874
122968
  message: "Only-me chats are not enabled for this organization.",
@@ -122494,7 +123588,7 @@ function sessionCreateErrorResponse(c, error) {
122494
123588
  403
122495
123589
  );
122496
123590
  }
122497
- if (error instanceof SessionTenancyNotActivatedError2) {
123591
+ if (error instanceof SessionTenancyNotActivatedError2 || nestedPostgresSqlState12(error) === "P0793") {
122498
123592
  return c.json(
122499
123593
  {
122500
123594
  code: "SESSION_TENANCY_NOT_ACTIVATED",
@@ -122611,7 +123705,7 @@ var ARCHIVE_LIVE_WORK_STATUSES = /* @__PURE__ */ new Set([
122611
123705
  async function pauseOwnArchivedWork(deps, grant, workspaceId, session) {
122612
123706
  if (session.createdBy.kind !== "subject" || session.createdBy.subjectId !== grant.subjectId)
122613
123707
  return session;
122614
- if (!hasPermission31(grant.permissions, "sessions:control")) return session;
123708
+ if (!hasPermission32(grant.permissions, "sessions:control")) return session;
122615
123709
  if (session.effectiveControl.directState === "paused") return session;
122616
123710
  const liveWork = ARCHIVE_LIVE_WORK_STATUSES.has(session.status) || session.activeTurnId !== null || Boolean(session.inputWait) || (await getSessionGoal2(deps.db, workspaceId, session.id))?.status === "active";
122617
123711
  if (!liveWork) return session;
@@ -122971,7 +124065,7 @@ import {
122971
124065
  replayWorkspaceGatewayCustomModelCreate,
122972
124066
  replayWorkspaceOpenRouterCustomModelCreate,
122973
124067
  listWorkspacesForSubject as listWorkspacesForSubject3,
122974
- nestedPostgresSqlState as nestedPostgresSqlState13,
124068
+ nestedPostgresSqlState as nestedPostgresSqlState14,
122975
124069
  removeWorkspaceMember,
122976
124070
  requireWorkspace as requireWorkspace6,
122977
124071
  updateWorkspaceSettings,
@@ -123003,7 +124097,7 @@ import {
123003
124097
  getManagedAuthRequestActorEpoch as getManagedAuthRequestActorEpoch3,
123004
124098
  accountScopedApiKeyWorkspaceAuthority as accountScopedApiKeyWorkspaceAuthority5,
123005
124099
  organizationWorkspaceInScope as organizationWorkspaceInScope2,
123006
- hasPermission as hasPermission32,
124100
+ hasPermission as hasPermission33,
123007
124101
  requireAccessContext as requireAccessContext12,
123008
124102
  requireApiKeyDelegationContext,
123009
124103
  requireExplicitPermissionDelegation as requireExplicitPermissionDelegation2,
@@ -123034,7 +124128,7 @@ import {
123034
124128
  // src/workspace-deletion.ts
123035
124129
  import {
123036
124130
  deleteWorkspaceIfQuiescent,
123037
- nestedPostgresSqlState as nestedPostgresSqlState12,
124131
+ nestedPostgresSqlState as nestedPostgresSqlState13,
123038
124132
  safeDatabaseErrorFacts
123039
124133
  } from "@opengeni/db";
123040
124134
  import { HTTPException as HTTPException107 } from "hono/http-exception";
@@ -123127,7 +124221,7 @@ async function deleteWorkspaceForRequest(deps, input) {
123127
124221
  ...observer ? { observer } : {}
123128
124222
  });
123129
124223
  } catch (error) {
123130
- const state = nestedPostgresSqlState12(error);
124224
+ const state = nestedPostgresSqlState13(error);
123131
124225
  if (state === "42501") {
123132
124226
  throw new HTTPException107(403, { message: "organization administration is not authorized" });
123133
124227
  }
@@ -123284,7 +124378,7 @@ function registerWorkspaceRoutes(app, deps) {
123284
124378
  return c.json(externalWorkspaces.map((workspace) => Workspace.parse(workspace)));
123285
124379
  const accountScopedAuthority = accountScopedApiKeyWorkspaceAuthority5(context);
123286
124380
  if (accountScopedAuthority) {
123287
- if (!hasPermission32(accountScopedAuthority.permissions, "workspace:read")) return c.json([]);
124381
+ if (!hasPermission33(accountScopedAuthority.permissions, "workspace:read")) return c.json([]);
123288
124382
  return c.json(
123289
124383
  (await listSharedWorkspacesForAccount2(deps.db, accountScopedAuthority.accountId)).filter(
123290
124384
  (workspace) => organizationWorkspaceInScope2(accountScopedAuthority.workspaceScope, workspace.id)
@@ -123293,7 +124387,7 @@ function registerWorkspaceRoutes(app, deps) {
123293
124387
  }
123294
124388
  const readableWorkspaceIds = [
123295
124389
  ...new Set(
123296
- context.workspaceGrants.filter((grant) => hasPermission32(grant.permissions, "workspace:read")).map((grant) => grant.workspaceId)
124390
+ context.workspaceGrants.filter((grant) => hasPermission33(grant.permissions, "workspace:read")).map((grant) => grant.workspaceId)
123297
124391
  )
123298
124392
  ];
123299
124393
  if (readableWorkspaceIds.length > 0) {
@@ -123484,7 +124578,7 @@ function registerWorkspaceRoutes(app, deps) {
123484
124578
  );
123485
124579
  return c.json(Workspace.parse(workspace));
123486
124580
  } catch (error) {
123487
- if (nestedPostgresSqlState13(error) === "0A000") {
124581
+ if (nestedPostgresSqlState14(error) === "0A000") {
123488
124582
  throw new HTTPException108(409, {
123489
124583
  message: "Memory settings moved to Settings > Agent learning. Refresh the app to change them."
123490
124584
  });
@@ -123734,7 +124828,7 @@ function registerWorkspaceRoutes(app, deps) {
123734
124828
  if (error instanceof WorkspaceGatewayCustomModelLimitError || error instanceof WorkspaceGatewayCustomModelHistoryLimitError) {
123735
124829
  throw new HTTPException108(422, { message: error.message });
123736
124830
  }
123737
- if (nestedPostgresSqlState13(error) === "23505") {
124831
+ if (nestedPostgresSqlState14(error) === "23505") {
123738
124832
  throw new HTTPException108(422, {
123739
124833
  message: "Gateway custom model already exists"
123740
124834
  });
@@ -123863,7 +124957,7 @@ function registerWorkspaceRoutes(app, deps) {
123863
124957
  if (error instanceof WorkspaceOpenRouterCustomModelLimitError || error instanceof WorkspaceOpenRouterCustomModelHistoryLimitError) {
123864
124958
  throw new HTTPException108(422, { message: error.message });
123865
124959
  }
123866
- if (nestedPostgresSqlState13(error) === "23505") {
124960
+ if (nestedPostgresSqlState14(error) === "23505") {
123867
124961
  throw new HTTPException108(422, {
123868
124962
  message: "OpenRouter custom model already exists"
123869
124963
  });
@@ -123995,7 +125089,7 @@ function registerWorkspaceRoutes(app, deps) {
123995
125089
  if (error instanceof WorkspaceOpperCustomModelLimitError || error instanceof WorkspaceOpperCustomModelHistoryLimitError) {
123996
125090
  throw new HTTPException108(422, { message: error.message });
123997
125091
  }
123998
- if (nestedPostgresSqlState13(error) === "23505") {
125092
+ if (nestedPostgresSqlState14(error) === "23505") {
123999
125093
  throw new HTTPException108(422, {
124000
125094
  message: "Opper custom model already exists"
124001
125095
  });
@@ -124483,7 +125577,7 @@ function rethrowWorkspaceMemberCandidateError(error) {
124483
125577
  message: "the workspace must keep at least one administrator"
124484
125578
  });
124485
125579
  }
124486
- const sqlState = nestedPostgresSqlState13(error);
125580
+ const sqlState = nestedPostgresSqlState14(error);
124487
125581
  if (sqlState === "P0002") {
124488
125582
  throw new HTTPException108(404, { message: "workspace not found" });
124489
125583
  }
@@ -124548,7 +125642,7 @@ import {
124548
125642
  getWorkspace as getWorkspace7,
124549
125643
  getWorkspaceUsage,
124550
125644
  grantWorkspaceCredits,
124551
- nestedPostgresSqlState as nestedPostgresSqlState14,
125645
+ nestedPostgresSqlState as nestedPostgresSqlState15,
124552
125646
  setMemberAllowance,
124553
125647
  setWorkspaceAllowance,
124554
125648
  withAccountRls as withAccountRls4,
@@ -124683,7 +125777,7 @@ async function lifecycle2(operation) {
124683
125777
  } catch (error) {
124684
125778
  if (error instanceof UsageAllowanceVersionConflictError)
124685
125779
  throw new HTTPException109(409, { message: error.message });
124686
- const state = nestedPostgresSqlState14(error);
125780
+ const state = nestedPostgresSqlState15(error);
124687
125781
  if (state === "40001" || state === "23505")
124688
125782
  throw new HTTPException109(409, { message: "Allowance version or operation conflicts" });
124689
125783
  if (state === "42501")
@@ -125606,7 +126700,7 @@ import {
125606
126700
  WORKSPACE_STATE_KNOWLEDGE_SAMPLE_LIMIT as WORKSPACE_STATE_KNOWLEDGE_SAMPLE_LIMIT2
125607
126701
  } from "@opengeni/contracts";
125608
126702
  import {
125609
- hasPermission as hasPermission33,
126703
+ hasPermission as hasPermission34,
125610
126704
  requireAccessGrant as requireAccessGrant52,
125611
126705
  requireAccessGrantAuthorization as requireAccessGrantAuthorization33,
125612
126706
  knowledgeContextForAccess as knowledgeContextForAccess3
@@ -126223,7 +127317,7 @@ function registerCompanyBrainRoutes(app, deps) {
126223
127317
  workspaceId,
126224
127318
  accountId: grant.accountId,
126225
127319
  subjectId: grant.subjectId,
126226
- canInspectKnowledge: hasPermission33(grant.permissions, "documents:search"),
127320
+ canInspectKnowledge: hasPermission34(grant.permissions, "documents:search"),
126227
127321
  access
126228
127322
  });
126229
127323
  context.header("cache-control", "private, no-store");
@@ -126242,7 +127336,7 @@ function registerCompanyBrainRoutes(app, deps) {
126242
127336
  workspaceId,
126243
127337
  accountId: grant.accountId,
126244
127338
  subjectId: grant.subjectId,
126245
- canInspectKnowledge: hasPermission33(grant.permissions, "documents:search"),
127339
+ canInspectKnowledge: hasPermission34(grant.permissions, "documents:search"),
126246
127340
  access
126247
127341
  });
126248
127342
  context.header("cache-control", "private, no-store");
@@ -126435,7 +127529,7 @@ import {
126435
127529
  } from "@opengeni/core";
126436
127530
  import {
126437
127531
  availableSlackBotConnectionMetadata as availableSlackBotConnectionMetadata2,
126438
- nestedPostgresSqlState as nestedPostgresSqlState15,
127532
+ nestedPostgresSqlState as nestedPostgresSqlState16,
126439
127533
  readOrganizationSlackBotAccess,
126440
127534
  setOrganizationSlackBotAccess,
126441
127535
  sharedOrganizationSlackBots as sharedOrganizationSlackBots2
@@ -126465,7 +127559,7 @@ function registerSlackBotAccessRoutes(app, deps) {
126465
127559
  )
126466
127560
  );
126467
127561
  } catch (error) {
126468
- if (nestedPostgresSqlState15(error) === "42501")
127562
+ if (nestedPostgresSqlState16(error) === "42501")
126469
127563
  throw new HTTPException115(404, { message: "Local bot installation unavailable" });
126470
127564
  throw error;
126471
127565
  }
@@ -126519,7 +127613,7 @@ function registerSlackBotAccessRoutes(app, deps) {
126519
127613
  return context.json(OpenGeniSlackBotOrganizationAccess.parse(result2));
126520
127614
  } catch (error) {
126521
127615
  if (error instanceof HTTPException115) throw error;
126522
- if (nestedPostgresSqlState15(error) === "42501")
127616
+ if (nestedPostgresSqlState16(error) === "42501")
126523
127617
  throw new HTTPException115(403, {
126524
127618
  message: "Organization administrator and a verified local bot installation required"
126525
127619
  });
@@ -126535,7 +127629,7 @@ import {
126535
127629
  WorkspaceStateResponse as WorkspaceStateResponse2
126536
127630
  } from "@opengeni/contracts";
126537
127631
  import {
126538
- hasPermission as hasPermission34,
127632
+ hasPermission as hasPermission35,
126539
127633
  requireAccessGrantAuthorization as requireAccessGrantAuthorization35,
126540
127634
  knowledgeContextForAccess as knowledgeContextForAccess4
126541
127635
  } from "@opengeni/core";
@@ -126594,7 +127688,7 @@ async function readWorkspaceState(deps, input) {
126594
127688
  const { workspaceId, query, access } = input;
126595
127689
  const { grant } = access;
126596
127690
  const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
126597
- const canInspectKnowledge = hasPermission34(grant.permissions, "documents:search");
127691
+ const canInspectKnowledge = hasPermission35(grant.permissions, "documents:search");
126598
127692
  const [workspace, policies, knowledge, currentPreferences, acceptedAttempt] = await Promise.all([
126599
127693
  getWorkspace9(deps.db, workspaceId),
126600
127694
  listWorkspaceInstructionPolicyRevisions3(deps.db, workspaceId, { limit: 1 }),
@@ -126721,7 +127815,7 @@ import {
126721
127815
  getWorkspaceArtifact as getWorkspaceArtifact3,
126722
127816
  getWorkspaceArtifactContentRef as getWorkspaceArtifactContentRef4,
126723
127817
  listWorkspaceArtifacts as listWorkspaceArtifacts2,
126724
- nestedPostgresSqlState as nestedPostgresSqlState16,
127818
+ nestedPostgresSqlState as nestedPostgresSqlState17,
126725
127819
  publishWorkspaceArtifactVersion as publishWorkspaceArtifactVersion2,
126726
127820
  rollbackWorkspaceArtifact as rollbackWorkspaceArtifact2,
126727
127821
  setWorkspaceArtifactStatus as setWorkspaceArtifactStatus2,
@@ -126773,7 +127867,7 @@ function workspaceArtifactErrorResponse(context, error) {
126773
127867
  422
126774
127868
  );
126775
127869
  }
126776
- if (nestedPostgresSqlState16(error) === "23505") {
127870
+ if (nestedPostgresSqlState17(error) === "23505") {
126777
127871
  return context.json(
126778
127872
  {
126779
127873
  code: "WORKSPACE_ARTIFACT_CONFLICT",
@@ -127674,6 +128768,9 @@ function registerSitePublishingRoutes(app, deps) {
127674
128768
  // src/routes/site-runtime.ts
127675
128769
  import { createHash as createHash37, randomBytes as randomBytes15, randomUUID as randomUUID16, timingSafeEqual as timingSafeEqual5 } from "crypto";
127676
128770
  import {
128771
+ ReasoningEffort,
128772
+ LatencyMode,
128773
+ permissionsRequiredByFirstPartyTools as permissionsRequiredByFirstPartyTools4,
127677
128774
  DeleteSessionQueueItemRequest as DeleteSessionQueueItemRequest3,
127678
128775
  EditSessionQueueItemRequest as EditSessionQueueItemRequest3,
127679
128776
  matchSiteOperation,
@@ -127698,17 +128795,19 @@ import {
127698
128795
  ToolGatewayInvokeRequest
127699
128796
  } from "@opengeni/contracts";
127700
128797
  import {
128798
+ cancelPublishedSiteSession,
127701
128799
  withHostSessionUsageLimit,
127702
128800
  withSiteSessionOrigin as withSiteSessionOrigin6,
127703
128801
  admissibleWorkspaceModel as admissibleWorkspaceModel2,
127704
128802
  loadWorkspaceModelSelectionInput as loadWorkspaceModelSelectionInput2,
127705
128803
  resolveWorkspaceModelSelection as resolveWorkspaceModelSelection4,
127706
- hasPermission as hasPermission35
128804
+ hasPermission as hasPermission36
127707
128805
  } from "@opengeni/core";
127708
128806
  import {
127709
128807
  consumeSiteAuthCode,
127710
128808
  finishSiteRuntimeAdmission,
127711
128809
  withSiteRuntimeAdmission,
128810
+ withSiteViewerRlsContext,
127712
128811
  createSiteAbuseReport,
127713
128812
  getSiteWorkspaceMemberPermissions,
127714
128813
  readSitePlatformUsage as readSitePlatformUsage2,
@@ -127731,13 +128830,16 @@ import {
127731
128830
  } from "@opengeni/db";
127732
128831
 
127733
128832
  // src/site-publishing/agent-session.ts
127734
- import { resolveAgentConfig } from "@opengeni/contracts";
128833
+ import {
128834
+ permissionsRequiredByFirstPartyTools as permissionsRequiredByFirstPartyTools3,
128835
+ resolveAgentConfig
128836
+ } from "@opengeni/contracts";
127735
128837
  import { agentConfigDeploymentPolicy as agentConfigDeploymentPolicy2, resolveFirstPartyMcpToolPolicy as resolveFirstPartyMcpToolPolicy3 } from "@opengeni/config";
127736
128838
  import { siteSessionOriginFromMetadata as siteSessionOriginFromMetadata2 } from "@opengeni/core";
127737
128839
  import { appendSessionEventsWithLockedSessionUpdate, getSiteSqlDatabase as getSiteSqlDatabase3 } from "@opengeni/db";
127738
128840
  import { publishDurableSessionEvents as publishDurableSessionEvents5 } from "@opengeni/events";
127739
- var SITE_AGENT_DEFAULTS_VERSION = 1;
127740
- async function normalizeSiteAgentSession(deps, host, viewer, sessionId, retainedToolIds) {
128841
+ var SITE_AGENT_DEFAULTS_VERSION = 2;
128842
+ async function normalizeSiteAgentSession(deps, host, viewer, sessionId, retainedToolIds, memberPermissions) {
127741
128843
  const data = await resolveSiteAgentDataContext(deps, host.scope, sessionId);
127742
128844
  if (data.kind !== "site" || data.siteId !== host.site.id || data.viewer.principal !== viewer.principal)
127743
128845
  throw sitePublishingError(
@@ -127750,8 +128852,10 @@ async function normalizeSiteAgentSession(deps, host, viewer, sessionId, retained
127750
128852
  const dataTools = siteAgentDataToolNames({
127751
128853
  viewerKind: viewer.kind,
127752
128854
  siteSql: sqlEnabled,
127753
- allowed: resolveFirstPartyMcpToolPolicy3(deps.settings).allowed
128855
+ allowed: resolveFirstPartyMcpToolPolicy3(deps.settings).allowed,
128856
+ ...memberPermissions === void 0 ? {} : { memberPermissions }
127754
128857
  });
128858
+ const dataToolPermissions = permissionsRequiredByFirstPartyTools3(dataTools);
127755
128859
  const config = resolveAgentConfig({
127756
128860
  creator: "api",
127757
128861
  request: {
@@ -127777,7 +128881,7 @@ async function normalizeSiteAgentSession(deps, host, viewer, sessionId, retained
127777
128881
  host.scope.workspaceId,
127778
128882
  sessionId,
127779
128883
  (session) => {
127780
- if (session.parentSessionId || session.createdBy.subjectId !== `site:${host.site.id}` || siteSessionOriginFromMetadata2(session.metadata)?.siteId !== host.site.id)
128884
+ if (session.parentSessionId || session.createdBy.subjectId !== `site:${host.site.id}` && !(viewer.kind === "member" && session.createdBy.kind === "subject" && session.createdBy.subjectId === viewer.subjectId) || siteSessionOriginFromMetadata2(session.metadata)?.siteId !== host.site.id)
127781
128885
  throw sitePublishingError(
127782
128886
  403,
127783
128887
  "forbidden",
@@ -127786,7 +128890,8 @@ async function normalizeSiteAgentSession(deps, host, viewer, sessionId, retained
127786
128890
  );
127787
128891
  const raw = session.metadata.opengeniPublishedSite;
127788
128892
  const stamp = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
127789
- if (stamp.agentDefaultsVersion === SITE_AGENT_DEFAULTS_VERSION) return { events: [] };
128893
+ if (stamp.agentDefaultsVersion === SITE_AGENT_DEFAULTS_VERSION && session.firstPartyMcpTools.join(",") === dataTools.join(",") && session.firstPartyMcpPermissions?.join(",") === dataToolPermissions.join(","))
128894
+ return { events: [] };
127790
128895
  const allowed2 = /* @__PURE__ */ new Set(["opengeni", ...retainedToolIds]);
127791
128896
  const tools = session.tools.filter((tool) => allowed2.has(tool.id));
127792
128897
  const toolPolicy = {
@@ -127813,7 +128918,7 @@ async function normalizeSiteAgentSession(deps, host, viewer, sessionId, retained
127813
128918
  ],
127814
128919
  update: {
127815
128920
  firstPartyMcpTools: dataTools,
127816
- firstPartyMcpPermissions: [...SITE_AGENT_DATA_TOOL_PERMISSIONS],
128921
+ firstPartyMcpPermissions: dataToolPermissions,
127817
128922
  agentConfig: config,
127818
128923
  instructions,
127819
128924
  tools,
@@ -128331,7 +129436,10 @@ var VersionId = z66.string().uuid();
128331
129436
  var ClientEventId = z66.string().min(1).max(200).optional();
128332
129437
  var CreateConversationRequest = z66.object({
128333
129438
  initialMessage: z66.string().trim().min(1).max(MESSAGE_MAX_CHARS),
128334
- idempotencyKey: z66.string().min(1).max(200).optional()
129439
+ idempotencyKey: z66.string().min(1).max(200).optional(),
129440
+ model: z66.string().min(1).optional(),
129441
+ reasoningEffort: ReasoningEffort.optional(),
129442
+ latencyMode: LatencyMode.optional()
128335
129443
  }).passthrough();
128336
129444
  var SendMessageRequest = z66.object({
128337
129445
  type: z66.literal("user.message"),
@@ -128520,7 +129628,7 @@ function idempotentSessionId(seed) {
128520
129628
  }
128521
129629
  function registerSiteRuntimeRoutes(app, deps) {
128522
129630
  const dispatch = async (request) => await app.fetch(markLocalInternalDispatch(request));
128523
- setSitePublishingDispatch(deps.settings, dispatch);
129631
+ setSitePublishingCancellation(deps.settings, (input) => cancelPublishedSiteSession(deps, input));
128524
129632
  const handler = async (context) => {
128525
129633
  const domain = configuredSitesDomain(deps.settings);
128526
129634
  if (!domain || !deps.settings.sitesGatewaySecret)
@@ -128908,7 +130016,7 @@ function registerSiteRuntimeRoutes(app, deps) {
128908
130016
  agent = choice !== null && choice.kind !== "unavailable";
128909
130017
  }
128910
130018
  const version2 = host.site.currentVersionId ? await getPublishedSiteVersion6(deps.db, host.scope, host.site.id, host.site.currentVersionId) : null;
128911
- const workspaceTools = base.workspaceTools && (version2?.requestedTools.length ?? 0) > 0 && viewer.subjectId !== null && viewer.subjectId !== void 0 && hasPermission35(
130019
+ const workspaceTools = base.workspaceTools && (version2?.requestedTools.length ?? 0) > 0 && viewer.subjectId !== null && viewer.subjectId !== void 0 && hasPermission36(
128912
130020
  await getSiteWorkspaceMemberPermissions(deps.db, host.scope, viewer.subjectId) ?? [],
128913
130021
  "workspace:read"
128914
130022
  );
@@ -129114,18 +130222,32 @@ function registerSiteRuntimeRoutes(app, deps) {
129114
130222
  const { context, url } = request;
129115
130223
  const base = `/v1/workspaces/${host.scope.workspaceId}/sessions`;
129116
130224
  const siteOrigin = { siteId: host.site.id, title: host.site.title, versionId: host.versionId };
130225
+ const reauthorizeViewer = async () => {
130226
+ const liveHost = await requireServedSiteRuntimeHost(deps, host.domain, request.fields.host);
130227
+ const liveViewer = await resolveSiteRuntimeViewer(deps, liveHost, request.fields);
130228
+ if (liveHost.site.id !== host.site.id || liveViewer.principal !== viewer.principal || liveViewer.kind !== viewer.kind || liveViewer.sessionId !== viewer.sessionId)
130229
+ throw siteNotAvailableForViewer(
130230
+ "agent",
130231
+ "This conversation is no longer available to this viewer"
130232
+ );
130233
+ };
129117
130234
  let pendingAdmission;
129118
130235
  const send = async (method, path, body5, extraPermissions) => {
129119
- const execute = () => withSiteSessionOrigin6(
129120
- siteOrigin,
129121
- async () => dispatch(
129122
- await siteRuntimeSessionRequest(deps, host, viewer, {
129123
- origin: url.origin,
129124
- method,
129125
- path,
129126
- ...body5 === void 0 ? {} : { body: body5 },
129127
- ...extraPermissions ? { extraPermissions } : {}
129128
- })
130236
+ await reauthorizeViewer();
130237
+ const execute = () => withSiteViewerRlsContext(
130238
+ { siteId: host.site.id, principal: viewer.principal },
130239
+ () => withSiteSessionOrigin6(
130240
+ siteOrigin,
130241
+ async () => dispatch(
130242
+ await siteRuntimeSessionRequest(deps, host, viewer, {
130243
+ origin: url.origin,
130244
+ method,
130245
+ path,
130246
+ reauthorize: reauthorizeViewer,
130247
+ ...body5 === void 0 ? {} : { body: body5 },
130248
+ ...extraPermissions ? { extraPermissions } : {}
130249
+ })
130250
+ )
129129
130251
  )
129130
130252
  );
129131
130253
  const pending2 = pendingAdmission;
@@ -129189,6 +130311,11 @@ function registerSiteRuntimeRoutes(app, deps) {
129189
130311
  if (viewer.kind === "guest" || viewer.kind === "user")
129190
130312
  await requireSitePlatformOpen(deps, "guest_agent");
129191
130313
  const models = await siteViewerModels(host, viewer, limits);
130314
+ if (input.model && !models.allowed.includes(input.model))
130315
+ throw siteNotAvailableForViewer(
130316
+ "agent_model",
130317
+ "This model is not available to you on this Site"
130318
+ );
129192
130319
  if (models.unavailable)
129193
130320
  throw siteNotAvailableForViewer(
129194
130321
  "agent_model",
@@ -129237,6 +130364,11 @@ ${input.idempotencyKey}`) : randomUUID16();
129237
130364
  }
129238
130365
  }
129239
130366
  }
130367
+ if (!repair && viewer.kind !== "member" && deps.settings.privacyOnlyMeAllowed === false)
130368
+ throw siteNotAvailableForViewer(
130369
+ "private_conversations",
130370
+ "Private Site conversations are disabled by this deployment"
130371
+ );
129240
130372
  for (const conversation2 of await listOwnedSiteRuntimeConversations(deps.db, host.scope, {
129241
130373
  siteId: host.site.id,
129242
130374
  viewerPrincipal: viewer.principal,
@@ -129275,8 +130407,10 @@ ${input.idempotencyKey}`) : randomUUID16();
129275
130407
  deps,
129276
130408
  host.scope,
129277
130409
  host.site.id,
129278
- viewer.kind
130410
+ viewer.kind,
130411
+ viewer.kind === "member" ? memberPermissions ?? [] : void 0
129279
130412
  );
130413
+ const dataToolPermissions = permissionsRequiredByFirstPartyTools4(dataTools);
129280
130414
  const admissionId = randomUUID16();
129281
130415
  const reservation = await reserve(
129282
130416
  () => repair ? reserveSiteRuntimeConversationWork(deps.db, host.scope, {
@@ -129305,13 +130439,14 @@ ${input.idempotencyKey}`) : randomUUID16();
129305
130439
  const body5 = {
129306
130440
  initialMessage: input.initialMessage,
129307
130441
  requestedSessionId,
130442
+ ...viewer.kind === "member" ? { visibility: "private" } : {},
129308
130443
  startMode: "standard",
129309
130444
  agentAccess: "session",
129310
130445
  memoryScope: "off",
129311
130446
  rigId: null,
129312
130447
  // Only this Site's data tools; never management or workspace tools.
129313
130448
  firstPartyMcpTools: dataTools,
129314
- ...dataTools.length > 0 ? { firstPartyMcpPermissions: [...SITE_AGENT_DATA_TOOL_PERMISSIONS] } : {},
130449
+ ...dataTools.length > 0 ? { firstPartyMcpPermissions: dataToolPermissions } : {},
129315
130450
  agent: {
129316
130451
  capabilities: {
129317
130452
  from: "none",
@@ -129323,7 +130458,9 @@ ${input.idempotencyKey}`) : randomUUID16();
129323
130458
  // No sandbox: a Site's agent answers from the page and the Site's
129324
130459
  // data, with no shell or workspace files.
129325
130460
  sandboxBackend: "none",
129326
- ...repair ? { model: repair.model } : models.default ? { model: models.default } : {},
130461
+ ...repair ? { model: repair.model } : input.model || models.default ? { model: input.model ?? models.default } : {},
130462
+ ...input.reasoningEffort === void 0 ? {} : { reasoningEffort: input.reasoningEffort },
130463
+ ...input.latencyMode === void 0 ? {} : { latencyMode: input.latencyMode },
129327
130464
  instructions: siteAgentInstructions(host, viewer, dataTools, agent.instructions),
129328
130465
  // Always explicit: an empty list means no workspace tools at all.
129329
130466
  tools: mcpTools,
@@ -129337,7 +130474,7 @@ ${input.idempotencyKey}`) : randomUUID16();
129337
130474
  },
129338
130475
  ...input.idempotencyKey ? { idempotencyKey: `site-runtime:${requestedSessionId}` } : {}
129339
130476
  };
129340
- const start = () => send("POST", base, body5, dataTools.length > 0 ? SITE_AGENT_DATA_TOOL_PERMISSIONS : []);
130477
+ const start = () => send("POST", base, body5, dataToolPermissions);
129341
130478
  const usageLimitMicros = viewer.kind === "member" || repair ? null : reservation.executionLimitMicros;
129342
130479
  let created;
129343
130480
  try {
@@ -129451,7 +130588,8 @@ ${input.idempotencyKey}`) : randomUUID16();
129451
130588
  host,
129452
130589
  viewer,
129453
130590
  conversation.sessionId,
129454
- conversation.toolIds
130591
+ conversation.toolIds,
130592
+ viewer.kind === "member" ? memberPermissions ?? [] : void 0
129455
130593
  );
129456
130594
  const usage = await settleSiteRuntimeSpend(deps, host, conversation);
129457
130595
  if (viewer.kind === "member" && conversation.limitMicros !== null)
@@ -129676,7 +130814,7 @@ import {
129676
130814
  editableArtifactScope as editableArtifactScope2,
129677
130815
  fileOwnerContextForAccess as fileOwnerContextForAccess5,
129678
130816
  grantHasAgentAttemptAuthority as grantHasAgentAttemptAuthority5,
129679
- hasPermission as hasPermission36,
130817
+ hasPermission as hasPermission37,
129680
130818
  requireAccessGrantAuthorization as requireAccessGrantAuthorization37,
129681
130819
  requireLiveAgentAttemptAuthorization as requireLiveAgentAttemptAuthorization8,
129682
130820
  requireSessionAuthorization as requireSessionAuthorization18,
@@ -129687,10 +130825,10 @@ import {
129687
130825
  import {
129688
130826
  getFilesForSubject as getFilesForSubject3,
129689
130827
  getGeneratedImageArtifact as getGeneratedImageArtifact2,
129690
- getSessionAuthorityProjection as getSessionAuthorityProjection3,
130828
+ getSessionAuthorityProjection as getSessionAuthorityProjection4,
129691
130829
  isWorkspaceArtifactVisible,
129692
130830
  listArtifactCatalogCandidates,
129693
- nestedPostgresSqlState as nestedPostgresSqlState17,
130831
+ nestedPostgresSqlState as nestedPostgresSqlState18,
129694
130832
  updateArtifactPin,
129695
130833
  withSessionRlsActorContext as withSessionRlsActorContext10
129696
130834
  } from "@opengeni/db";
@@ -129771,7 +130909,7 @@ function registerArtifactCatalogRoutes(app, deps) {
129771
130909
  "artifacts:publish"
129772
130910
  );
129773
130911
  const grant = authorization.grant;
129774
- if (!hasPermission36(grant.permissions, "artifacts:publish"))
130912
+ if (!hasPermission37(grant.permissions, "artifacts:publish"))
129775
130913
  throw new HTTPException119(403, { message: "Artifact publish access required" });
129776
130914
  const kind = ArtifactCatalogKind3.safeParse(context.req.param("kind"));
129777
130915
  const body5 = UpdateArtifactPinRequest.safeParse(await context.req.json().catch(() => null));
@@ -129780,7 +130918,7 @@ function registerArtifactCatalogRoutes(app, deps) {
129780
130918
  throw new HTTPException119(422, { message: "Invalid artifact pin request" });
129781
130919
  const artifactId2 = editableKinds.has(kind.data) ? requestedId : requestedId.toLowerCase();
129782
130920
  const fileKind = kind.data === "file" || kind.data === "image";
129783
- if (!hasPermission36(grant.permissions, fileKind ? "files:read" : "artifacts:read"))
130921
+ if (!hasPermission37(grant.permissions, fileKind ? "files:read" : "artifacts:read"))
129784
130922
  throw new HTTPException119(403, { message: "Artifact read access required" });
129785
130923
  const actor = fileKind ? await fileOwnerContextForAccess5(deps, authorization, "files:read") : { subjectId: grant.subjectId, privateFileOwnerSubjectId: null };
129786
130924
  context.header("cache-control", "private, no-store");
@@ -129832,7 +130970,7 @@ function registerArtifactCatalogRoutes(app, deps) {
129832
130970
  }
129833
130971
  );
129834
130972
  } catch (error) {
129835
- if (nestedPostgresSqlState17(error) === "42501")
130973
+ if (nestedPostgresSqlState18(error) === "42501")
129836
130974
  throw new HTTPException119(404, { message: "Artifact not found" });
129837
130975
  throw error;
129838
130976
  }
@@ -129849,8 +130987,8 @@ function registerArtifactCatalogRoutes(app, deps) {
129849
130987
  if (!parsed.success)
129850
130988
  throw new HTTPException119(422, { message: "Invalid artifact catalog query" });
129851
130989
  const query = parsed.data;
129852
- const artifactsAllowed = hasPermission36(grant.permissions, "artifacts:read");
129853
- const filesAllowed = hasPermission36(grant.permissions, "files:read");
130990
+ const artifactsAllowed = hasPermission37(grant.permissions, "artifacts:read");
130991
+ const filesAllowed = hasPermission37(grant.permissions, "files:read");
129854
130992
  if (!artifactsAllowed && !filesAllowed)
129855
130993
  throw new HTTPException119(403, { message: "Artifact catalog read access required" });
129856
130994
  let kinds = ArtifactCatalogKind3.options.filter(
@@ -129878,7 +131016,7 @@ function registerArtifactCatalogRoutes(app, deps) {
129878
131016
  }
129879
131017
  const sourceDecisions = /* @__PURE__ */ new Map();
129880
131018
  const canReadSession = async (sessionId) => {
129881
- if (!hasPermission36(grant.permissions, "sessions:read")) return false;
131019
+ if (!hasPermission37(grant.permissions, "sessions:read")) return false;
129882
131020
  if (sourceDecisions.has(sessionId)) return sourceDecisions.get(sessionId);
129883
131021
  try {
129884
131022
  await requireSessionAuthorization18(deps, grant, {
@@ -129886,7 +131024,7 @@ function registerArtifactCatalogRoutes(app, deps) {
129886
131024
  operation: "session.read",
129887
131025
  surface: "http"
129888
131026
  });
129889
- if (!await getSessionAuthorityProjection3(deps.db, workspaceId, sessionId)) {
131027
+ if (!await getSessionAuthorityProjection4(deps.db, workspaceId, sessionId)) {
129890
131028
  sourceDecisions.set(sessionId, false);
129891
131029
  return false;
129892
131030
  }
@@ -130165,6 +131303,8 @@ function registerInsightsRoutes(app, deps) {
130165
131303
  import {
130166
131304
  InsightsCallsResponse,
130167
131305
  InsightsUsageResponse,
131306
+ InsightsSiteUsageQuery,
131307
+ InsightsSiteUsageResponse,
130168
131308
  OrganizationInsightsCallsQuery,
130169
131309
  OrganizationInsightsUsageQuery,
130170
131310
  WorkspaceInsightsCallsQuery,
@@ -130173,10 +131313,12 @@ import {
130173
131313
  import {
130174
131314
  accountScopedApiKeyWorkspaceAuthority as accountScopedApiKeyWorkspaceAuthority7,
130175
131315
  getInsightsUsage,
130176
- hasPermission as hasPermission37,
131316
+ getInsightsSiteUsage,
131317
+ hasPermission as hasPermission38,
130177
131318
  listInsightsCalls,
130178
131319
  requireAccessContext as requireAccessContext15,
130179
- requireAccessGrant as requireAccessGrant58
131320
+ requireAccessGrant as requireAccessGrant58,
131321
+ siteViewerForGrant as siteViewerForGrant10
130180
131322
  } from "@opengeni/core";
130181
131323
  import {
130182
131324
  currentSessionRlsActorIdentityKey as currentSessionRlsActorIdentityKey2,
@@ -130314,7 +131456,7 @@ function insightsUsageCoalesceKey(scope, query, actor) {
130314
131456
  function organizationInsightsScope(context, accountId) {
130315
131457
  const authority = accountScopedApiKeyWorkspaceAuthority7(context);
130316
131458
  if (authority?.accountId === accountId) {
130317
- const readable = hasPermission37(
131459
+ const readable = hasPermission38(
130318
131460
  authority.permissions,
130319
131461
  "sessions:read",
130320
131462
  authority.permissionMode
@@ -130332,7 +131474,7 @@ function organizationInsightsScope(context, accountId) {
130332
131474
  detailsWorkspaceIds: [
130333
131475
  ...new Set(
130334
131476
  context.workspaceGrants.filter(
130335
- (grant) => grant.accountId === accountId && grant.subjectId === context.subjectId && hasPermission37(grant.permissions, "sessions:read", grant.permissionMode)
131477
+ (grant) => grant.accountId === accountId && grant.subjectId === context.subjectId && hasPermission38(grant.permissions, "sessions:read", grant.permissionMode)
130336
131478
  ).map((grant) => grant.workspaceId)
130337
131479
  )
130338
131480
  ].sort(),
@@ -130378,6 +131520,23 @@ function registerInsightsUsageRoutes(app, deps) {
130378
131520
  return response;
130379
131521
  });
130380
131522
  }
131523
+ app.get("/v1/workspaces/:workspaceId/insights/sites", async (c) => {
131524
+ const workspaceId = c.req.param("workspaceId");
131525
+ const grant = await requireAccessGrant58(c, deps, workspaceId, "workspace:admin");
131526
+ const query = InsightsSiteUsageQuery.safeParse(insightsQueryParameters(c.req.queries()));
131527
+ if (!query.success) throw new HTTPException122(400, { message: "invalid Site Insights query" });
131528
+ const viewer = await siteViewerForGrant10(deps.db, grant);
131529
+ const response = await insightsWithFriendlyTimeout(
131530
+ () => getInsightsSiteUsage(deps.db, {
131531
+ accountId: grant.accountId,
131532
+ workspaceId,
131533
+ query: query.data,
131534
+ viewerSubjectId: viewer.subjectId
131535
+ })
131536
+ );
131537
+ c.header("cache-control", "private, no-store");
131538
+ return c.json(InsightsSiteUsageResponse.parse(response));
131539
+ });
130381
131540
  app.get("/v1/workspaces/:workspaceId/insights/usage", async (c) => {
130382
131541
  const workspaceId = c.req.param("workspaceId");
130383
131542
  const grant = await requireAccessGrant58(c, deps, workspaceId, "workspace:admin");
@@ -130389,7 +131548,7 @@ function registerInsightsUsageRoutes(app, deps) {
130389
131548
  const scope = {
130390
131549
  accountId: grant.accountId,
130391
131550
  workspaceId,
130392
- detailsWorkspaceIds: hasPermission37(grant.permissions, "sessions:read", grant.permissionMode) ? [workspaceId] : []
131551
+ detailsWorkspaceIds: hasPermission38(grant.permissions, "sessions:read", grant.permissionMode) ? [workspaceId] : []
130393
131552
  };
130394
131553
  const response = await cached(
130395
131554
  c,
@@ -130415,7 +131574,7 @@ function registerInsightsUsageRoutes(app, deps) {
130415
131574
  const scope = {
130416
131575
  accountId: grant.accountId,
130417
131576
  workspaceId,
130418
- detailsWorkspaceIds: hasPermission37(grant.permissions, "sessions:read", grant.permissionMode) ? [workspaceId] : []
131577
+ detailsWorkspaceIds: hasPermission38(grant.permissions, "sessions:read", grant.permissionMode) ? [workspaceId] : []
130419
131578
  };
130420
131579
  const response = await cached(
130421
131580
  c,
@@ -131663,7 +132822,7 @@ import {
131663
132822
  } from "@opengeni/core";
131664
132823
 
131665
132824
  // src/model-calls/chat-completions.ts
131666
- import { ReasoningEffort } from "@opengeni/contracts";
132825
+ import { ReasoningEffort as ReasoningEffort2 } from "@opengeni/contracts";
131667
132826
  import { ModelCallError } from "@opengeni/core";
131668
132827
  import {
131669
132828
  normalizeModelCallUsage
@@ -131704,7 +132863,7 @@ var ChatCompletionRequest = z69.object({
131704
132863
  temperature: z69.number().min(0).max(2).nullish(),
131705
132864
  top_p: z69.number().min(0).max(1).nullish(),
131706
132865
  stop: z69.union([z69.string(), z69.array(z69.string()).max(4)]).nullish(),
131707
- reasoning_effort: ReasoningEffort.nullish(),
132866
+ reasoning_effort: ReasoningEffort2.nullish(),
131708
132867
  verbosity: z69.enum(["low", "medium", "high"]).nullish(),
131709
132868
  response_format: z69.object({ type: z69.string() }).passthrough().nullish(),
131710
132869
  stream: z69.boolean().nullish(),
@@ -132773,7 +133932,7 @@ import {
132773
133932
  requireSessionAuthorization as requireSessionAuthorization19,
132774
133933
  SessionAuthorizationDeniedError as SessionAuthorizationDeniedError18,
132775
133934
  SessionAuthorizationUnavailableError as SessionAuthorizationUnavailableError16,
132776
- siteViewerForGrant as siteViewerForGrant10
133935
+ siteViewerForGrant as siteViewerForGrant11
132777
133936
  } from "@opengeni/core";
132778
133937
  import {
132779
133938
  getGeneratedImageArtifact as getGeneratedImageArtifact3,
@@ -132827,7 +133986,7 @@ function registerSessionArtifactAssociationRoutes(app, deps) {
132827
133986
  ) : await hasWorkspaceArtifactSessionLink(
132828
133987
  deps.db,
132829
133988
  workspaceId,
132830
- await siteViewerForGrant10(deps.db, grant),
133989
+ await siteViewerForGrant11(deps.db, grant),
132831
133990
  sessionId,
132832
133991
  artifactId2
132833
133992
  );
@@ -133129,7 +134288,7 @@ import {
133129
134288
  StartManagedAuthSocialTransactionRequest,
133130
134289
  StartManagedAuthSocialTransactionResponse
133131
134290
  } from "@opengeni/contracts/managed-auth-session-sets";
133132
- import { hasPermission as hasPermission38, requireSessionAuthorization as requireSessionAuthorization20 } from "@opengeni/core";
134291
+ import { hasPermission as hasPermission39, requireSessionAuthorization as requireSessionAuthorization20 } from "@opengeni/core";
133133
134292
  import {
133134
134293
  authenticateAndAdoptManagedAuthSession,
133135
134294
  isolatedManagedAuthHeaders,
@@ -133812,7 +134971,7 @@ async function resolveCanonicalDeepLink(deps, authority, path, expectedActorEpoc
133812
134971
  const grants = target.workspaceId ? access.workspaceGrants.filter((grant) => grant.workspaceId === target.workspaceId) : access.workspaceGrants;
133813
134972
  let authorized = false;
133814
134973
  for (const grant of grants) {
133815
- if (!hasPermission38(grant.permissions, target.sessionId ? "sessions:read" : target.permission)) {
134974
+ if (!hasPermission39(grant.permissions, target.sessionId ? "sessions:read" : target.permission)) {
133816
134975
  continue;
133817
134976
  }
133818
134977
  if (target.sessionId) {
@@ -134668,7 +135827,7 @@ import {
134668
135827
  getManagedSession as getManagedSession5,
134669
135828
  accountScopedApiKeyWorkspaceAuthority as accountScopedApiKeyWorkspaceAuthority8,
134670
135829
  organizationWorkspaceInScope as organizationWorkspaceInScope3,
134671
- hasPermission as hasPermission39,
135830
+ hasPermission as hasPermission40,
134672
135831
  requireAccessContext as requireAccessContext16,
134673
135832
  organizationMembershipHttpStatus,
134674
135833
  requireCanonicalLocalAccountAdministrator as requireCanonicalLocalAccountAdministrator4,
@@ -134692,7 +135851,7 @@ import {
134692
135851
  listOrganizationAdministrationMembers as listOrganizationAdministrationMembers2,
134693
135852
  listOrganizationInvitations,
134694
135853
  listSelfOrganizationInvitations,
134695
- nestedPostgresSqlState as nestedPostgresSqlState18,
135854
+ nestedPostgresSqlState as nestedPostgresSqlState19,
134696
135855
  prepareOrganizationUserSetupDelivery,
134697
135856
  revokeOrganizationInvitation,
134698
135857
  settleOrganizationUserSetupDelivery,
@@ -134736,7 +135895,7 @@ async function requirePrivateSessionAdministrator(context, deps, organizationId2
134736
135895
  async function requireOrganizationKeyWorkspaceDeletion(context, deps, organizationId2, workspaceId) {
134737
135896
  const access = await requireAccessContext16(context, deps);
134738
135897
  const key2 = accountScopedApiKeyWorkspaceAuthority8(access);
134739
- if (!key2 || key2.accountId !== organizationId2 || !hasPermission39(key2.permissions, "workspace:admin")) {
135898
+ if (!key2 || key2.accountId !== organizationId2 || !hasPermission40(key2.permissions, "workspace:admin")) {
134740
135899
  throw new HTTPException128(403, {
134741
135900
  message: "deleting an organization workspace requires an organization owner session or an organization API key with workspace:admin"
134742
135901
  });
@@ -134809,7 +135968,7 @@ function parseId3(schema, value, label) {
134809
135968
  return parsed.data;
134810
135969
  }
134811
135970
  function rethrowMembershipError(error, resourceLimitMessage) {
134812
- const sqlState = nestedPostgresSqlState18(error);
135971
+ const sqlState = nestedPostgresSqlState19(error);
134813
135972
  if (sqlState === "54000" && resourceLimitMessage) {
134814
135973
  throw new HTTPException128(409, {
134815
135974
  message: resourceLimitMessage
@@ -134915,7 +136074,7 @@ function registerOrganizationMembershipRoutes(app, deps) {
134915
136074
  })
134916
136075
  );
134917
136076
  } catch (error) {
134918
- if (nestedPostgresSqlState18(error) === "42501") {
136077
+ if (nestedPostgresSqlState19(error) === "42501") {
134919
136078
  throw new HTTPException128(403, {
134920
136079
  message: "organization membership is not active"
134921
136080
  });
@@ -135604,7 +136763,7 @@ import {
135604
136763
  import {
135605
136764
  accountScopedApiKeyWorkspaceAuthority as accountScopedApiKeyWorkspaceAuthority9,
135606
136765
  organizationWorkspaceInScope as organizationWorkspaceInScope4,
135607
- hasPermission as hasPermission40,
136766
+ hasPermission as hasPermission41,
135608
136767
  requireAccessContext as requireAccessContext17,
135609
136768
  requireAccessGrantAuthorization as requireAccessGrantAuthorization40,
135610
136769
  requireSessionAuthorizationListScope as requireSessionAuthorizationListScope3,
@@ -135649,7 +136808,7 @@ function decodeOrganizationSessionListCursor(value) {
135649
136808
  function requireOrganizationSessionReadAuthority(context, organizationId2) {
135650
136809
  const authority = accountScopedApiKeyWorkspaceAuthority9(context);
135651
136810
  if (authority) {
135652
- if (authority.accountId === organizationId2 && hasPermission40(authority.permissions, "sessions:read")) {
136811
+ if (authority.accountId === organizationId2 && hasPermission41(authority.permissions, "sessions:read")) {
135653
136812
  return "organization_api_key";
135654
136813
  }
135655
136814
  throw new HTTPException129(403, { message: "organization session read authority required" });
@@ -136114,7 +137273,7 @@ import {
136114
137273
  completeSelfServiceOrganizationSetup,
136115
137274
  completeOrganizationUserSetup,
136116
137275
  getSelfServiceOrganizationOnboardingState,
136117
- nestedPostgresSqlState as nestedPostgresSqlState19,
137276
+ nestedPostgresSqlState as nestedPostgresSqlState20,
136118
137277
  preflightOrganizationUserSetup,
136119
137278
  previewOrganizationUserSetup,
136120
137279
  recordOrganizationSignupUseCase
@@ -136172,14 +137331,14 @@ function registerManagedOnboardingRoutes(app, deps, options = {}) {
136172
137331
  useCase: parsed.data.useCase
136173
137332
  }).catch((error) => {
136174
137333
  console.warn("[api] could not record the signup use case", {
136175
- sqlState: nestedPostgresSqlState19(error) ?? null
137334
+ sqlState: nestedPostgresSqlState20(error) ?? null
136176
137335
  });
136177
137336
  });
136178
137337
  }
136179
137338
  return context.json(completed);
136180
137339
  } catch (error) {
136181
137340
  recordOrganizationSetupOutcome(deps.observability, "failed");
136182
- const sqlState = nestedPostgresSqlState19(error);
137341
+ const sqlState = nestedPostgresSqlState20(error);
136183
137342
  if (sqlState === "22023") {
136184
137343
  throw new HTTPException131(422, {
136185
137344
  message: "invalid organization setup request"
@@ -136259,7 +137418,7 @@ function registerManagedOnboardingRoutes(app, deps, options = {}) {
136259
137418
  )
136260
137419
  );
136261
137420
  } catch (error) {
136262
- const sqlState = nestedPostgresSqlState19(error);
137421
+ const sqlState = nestedPostgresSqlState20(error);
136263
137422
  if (sqlState === "22023") {
136264
137423
  throw new HTTPException131(422, {
136265
137424
  message: "invalid account setup request"
@@ -136624,7 +137783,7 @@ import {
136624
137783
  SessionAuthorizationUnavailableError as SessionAuthorizationUnavailableError18,
136625
137784
  SessionTenancyManagedHumanRequiredError as SessionTenancyManagedHumanRequiredError3
136626
137785
  } from "@opengeni/core";
136627
- import { nestedPostgresSqlState as nestedPostgresSqlState20, SessionTenancyNotActivatedError as SessionTenancyNotActivatedError3 } from "@opengeni/db";
137786
+ import { nestedPostgresSqlState as nestedPostgresSqlState21, SessionTenancyNotActivatedError as SessionTenancyNotActivatedError3 } from "@opengeni/db";
136628
137787
  import { HTTPException as HTTPException133 } from "hono/http-exception";
136629
137788
  import { z as z78 } from "zod";
136630
137789
  async function body4(context, schema) {
@@ -136639,10 +137798,10 @@ function lifecycleError(error) {
136639
137798
  if (error instanceof SessionAuthorizationUnavailableError18) {
136640
137799
  throw new HTTPException133(503, { message: "session authorization unavailable" });
136641
137800
  }
136642
- if (nestedPostgresSqlState20(error) === "42501") {
137801
+ if (nestedPostgresSqlState21(error) === "42501") {
136643
137802
  throw new HTTPException133(403, { message: "user-resource authority denied" });
136644
137803
  }
136645
- if (nestedPostgresSqlState20(error) === "22023") {
137804
+ if (nestedPostgresSqlState21(error) === "22023") {
136646
137805
  throw new HTTPException133(422, { message: "invalid user-resource request" });
136647
137806
  }
136648
137807
  throw error;
@@ -137953,7 +139112,7 @@ import {
137953
139112
  controlHumanSessionWorkstream as controlHumanSessionWorkstream2,
137954
139113
  createSessionForRequest as createSessionForRequest2,
137955
139114
  getActorNewSessionModelChoice,
137956
- hasPermission as hasPermission42,
139115
+ hasPermission as hasPermission43,
137957
139116
  requireAccessContext as requireAccessContext18,
137958
139117
  requireAccessGrant as requireAccessGrant63,
137959
139118
  requireSessionAuthorizationListScope as requireSessionAuthorizationListScope4,
@@ -137967,7 +139126,7 @@ import {
137967
139126
  resourceMountPathCollisionKey
137968
139127
  } from "@opengeni/contracts";
137969
139128
  import { listRecentSessionRepositoryResources } from "@opengeni/db";
137970
- import { hasPermission as hasPermission41 } from "@opengeni/core";
139129
+ import { hasPermission as hasPermission42 } from "@opengeni/core";
137971
139130
  var SLACK_SESSION_RECENT_REPOSITORY_LIMIT = 5;
137972
139131
  var SLACK_SESSION_RECENT_REPOSITORY_WINDOW_MS = 30 * 24 * 60 * 60 * 1e3;
137973
139132
  function githubUriKey(uri) {
@@ -138032,7 +139191,7 @@ function selectRecentRepositoryResources(recent, catalog, limit = SLACK_SESSION_
138032
139191
  return resources;
138033
139192
  }
138034
139193
  async function slackRecentRepositoryResources(deps, grant, workspaceId, now = /* @__PURE__ */ new Date()) {
138035
- if (!hasPermission41(grant.permissions, "github:use")) return [];
139194
+ if (!hasPermission42(grant.permissions, "github:use")) return [];
138036
139195
  const recent = await listRecentSessionRepositoryResources(deps.db, {
138037
139196
  workspaceId,
138038
139197
  subjectId: grant.subjectId,
@@ -139335,7 +140494,7 @@ function registerSlackInteractionRoutes(app, deps) {
139335
140494
  targetAccountId: grant.accountId,
139336
140495
  targetWorkspaceId: route2.targetWorkspaceId
139337
140496
  });
139338
- if (!authorized || !hasPermission42(authorized.permissions, "sessions:create")) {
140497
+ if (!authorized || !hasPermission43(authorized.permissions, "sessions:create")) {
139339
140498
  throw new HTTPException134(403, {
139340
140499
  message: `you cannot start work in the workspace chosen for ${route2.slackChannelId}`
139341
140500
  });
@@ -139418,7 +140577,7 @@ async function publishSlackAppHome(deps, installation, refresh, renewLease) {
139418
140577
  const grant = link ? await getWorkspaceGrant5(deps.db, link.subjectId, installation.workspaceId, {
139419
140578
  principalKind: "human_session"
139420
140579
  }) : null;
139421
- if (!grant || grant.accountId !== installation.accountId || !hasPermission42(grant.permissions, "sessions:read")) {
140580
+ if (!grant || grant.accountId !== installation.accountId || !hasPermission43(grant.permissions, "sessions:read")) {
139422
140581
  const client2 = await createOpenGeniSlackBotInteractionClient(deps, {
139423
140582
  accountId: installation.accountId,
139424
140583
  workspaceId: installation.workspaceId,
@@ -139496,7 +140655,7 @@ async function publishSlackAppHome(deps, installation, refresh, renewLease) {
139496
140655
  const currentGrant = currentLink ? await getWorkspaceGrant5(deps.db, currentLink.subjectId, installation.workspaceId, {
139497
140656
  principalKind: "human_session"
139498
140657
  }) : null;
139499
- if (!currentLink || currentLink.subjectId !== grant.subjectId || !currentGrant || currentGrant.accountId !== installation.accountId || !hasPermission42(currentGrant.permissions, "sessions:read")) {
140658
+ if (!currentLink || currentLink.subjectId !== grant.subjectId || !currentGrant || currentGrant.accountId !== installation.accountId || !hasPermission43(currentGrant.permissions, "sessions:read")) {
139500
140659
  await publishSlackAppHomeAccessView(
139501
140660
  client,
139502
140661
  refresh,
@@ -140049,7 +141208,7 @@ async function handleSlackRouteChoice(deps, home, entry2, actionId, optionId) {
140049
141208
  targetAccountId: chosen.candidateAccountId,
140050
141209
  targetWorkspaceId: chosen.candidateWorkspaceId
140051
141210
  }) : null;
140052
- if (!grant || !hasPermission42(grant.permissions, "sessions:create")) {
141211
+ if (!grant || !hasPermission43(grant.permissions, "sessions:create")) {
140053
141212
  await client.postMessage({
140054
141213
  operationId: deterministicUuid2(`slack-route-denied:${prompt.id}:${chosen.id}`),
140055
141214
  userId: entry2.slackUserId,
@@ -140258,7 +141417,7 @@ async function processSlackInboxEntry(deps, entry2) {
140258
141417
  });
140259
141418
  return;
140260
141419
  }
140261
- if (!hasPermission42(grant.permissions, "sessions:create")) {
141420
+ if (!hasPermission43(grant.permissions, "sessions:create")) {
140262
141421
  throw new SlackInteractionPermanentError("sessions_create_denied");
140263
141422
  }
140264
141423
  const { interaction } = await getOrCreateSlackInteraction(deps.db, {
@@ -140708,7 +141867,7 @@ async function processSlackReactionInboxEntry(deps, entry2) {
140708
141867
  if (!resolved) {
140709
141868
  throw new SlackInteractionPermanentError("identity_access_revoked");
140710
141869
  }
140711
- if (!hasPermission42(resolved.permissions, "sessions:create") || !hasPermission42(resolved.permissions, "sessions:control")) {
141870
+ if (!hasPermission43(resolved.permissions, "sessions:create") || !hasPermission43(resolved.permissions, "sessions:control")) {
140712
141871
  throw new SlackInteractionPermanentError("reaction_session_permissions_denied");
140713
141872
  }
140714
141873
  return resolved;
@@ -141253,7 +142412,7 @@ async function continueSlackSession(deps, grant, interaction, entry2, resources
141253
142412
  const sessionId = interaction.sessionId;
141254
142413
  await reopenSlackInteractionDelivery(deps.db, interaction);
141255
142414
  if (entry2.text.trim().toLowerCase() === "stop") {
141256
- if (!hasPermission42(grant.permissions, "sessions:control")) {
142415
+ if (!hasPermission43(grant.permissions, "sessions:control")) {
141257
142416
  throw new SlackInteractionPermanentError("sessions_control_denied");
141258
142417
  }
141259
142418
  await controlHumanSessionWorkstream2(
@@ -141332,7 +142491,7 @@ async function continueSlackSession(deps, grant, interaction, entry2, resources
141332
142491
  }
141333
142492
  }
141334
142493
  }
141335
- if (!hasPermission42(grant.permissions, "sessions:control")) {
142494
+ if (!hasPermission43(grant.permissions, "sessions:control")) {
141336
142495
  throw new SlackInteractionPermanentError("sessions_control_denied");
141337
142496
  }
141338
142497
  await withSlackAllowanceAdmissionNotice(deps, entry2, interaction, async () => {
@@ -141444,7 +142603,7 @@ async function processSlackBlockAction(deps, entry2) {
141444
142603
  targetAccountId: target.accountId,
141445
142604
  targetWorkspaceId: target.workspaceId
141446
142605
  });
141447
- if (!grant || !hasPermission42(grant.permissions, "sessions:control")) {
142606
+ if (!grant || !hasPermission43(grant.permissions, "sessions:control")) {
141448
142607
  throw new SlackInteractionPermanentError("sessions_control_denied");
141449
142608
  }
141450
142609
  const client = await createOpenGeniSlackBotInteractionClient(deps, {
@@ -141804,7 +142963,7 @@ async function executeSlackAction(deps, grant, interaction, handle) {
141804
142963
  }
141805
142964
  const session = await getSession18(deps.db, grant.workspaceId, handle.sessionId);
141806
142965
  if (!session) throw new SlackInteractionPermanentError("slack_action_session_missing");
141807
- const recurring = hasPermission42(grant.permissions, "sessions:read") && hasPermission42(grant.permissions, "scheduled_tasks:manage") ? makeRecurringText(deps, grant.workspaceId, handle.sessionId) : null;
142966
+ const recurring = hasPermission43(grant.permissions, "sessions:read") && hasPermission43(grant.permissions, "scheduled_tasks:manage") ? makeRecurringText(deps, grant.workspaceId, handle.sessionId) : null;
141808
142967
  return {
141809
142968
  result: "status",
141810
142969
  text: `${mention}Opengeni task status: *${session.status.replaceAll("_", " ")}*.${recurring ? `
@@ -142891,7 +144050,7 @@ async function slackInfoCommandResponse(deps, installation, entry2) {
142891
144050
  const grant = link ? await getWorkspaceGrant5(deps.db, link.subjectId, installation.workspaceId, {
142892
144051
  principalKind: "human_session"
142893
144052
  }) : null;
142894
- if (!grant || grant.accountId !== installation.accountId || !hasPermission42(grant.permissions, "sessions:read")) {
144053
+ if (!grant || grant.accountId !== installation.accountId || !hasPermission43(grant.permissions, "sessions:read")) {
142895
144054
  return ephemeralSlackResponse(
142896
144055
  link ? `Your Slack identity is linked, but it does not currently have access to this Opengeni workspace. Request access: ${linkUrl(deps, identity2)}. No session was created.` : `Link your Slack identity to Opengeni before starting work: ${linkUrl(deps, identity2)}. No session was created.`
142897
144056
  );
@@ -142899,9 +144058,9 @@ async function slackInfoCommandResponse(deps, installation, entry2) {
142899
144058
  const workspace = await getWorkspace15(deps.db, installation.workspaceId);
142900
144059
  const command = deps.settings.slackCommand;
142901
144060
  const botMention = slackBotMention(installation.botUserId);
142902
- const canControl = hasPermission42(grant.permissions, "sessions:control");
142903
- const canCreate = hasPermission42(grant.permissions, "sessions:create");
142904
- const canSchedule = hasPermission42(grant.permissions, "scheduled_tasks:manage");
144061
+ const canControl = hasPermission43(grant.permissions, "sessions:control");
144062
+ const canCreate = hasPermission43(grant.permissions, "sessions:create");
144063
+ const canSchedule = hasPermission43(grant.permissions, "scheduled_tasks:manage");
142905
144064
  const schedules = canSchedule ? slackSchedulesUrl(deps, installation.workspaceId) : null;
142906
144065
  const agentSchedules = canSchedule && canControl && slackTaskFirstPartyMcpTools(deps.settings, workspace?.settings).includes(
142907
144066
  "scheduled_tasks_create"
@@ -144047,7 +145206,7 @@ function createAppComposition(deps) {
144047
145206
  { accountId: grant.accountId, workspaceId, subjectId: grant.subjectId },
144048
145207
  { observeAvailability: true }
144049
145208
  );
144050
- if (!hasPermission43(grant.permissions, "sessions:create")) {
145209
+ if (!hasPermission44(grant.permissions, "sessions:create")) {
144051
145210
  modelSelectionForbidden = true;
144052
145211
  selections = [];
144053
145212
  }
@@ -144061,7 +145220,7 @@ function createAppComposition(deps) {
144061
145220
  preferredProvider: voicePreferences?.preferredProvider,
144062
145221
  fallbackEnabled: voicePreferences?.fallbackEnabled
144063
145222
  };
144064
- if (hasPermission43(grant.permissions, "sessions:create") && transcription) {
145223
+ if (hasPermission44(grant.permissions, "sessions:create") && transcription) {
144065
145224
  voiceInputProviders = await transcription.availableProviderIds?.(voiceContext) ?? [];
144066
145225
  voiceInputAvailable = voiceInputProviders.length > 0 && await Promise.resolve(transcription.available(voiceContext)).catch(() => false);
144067
145226
  }
@@ -144356,8 +145515,8 @@ function createAppComposition(deps) {
144356
145515
  throw error;
144357
145516
  }
144358
145517
  const grant = authorization.grant;
144359
- const outsideAgentContext = AsyncLocalStorage3.snapshot();
144360
- return await withSessionAuthorizationReadReuse(
145518
+ const outsideAgentContext = AsyncLocalStorage4.snapshot();
145519
+ return await withSessionAuthorizationReadReuse3(
144361
145520
  (reads) => withAccessGrantSessionRlsContext(routeDeps, grant, async () => {
144362
145521
  const boundSessionId = grant.metadata?.sessionId;
144363
145522
  if (typeof boundSessionId === "string") {
@@ -144454,7 +145613,7 @@ function createAppComposition(deps) {
144454
145613
  reauthorize: async () => {
144455
145614
  const live = await requireFreshAccessGrant5(c, routeDeps, workspaceId, "workspace:read");
144456
145615
  const original = authorization.grant;
144457
- if (live.accountId !== original.accountId || live.subjectId !== original.subjectId || live.principalKind !== original.principalKind || original.permissions.some((permission) => !hasPermission43(live.permissions, permission)))
145616
+ if (live.accountId !== original.accountId || live.subjectId !== original.subjectId || live.principalKind !== original.principalKind || original.permissions.some((permission) => !hasPermission44(live.permissions, permission)))
144458
145617
  throw new HTTPException135(403, { message: "tool_access_changed" });
144459
145618
  },
144460
145619
  onFence: (created) => {
@@ -144701,7 +145860,17 @@ function createAppComposition(deps) {
144701
145860
  const interactionSecrets = createVaultInteractionSecretsPort({
144702
145861
  db: routeDeps.db,
144703
145862
  encryptionKey: environmentsEncryptionKeyBytes14(routeDeps.settings) ?? null,
144704
- providersFor: (workspaceId, subjectId) => vaultProviderRegistryFor(routeDeps, { workspaceId, subjectId })
145863
+ providersFor: (workspaceId, subjectId, principal) => vaultProviderRegistryFor(routeDeps, {
145864
+ workspaceId,
145865
+ subjectId,
145866
+ ...principal ? {
145867
+ executionContext: {
145868
+ sessionId: principal.sessionId,
145869
+ turnId: principal.turnId,
145870
+ attemptId: principal.attemptId
145871
+ }
145872
+ } : {}
145873
+ })
144705
145874
  });
144706
145875
  registerBrowserSessionRoutes(app, routeDeps, { interactionSecrets });
144707
145876
  registerComputerSessionRoutes(app, routeDeps, { interactionSecrets });
@@ -144898,7 +146067,7 @@ async function validateCodexAccountTarget(request) {
144898
146067
  async function requireMcpAccessGrantAuthorization(c, deps, workspaceId) {
144899
146068
  const authorization = await requireAccessGrantAuthorization42(c, deps, workspaceId);
144900
146069
  const grant = authorization.grant;
144901
- if (hasPermission43(grant.permissions, "workspace:read")) {
146070
+ if (hasPermission44(grant.permissions, "workspace:read")) {
144902
146071
  return authorization;
144903
146072
  }
144904
146073
  if (isCodemodeGrant(grant)) {
@@ -146289,6 +147458,7 @@ export {
146289
147458
  apiRequestBindingsForTransportPeer,
146290
147459
  reconcileScreenControlOnHello,
146291
147460
  withAccessGrantSessionRlsContext,
147461
+ closeNativeExternalVaultProviders,
146292
147462
  SlackBotProviderError,
146293
147463
  createOpenGeniSlackBotInteractionClient,
146294
147464
  startTemporalScheduleCleanupPump,
@@ -146329,4 +147499,4 @@ export {
146329
147499
  withDefaultEnabledCapabilityMcpTools,
146330
147500
  workflowIdForSession4 as workflowIdForSession
146331
147501
  };
146332
- //# sourceMappingURL=chunk-OT56OY4V.js.map
147502
+ //# sourceMappingURL=chunk-6CECHDZP.js.map