@keystrokehq/keystroke 1.0.8 → 1.0.9

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 (91) hide show
  1. package/dist/action.cjs +3 -1
  2. package/dist/action.d.cts +3 -3
  3. package/dist/action.d.mts +3 -3
  4. package/dist/action.mjs +2 -2
  5. package/dist/agent.cjs +21 -10
  6. package/dist/agent.cjs.map +1 -1
  7. package/dist/agent.d.cts +2 -2
  8. package/dist/agent.d.mts +2 -2
  9. package/dist/agent.mjs +21 -10
  10. package/dist/agent.mjs.map +1 -1
  11. package/dist/app.cjs +1 -1
  12. package/dist/app.d.cts +2 -2
  13. package/dist/app.d.mts +2 -2
  14. package/dist/app.mjs +1 -1
  15. package/dist/client.cjs +13 -7
  16. package/dist/client.cjs.map +1 -1
  17. package/dist/client.d.cts.map +1 -1
  18. package/dist/client.d.mts.map +1 -1
  19. package/dist/client.mjs +13 -7
  20. package/dist/client.mjs.map +1 -1
  21. package/dist/config.d.cts +1 -1
  22. package/dist/config.d.mts +1 -1
  23. package/dist/credentials.cjs +1 -1
  24. package/dist/credentials.d.cts +1 -1
  25. package/dist/credentials.d.mts +1 -1
  26. package/dist/credentials.mjs +1 -1
  27. package/dist/{dist-DQL6zTI5.cjs → dist-C0fPHFaM.cjs} +20 -11
  28. package/dist/dist-C0fPHFaM.cjs.map +1 -0
  29. package/dist/{dist-DqFdFpiB.mjs → dist-CppO7361.mjs} +92 -9
  30. package/dist/dist-CppO7361.mjs.map +1 -0
  31. package/dist/{dist-C5otI4u3.cjs → dist-DivFQzKG.cjs} +236 -41
  32. package/dist/dist-DivFQzKG.cjs.map +1 -0
  33. package/dist/{dist-DOMwPx7V.cjs → dist-HI6bM6LK.cjs} +103 -8
  34. package/dist/dist-HI6bM6LK.cjs.map +1 -0
  35. package/dist/{dist-IUl7Bexl.mjs → dist-UzTnzZem.mjs} +231 -42
  36. package/dist/dist-UzTnzZem.mjs.map +1 -0
  37. package/dist/{dist-BpkCqbil.mjs → dist-nvW8vbKn.mjs} +20 -11
  38. package/dist/dist-nvW8vbKn.mjs.map +1 -0
  39. package/dist/{index-BMqj40Li.d.cts → index-3P7ec4Vo.d.cts} +4 -2
  40. package/dist/index-3P7ec4Vo.d.cts.map +1 -0
  41. package/dist/{index-nUAXCgEe.d.cts → index-BTz2OMAM.d.cts} +13 -3
  42. package/dist/index-BTz2OMAM.d.cts.map +1 -0
  43. package/dist/{index-8_UEbXaF.d.mts → index-Cq2F2XdS.d.mts} +13 -3
  44. package/dist/index-Cq2F2XdS.d.mts.map +1 -0
  45. package/dist/{index-Dgy9MjuX.d.cts → index-D4dAsbJr.d.cts} +20 -3
  46. package/dist/index-D4dAsbJr.d.cts.map +1 -0
  47. package/dist/{index-CWZAGTad.d.mts → index-D7UUmswR.d.mts} +4 -2
  48. package/dist/index-D7UUmswR.d.mts.map +1 -0
  49. package/dist/{index-BeBgntxT.d.mts → index-DdAOmbQc.d.mts} +9 -16
  50. package/dist/index-DdAOmbQc.d.mts.map +1 -0
  51. package/dist/{index-BY9SPR2h.d.cts → index-Ohwnfidc.d.cts} +9 -16
  52. package/dist/index-Ohwnfidc.d.cts.map +1 -0
  53. package/dist/{index-Bl4VEelg.d.mts → index-Sx9T2i0u.d.mts} +20 -3
  54. package/dist/index-Sx9T2i0u.d.mts.map +1 -0
  55. package/dist/{index-e9f4pcX4.d.cts → index-WT4ULMiw.d.cts} +14 -3
  56. package/dist/index-WT4ULMiw.d.cts.map +1 -0
  57. package/dist/{index-e9f4pcX4.d.mts → index-WT4ULMiw.d.mts} +14 -3
  58. package/dist/index-WT4ULMiw.d.mts.map +1 -0
  59. package/dist/{mistral-wOLLEgb9.cjs → mistral-CSlOhLAJ.cjs} +2 -2
  60. package/dist/{mistral-wOLLEgb9.cjs.map → mistral-CSlOhLAJ.cjs.map} +1 -1
  61. package/dist/{mistral-CMDejXQt.mjs → mistral-StBMjPiK.mjs} +2 -2
  62. package/dist/{mistral-CMDejXQt.mjs.map → mistral-StBMjPiK.mjs.map} +1 -1
  63. package/dist/{sse-DI7TsPKG.mjs → sse-CDOw-yuH.mjs} +2 -2
  64. package/dist/{sse-DI7TsPKG.mjs.map → sse-CDOw-yuH.mjs.map} +1 -1
  65. package/dist/{sse-Dzs73rQw.cjs → sse-CZOklzgA.cjs} +2 -2
  66. package/dist/{sse-Dzs73rQw.cjs.map → sse-CZOklzgA.cjs.map} +1 -1
  67. package/dist/trigger.cjs +1 -1
  68. package/dist/trigger.d.cts +3 -3
  69. package/dist/trigger.d.mts +3 -3
  70. package/dist/trigger.mjs +1 -1
  71. package/dist/workflow.cjs +1 -1
  72. package/dist/workflow.d.cts +2 -2
  73. package/dist/workflow.d.mts +2 -2
  74. package/dist/workflow.mjs +1 -1
  75. package/package.json +1 -1
  76. package/dist/dist-BpkCqbil.mjs.map +0 -1
  77. package/dist/dist-C5otI4u3.cjs.map +0 -1
  78. package/dist/dist-DOMwPx7V.cjs.map +0 -1
  79. package/dist/dist-DQL6zTI5.cjs.map +0 -1
  80. package/dist/dist-DqFdFpiB.mjs.map +0 -1
  81. package/dist/dist-IUl7Bexl.mjs.map +0 -1
  82. package/dist/index-8_UEbXaF.d.mts.map +0 -1
  83. package/dist/index-BMqj40Li.d.cts.map +0 -1
  84. package/dist/index-BY9SPR2h.d.cts.map +0 -1
  85. package/dist/index-BeBgntxT.d.mts.map +0 -1
  86. package/dist/index-Bl4VEelg.d.mts.map +0 -1
  87. package/dist/index-CWZAGTad.d.mts.map +0 -1
  88. package/dist/index-Dgy9MjuX.d.cts.map +0 -1
  89. package/dist/index-e9f4pcX4.d.cts.map +0 -1
  90. package/dist/index-e9f4pcX4.d.mts.map +0 -1
  91. package/dist/index-nUAXCgEe.d.cts.map +0 -1
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-DHdmVzO2.cjs");
2
- const require_dist$1 = require("./dist-DOMwPx7V.cjs");
2
+ const require_dist$1 = require("./dist-HI6bM6LK.cjs");
3
3
  let node_async_hooks = require("node:async_hooks");
4
4
  require("node:fs");
5
5
  require("node:path");
@@ -3119,6 +3119,9 @@ const requestHandle = new node_async_hooks.AsyncLocalStorage();
3119
3119
  function getRequestDatabaseHandle() {
3120
3120
  return requestHandle.getStore();
3121
3121
  }
3122
+ function isDatabaseInitialized() {
3123
+ return getRequestDatabaseHandle() !== void 0 || false;
3124
+ }
3122
3125
  function getDatabaseHandle$1() {
3123
3126
  const scoped = getRequestDatabaseHandle();
3124
3127
  if (scoped) return scoped;
@@ -3145,7 +3148,7 @@ const agents = pgTable("agents", {
3145
3148
  systemPrompt: text$1("system_prompt").notNull(),
3146
3149
  toolCount: integer$1("tool_count"),
3147
3150
  credentialCount: integer$1("credential_count"),
3148
- credentialKeys: jsonb("credential_keys").$type(),
3151
+ appSlugs: jsonb("app_slugs").$type(),
3149
3152
  registeredAt: timestamp("registered_at", { withTimezone: true }).notNull(),
3150
3153
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull(),
3151
3154
  deletedAt: timestamp("deleted_at", { withTimezone: true })
@@ -3162,7 +3165,7 @@ const agentsSqlite = sqliteTable("agents", {
3162
3165
  systemPrompt: text("system_prompt").notNull(),
3163
3166
  toolCount: integer("tool_count"),
3164
3167
  credentialCount: integer("credential_count"),
3165
- credentialKeys: text("credential_keys", { mode: "json" }).$type(),
3168
+ appSlugs: text("app_slugs", { mode: "json" }).$type(),
3166
3169
  registeredAt: integer("registered_at", { mode: "timestamp_ms" }).notNull(),
3167
3170
  updatedAt: integer("updated_at", { mode: "timestamp_ms" }).notNull(),
3168
3171
  deletedAt: integer("deleted_at", { mode: "timestamp_ms" })
@@ -3430,7 +3433,9 @@ const workflowHooksSqlite = sqliteTable("workflow_hooks", {
3430
3433
  const credentialInstances = pgTable("credential_instances", {
3431
3434
  id: text$1("id").primaryKey(),
3432
3435
  projectId: text$1("project_id").notNull(),
3436
+ appSlug: text$1("app_slug").notNull(),
3433
3437
  slug: text$1("slug").notNull(),
3438
+ name: text$1("name"),
3434
3439
  scopeType: text$1("scope_type").$type().notNull(),
3435
3440
  scopeId: text$1("scope_id"),
3436
3441
  label: text$1("label"),
@@ -3442,11 +3447,13 @@ const credentialInstances = pgTable("credential_instances", {
3442
3447
  sharedConnectionId: text$1("shared_connection_id"),
3443
3448
  createdAt: timestamp("created_at", { withTimezone: true }).notNull(),
3444
3449
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull()
3445
- }, (table) => [uniqueIndex$1("credential_instances_project_slug_scope_label_unique").on(table.projectId, table.slug, table.scopeType, table.scopeId, table.label), index$1("credential_instances_project_slug_scope_idx").on(table.projectId, table.slug, table.scopeType, table.scopeId)]);
3450
+ }, (table) => [uniqueIndex$1("credential_instances_project_scope_slug_unique").on(table.projectId, table.scopeType, table.scopeId, table.slug), index$1("credential_instances_project_app_slug_scope_idx").on(table.projectId, table.appSlug, table.scopeType, table.scopeId)]);
3446
3451
  const credentialInstancesSqlite = sqliteTable("credential_instances", {
3447
3452
  id: text("id").primaryKey(),
3448
3453
  projectId: text("project_id").notNull(),
3454
+ appSlug: text("app_slug").notNull(),
3449
3455
  slug: text("slug").notNull(),
3456
+ name: text("name"),
3450
3457
  scopeType: text("scope_type").$type().notNull(),
3451
3458
  scopeId: text("scope_id"),
3452
3459
  label: text("label"),
@@ -3458,7 +3465,30 @@ const credentialInstancesSqlite = sqliteTable("credential_instances", {
3458
3465
  sharedConnectionId: text("shared_connection_id"),
3459
3466
  createdAt: integer("created_at", { mode: "timestamp_ms" }).notNull(),
3460
3467
  updatedAt: integer("updated_at", { mode: "timestamp_ms" }).notNull()
3461
- }, (table) => [uniqueIndex("credential_instances_project_slug_scope_label_unique").on(table.projectId, table.slug, table.scopeType, table.scopeId, table.label), index("credential_instances_project_slug_scope_idx").on(table.projectId, table.slug, table.scopeType, table.scopeId)]);
3468
+ }, (table) => [uniqueIndex("credential_instances_project_scope_slug_unique").on(table.projectId, table.scopeType, table.scopeId, table.slug), index("credential_instances_project_app_slug_scope_idx").on(table.projectId, table.appSlug, table.scopeType, table.scopeId)]);
3469
+ const credentialAssignments = pgTable("credential_assignments", {
3470
+ id: text$1("id").primaryKey(),
3471
+ projectId: text$1("project_id").notNull(),
3472
+ targetType: text$1("target_type").$type().notNull(),
3473
+ targetKey: text$1("target_key").notNull(),
3474
+ /** '*' = wildcard; else runtime consumer id (step correlation id or tool slug). */
3475
+ consumerId: text$1("consumer_id").notNull(),
3476
+ credentialSlug: text$1("credential_slug").notNull(),
3477
+ instanceId: text$1("instance_id").notNull(),
3478
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull(),
3479
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull()
3480
+ }, (table) => [uniqueIndex$1("credential_assignments_project_target_consumer_slug").on(table.projectId, table.targetType, table.targetKey, table.consumerId, table.credentialSlug), index$1("credential_assignments_project_target_idx").on(table.projectId, table.targetType, table.targetKey)]);
3481
+ const credentialAssignmentsSqlite = sqliteTable("credential_assignments", {
3482
+ id: text("id").primaryKey(),
3483
+ projectId: text("project_id").notNull(),
3484
+ targetType: text("target_type").$type().notNull(),
3485
+ targetKey: text("target_key").notNull(),
3486
+ consumerId: text("consumer_id").notNull(),
3487
+ credentialSlug: text("credential_slug").notNull(),
3488
+ instanceId: text("instance_id").notNull(),
3489
+ createdAt: integer("created_at", { mode: "timestamp_ms" }).notNull(),
3490
+ updatedAt: integer("updated_at", { mode: "timestamp_ms" }).notNull()
3491
+ }, (table) => [uniqueIndex("credential_assignments_project_target_consumer_slug").on(table.projectId, table.targetType, table.targetKey, table.consumerId, table.credentialSlug), index("credential_assignments_project_target_idx").on(table.projectId, table.targetType, table.targetKey)]);
3462
3492
  const jobs = pgTable("jobs", {
3463
3493
  id: text$1("id").primaryKey(),
3464
3494
  projectId: text$1("project_id").notNull(),
@@ -3695,6 +3725,10 @@ const tableRegistry$1 = {
3695
3725
  pg: credentialInstances,
3696
3726
  sqlite: credentialInstancesSqlite
3697
3727
  },
3728
+ credentialAssignments: {
3729
+ pg: credentialAssignments,
3730
+ sqlite: credentialAssignmentsSqlite
3731
+ },
3698
3732
  jobs: {
3699
3733
  pg: jobs,
3700
3734
  sqlite: jobsSqlite
@@ -3817,13 +3851,16 @@ function credentialScopeAnd(scopeType, ...conditions) {
3817
3851
  if (scopeType === "project") return scopedAnd$1(credentialInstances, ...conditions);
3818
3852
  return and(...conditions.filter(Boolean));
3819
3853
  }
3820
- async function selectCredentialInstanceById$1(id) {
3854
+ async function selectCredentialInstanceById(id) {
3821
3855
  return (await getDb$1().select().from(credentialInstances).where(eq(credentialInstances.id, id)).limit(1))[0];
3822
3856
  }
3823
- async function selectCredentialInstancesForScope$1(slug, scopeType, scopeId) {
3857
+ async function selectCredentialInstancesForScope(appSlug, scopeType, scopeId) {
3824
3858
  const db = getDb$1();
3825
3859
  const scopeCondition = scopeId === null ? and(eq(credentialInstances.scopeType, scopeType), isNull(credentialInstances.scopeId)) : and(eq(credentialInstances.scopeType, scopeType), eq(credentialInstances.scopeId, scopeId));
3826
- return db.select().from(credentialInstances).where(credentialScopeAnd(scopeType, eq(credentialInstances.slug, slug), scopeCondition));
3860
+ return db.select().from(credentialInstances).where(credentialScopeAnd(scopeType, eq(credentialInstances.appSlug, appSlug), scopeCondition));
3861
+ }
3862
+ async function listCredentialAssignmentsByTarget(options) {
3863
+ return getDb$1().select().from(credentialAssignments).where(scopedAnd$1(credentialAssignments, eq(credentialAssignments.targetType, options.targetType), eq(credentialAssignments.targetKey, options.targetKey)));
3827
3864
  }
3828
3865
  async function selectTraceSpanById(id) {
3829
3866
  const db = getDb$1();
@@ -17218,7 +17255,7 @@ async function connectMcpServer(name, options) {
17218
17255
  }
17219
17256
  async function createTransport(url, transport, requestInit, fetchImpl) {
17220
17257
  if (transport === "sse") {
17221
- const { SSEClientTransport } = await Promise.resolve().then(() => require("./sse-Dzs73rQw.cjs"));
17258
+ const { SSEClientTransport } = await Promise.resolve().then(() => require("./sse-CZOklzgA.cjs"));
17222
17259
  return new SSEClientTransport(url, {
17223
17260
  requestInit,
17224
17261
  fetch: fetchImpl
@@ -18008,6 +18045,26 @@ async function resolveOAuthAccessToken(connection, app, tokenRefresh) {
18008
18045
  return refreshed.accessToken;
18009
18046
  }
18010
18047
  //#endregion
18048
+ //#region ../credentials/dist/store-BokhwcCi.mjs
18049
+ function normalizeRow(row) {
18050
+ const { projectId: _projectId, ...rest } = row;
18051
+ return rest;
18052
+ }
18053
+ async function listCredentialAssignmentsByTarget$1(options) {
18054
+ return (await listCredentialAssignmentsByTarget(options)).map(normalizeRow);
18055
+ }
18056
+ function normalizeLocalRow(row) {
18057
+ const { projectId: _projectId, ...rest } = row;
18058
+ return rest;
18059
+ }
18060
+ async function selectCredentialInstanceById$1(id) {
18061
+ const row = await selectCredentialInstanceById(id);
18062
+ return row ? normalizeLocalRow(row) : void 0;
18063
+ }
18064
+ async function selectCredentialInstancesForScope$1(appSlug, scopeType, scopeId) {
18065
+ return (await selectCredentialInstancesForScope(appSlug, scopeType, scopeId)).map(normalizeLocalRow);
18066
+ }
18067
+ //#endregion
18011
18068
  //#region ../secrets/dist/index.mjs
18012
18069
  const ALGORITHM = "aes-256-gcm";
18013
18070
  const IV_LENGTH = 12;
@@ -18079,19 +18136,6 @@ async function readCredentialInstanceSecret(instanceId) {
18079
18136
  });
18080
18137
  }
18081
18138
  //#endregion
18082
- //#region ../credentials/dist/store/index.mjs
18083
- function normalizeLocalRow(row) {
18084
- const { projectId: _projectId, ...rest } = row;
18085
- return rest;
18086
- }
18087
- async function selectCredentialInstanceById(id) {
18088
- const row = await selectCredentialInstanceById$1(id);
18089
- return row ? normalizeLocalRow(row) : void 0;
18090
- }
18091
- async function selectCredentialInstancesForScope(key, scopeType, scopeId) {
18092
- return (await selectCredentialInstancesForScope$1(key, scopeType, scopeId)).map(normalizeLocalRow);
18093
- }
18094
- //#endregion
18095
18139
  //#region ../credentials/dist/index.mjs
18096
18140
  var MissingCredentialsError = class extends Error {
18097
18141
  code = "missing_credentials";
@@ -18170,6 +18214,93 @@ function captureCredentialToolErrors(tools) {
18170
18214
  }
18171
18215
  };
18172
18216
  }
18217
+ const EMPTY_ASSIGNMENT_SET = {
18218
+ byConsumer: {},
18219
+ wildcard: {}
18220
+ };
18221
+ function selectAssignedInstanceId(assignments, consumerId, credentialSlug) {
18222
+ if (!assignments) return;
18223
+ if (consumerId) {
18224
+ const specific = assignments.byConsumer[consumerId]?.[credentialSlug];
18225
+ if (specific) return specific;
18226
+ }
18227
+ return assignments.wildcard[credentialSlug];
18228
+ }
18229
+ function buildAssignmentSet(rows) {
18230
+ const byConsumer = {};
18231
+ const wildcard = {};
18232
+ for (const row of rows) {
18233
+ if (row.consumerId === "*") {
18234
+ wildcard[row.credentialSlug] = row.instanceId;
18235
+ continue;
18236
+ }
18237
+ const bucket = byConsumer[row.consumerId] ?? {};
18238
+ bucket[row.credentialSlug] = row.instanceId;
18239
+ byConsumer[row.consumerId] = bucket;
18240
+ }
18241
+ return {
18242
+ byConsumer,
18243
+ wildcard
18244
+ };
18245
+ }
18246
+ async function loadCredentialAssignments(options) {
18247
+ if (!isDatabaseInitialized()) return EMPTY_ASSIGNMENT_SET;
18248
+ return buildAssignmentSet(await listCredentialAssignmentsByTarget$1(options));
18249
+ }
18250
+ async function withCredentialAssignments(context, options) {
18251
+ const assignments = await loadCredentialAssignments(options);
18252
+ return {
18253
+ ...context,
18254
+ assignments
18255
+ };
18256
+ }
18257
+ function pickKeystrokeInstanceRow(rows, key, consumer) {
18258
+ if (rows.length === 0) return;
18259
+ if (rows.length === 1) return rows[0];
18260
+ const defaults = rows.filter((row) => row.isDefault);
18261
+ if (defaults.length === 1) return defaults[0];
18262
+ if (consumer !== void 0) throw new NeedsSelectionError({
18263
+ key,
18264
+ options: rows.map((row) => ({
18265
+ id: row.id,
18266
+ label: row.name ?? row.label,
18267
+ scopeType: row.scopeType,
18268
+ scopeId: row.scopeId
18269
+ })),
18270
+ consumer
18271
+ });
18272
+ return rows.find((row) => row.isDefault) ?? rows[0];
18273
+ }
18274
+ async function resolveAssignedKeystrokeInstance(app, assignments, consumerId) {
18275
+ const assignedId = selectAssignedInstanceId(assignments, consumerId, app);
18276
+ if (!assignedId) return;
18277
+ const row = await selectCredentialInstanceById$1(assignedId);
18278
+ if (!row || row.authKind !== "keystroke" || !row.connectionId || row.appSlug !== app) return;
18279
+ return {
18280
+ instanceId: assignedId,
18281
+ scopeType: row.scopeType,
18282
+ scopeId: row.scopeId
18283
+ };
18284
+ }
18285
+ /** Assignment lookup (when assignments provided) then ordered scope walk. User scope only when included in scopes. */
18286
+ async function resolveKeystrokeInstanceId(options) {
18287
+ const assignments = options.assignments ?? (options.assignmentTarget ? await loadCredentialAssignments({
18288
+ targetType: options.assignmentTarget.type,
18289
+ targetKey: options.assignmentTarget.key
18290
+ }) : void 0);
18291
+ if (assignments) {
18292
+ const assigned = await resolveAssignedKeystrokeInstance(options.app, assignments, options.consumerId);
18293
+ if (assigned) return assigned;
18294
+ }
18295
+ for (const [scopeType, scopeId] of options.scopes) {
18296
+ const row = pickKeystrokeInstanceRow((await selectCredentialInstancesForScope$1(options.app, scopeType, scopeId)).filter((row) => row.authKind === "keystroke" && row.connectionId), options.app, options.consumer);
18297
+ if (row) return {
18298
+ instanceId: row.id,
18299
+ scopeType: row.scopeType,
18300
+ scopeId: row.scopeId
18301
+ };
18302
+ }
18303
+ }
18173
18304
  function buildCredentialRunContext(input) {
18174
18305
  const subscription = input.subscription;
18175
18306
  const request = input.request ?? {};
@@ -18187,7 +18318,7 @@ function createLocalCredentialBackend(options = {}) {
18187
18318
  const { tokenRefresh } = options;
18188
18319
  return {
18189
18320
  async resolveApiKey(instanceId, schema) {
18190
- const row = await selectCredentialInstanceById$1(instanceId);
18321
+ const row = await selectCredentialInstanceById(instanceId);
18191
18322
  if (!row) throw new MissingCredentialsError({
18192
18323
  key: instanceId,
18193
18324
  chainAttempted: ["api_key"]
@@ -18199,7 +18330,7 @@ function createLocalCredentialBackend(options = {}) {
18199
18330
  const secret = await readCredentialInstanceSecret(instanceId);
18200
18331
  if (secret) return schema.parse(JSON.parse(secret));
18201
18332
  throw new MissingCredentialsError({
18202
- key: row.slug,
18333
+ key: row.appSlug,
18203
18334
  chainAttempted: ["api_key"]
18204
18335
  });
18205
18336
  },
@@ -18279,7 +18410,7 @@ function createCredentialBackend(options = {}) {
18279
18410
  function toSelectionOption(row) {
18280
18411
  return {
18281
18412
  id: row.id,
18282
- label: row.label,
18413
+ label: row.name ?? row.label,
18283
18414
  scopeType: row.scopeType,
18284
18415
  scopeId: row.scopeId
18285
18416
  };
@@ -18305,12 +18436,12 @@ function pickInstance(rows, key, consumer) {
18305
18436
  async function resolveInstanceValue(row, requirement, backend) {
18306
18437
  if (row.authKind === "keystroke") {
18307
18438
  if (!row.connectionId) throw new MissingCredentialsError({
18308
- key: row.slug,
18439
+ key: row.appSlug,
18309
18440
  chainAttempted: ["keystroke"]
18310
18441
  });
18311
18442
  const scopeId = row.scopeType === "organization" ? getServerTenantScopeId() : row.scopeId ?? "";
18312
18443
  if (!scopeId) throw new MissingCredentialsError({
18313
- key: row.slug,
18444
+ key: row.appSlug,
18314
18445
  chainAttempted: ["keystroke"]
18315
18446
  });
18316
18447
  const value = {
@@ -18322,7 +18453,7 @@ async function resolveInstanceValue(row, requirement, backend) {
18322
18453
  }
18323
18454
  if (row.authKind === "oauth_managed") {
18324
18455
  if (!row.connectionId) throw new MissingCredentialsError({
18325
- key: row.slug,
18456
+ key: row.appSlug,
18326
18457
  chainAttempted: ["oauth_managed"]
18327
18458
  });
18328
18459
  const token = await backend.getOAuthAccessToken(row.connectionId);
@@ -18333,8 +18464,8 @@ async function resolveInstanceValue(row, requirement, backend) {
18333
18464
  return backend.resolveApiKey(row.id, requirement.schema);
18334
18465
  }
18335
18466
  async function resolveSelectedInstance(key, instanceId, context, consumer) {
18336
- const row = await selectCredentialInstanceById(instanceId);
18337
- if (!row || row.slug !== key) throw new MissingCredentialsError({
18467
+ const row = await selectCredentialInstanceById$1(instanceId);
18468
+ if (!row || row.appSlug !== key) throw new MissingCredentialsError({
18338
18469
  key,
18339
18470
  chainAttempted: ["selection"],
18340
18471
  consumer
@@ -18356,26 +18487,58 @@ function scopeIdForScope(scope, key, context) {
18356
18487
  }
18357
18488
  }
18358
18489
  async function resolveAtScope(key, scopeType, scopeId, consumer) {
18359
- const rows = await selectCredentialInstancesForScope(key, scopeType, scopeId);
18490
+ const rows = await selectCredentialInstancesForScope$1(key, scopeType, scopeId);
18360
18491
  if (rows.length === 0) return;
18361
- try {
18362
- return pickInstance(rows, key, consumer);
18363
- } catch (error) {
18364
- if (error instanceof NeedsSelectionError) throw error;
18365
- throw error;
18492
+ return pickInstance(rows, key, consumer);
18493
+ }
18494
+ async function resolveBoundInstance(instanceId, requirement, context, consumer, backend) {
18495
+ const row = await selectCredentialInstanceById$1(instanceId);
18496
+ if (!row || row.appSlug !== requirement.key) throw new MissingCredentialsError({
18497
+ key: requirement.key,
18498
+ chainAttempted: ["binding"],
18499
+ consumer
18500
+ });
18501
+ if (!bindingTenantReachable(row, context)) throw new CredentialAccessDeniedError(instanceId);
18502
+ return resolveInstanceValue(row, requirement, backend ?? createCredentialBackend());
18503
+ }
18504
+ function bindingTenantReachable(row, context) {
18505
+ switch (row.scopeType) {
18506
+ case "organization": return row.scopeId === context.orgId;
18507
+ case "project": return row.scopeId === context.projectId;
18508
+ case "user": return Boolean(row.scopeId);
18509
+ default: return false;
18366
18510
  }
18367
18511
  }
18368
18512
  /**
18369
18513
  * Resolution order:
18370
- * 1. A platform-provided binding (explicit instance id in `context.selection`) wins.
18371
- * 2. A scope pinned on the requirement (`.scope("user")`) resolves only at that scope.
18372
- * 3. Otherwise the project default, then the org default. No configurable chain.
18373
- * If nothing matches, throw there is no binding.
18514
+ * 1. Platform assignment (consumer-specific, then wildcard).
18515
+ * 2. Client selection in `context.selection`.
18516
+ * 3. Scope pinned on the requirement (`.scope("user")`).
18517
+ * 4. Project default, then org default.
18374
18518
  */
18375
18519
  async function resolvePolicy(requirement, context, consumer, backend) {
18376
18520
  const attempted = [];
18377
18521
  const materialBackend = backend ?? createCredentialBackend();
18378
18522
  const scoped = withTenantScope(context);
18523
+ const boundId = requirement.kind !== "keystroke" ? selectAssignedInstanceId(scoped.assignments, consumer?.id, requirement.key) : void 0;
18524
+ if (boundId) return resolveBoundInstance(boundId, requirement, scoped, consumer, materialBackend);
18525
+ if (requirement.kind === "keystroke") {
18526
+ const bound = await resolveKeystrokeInstanceId({
18527
+ app: requirement.key,
18528
+ scopes: [],
18529
+ assignments: scoped.assignments,
18530
+ consumerId: consumer?.id
18531
+ });
18532
+ if (bound) {
18533
+ const row = await selectCredentialInstanceById$1(bound.instanceId);
18534
+ if (!row) throw new MissingCredentialsError({
18535
+ key: requirement.key,
18536
+ chainAttempted: ["binding"],
18537
+ consumer
18538
+ });
18539
+ return resolveInstanceValue(row, requirement, materialBackend);
18540
+ }
18541
+ }
18379
18542
  const selectionId = context.selection?.[requirement.key];
18380
18543
  if (selectionId) return resolveInstanceValue(await resolveSelectedInstance(requirement.key, selectionId, scoped, consumer), requirement, materialBackend);
18381
18544
  if (requirement.scope) {
@@ -18391,6 +18554,32 @@ async function resolvePolicy(requirement, context, consumer, backend) {
18391
18554
  consumer
18392
18555
  });
18393
18556
  }
18557
+ if (requirement.kind === "keystroke") {
18558
+ const scopes = [];
18559
+ if (scoped.projectId) {
18560
+ attempted.push("project");
18561
+ scopes.push(["project", scoped.projectId]);
18562
+ }
18563
+ if (scoped.orgId) {
18564
+ attempted.push("organization");
18565
+ scopes.push(["organization", scoped.orgId]);
18566
+ }
18567
+ const resolved = await resolveKeystrokeInstanceId({
18568
+ app: requirement.key,
18569
+ scopes,
18570
+ consumerId: consumer?.id,
18571
+ consumer
18572
+ });
18573
+ if (resolved) {
18574
+ const row = await selectCredentialInstanceById$1(resolved.instanceId);
18575
+ if (row) return resolveInstanceValue(row, requirement, materialBackend);
18576
+ }
18577
+ throw new MissingCredentialsError({
18578
+ key: requirement.key,
18579
+ chainAttempted: attempted,
18580
+ consumer
18581
+ });
18582
+ }
18394
18583
  if (scoped.projectId) {
18395
18584
  attempted.push("project");
18396
18585
  const row = await resolveAtScope(requirement.key, "project", scoped.projectId, consumer);
@@ -18737,6 +18926,12 @@ Object.defineProperty(exports, "touchSession", {
18737
18926
  return touchSession;
18738
18927
  }
18739
18928
  });
18929
+ Object.defineProperty(exports, "withCredentialAssignments", {
18930
+ enumerable: true,
18931
+ get: function() {
18932
+ return withCredentialAssignments;
18933
+ }
18934
+ });
18740
18935
  Object.defineProperty(exports, "withSpan", {
18741
18936
  enumerable: true,
18742
18937
  get: function() {
@@ -18750,4 +18945,4 @@ Object.defineProperty(exports, "zodToJsonSchema", {
18750
18945
  }
18751
18946
  });
18752
18947
 
18753
- //# sourceMappingURL=dist-C5otI4u3.cjs.map
18948
+ //# sourceMappingURL=dist-DivFQzKG.cjs.map