@keystrokehq/keystroke 1.0.7 → 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 (93) 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 +8 -7
  68. package/dist/trigger.cjs.map +1 -1
  69. package/dist/trigger.d.cts +3 -3
  70. package/dist/trigger.d.mts +3 -3
  71. package/dist/trigger.mjs +8 -7
  72. package/dist/trigger.mjs.map +1 -1
  73. package/dist/workflow.cjs +1 -1
  74. package/dist/workflow.d.cts +2 -2
  75. package/dist/workflow.d.mts +2 -2
  76. package/dist/workflow.mjs +1 -1
  77. package/package.json +1 -1
  78. package/dist/dist-BpkCqbil.mjs.map +0 -1
  79. package/dist/dist-C5otI4u3.cjs.map +0 -1
  80. package/dist/dist-DOMwPx7V.cjs.map +0 -1
  81. package/dist/dist-DQL6zTI5.cjs.map +0 -1
  82. package/dist/dist-DqFdFpiB.mjs.map +0 -1
  83. package/dist/dist-IUl7Bexl.mjs.map +0 -1
  84. package/dist/index-8_UEbXaF.d.mts.map +0 -1
  85. package/dist/index-BMqj40Li.d.cts.map +0 -1
  86. package/dist/index-BY9SPR2h.d.cts.map +0 -1
  87. package/dist/index-BeBgntxT.d.mts.map +0 -1
  88. package/dist/index-Bl4VEelg.d.mts.map +0 -1
  89. package/dist/index-CWZAGTad.d.mts.map +0 -1
  90. package/dist/index-Dgy9MjuX.d.cts.map +0 -1
  91. package/dist/index-e9f4pcX4.d.cts.map +0 -1
  92. package/dist/index-e9f4pcX4.d.mts.map +0 -1
  93. package/dist/index-nUAXCgEe.d.cts.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { a as __toESM, i as __require, t as __commonJSMin } from "./chunk-D0VCBZRD.mjs";
2
- import { C as mcpEntityId, w as normalizeCredentialList } from "./dist-DqFdFpiB.mjs";
2
+ import { E as normalizeCredentialList, T as mcpEntityId } from "./dist-CppO7361.mjs";
3
3
  import { AsyncLocalStorage } from "node:async_hooks";
4
4
  import "node:fs";
5
5
  import "node:path";
@@ -3115,6 +3115,9 @@ const requestHandle = new AsyncLocalStorage();
3115
3115
  function getRequestDatabaseHandle() {
3116
3116
  return requestHandle.getStore();
3117
3117
  }
3118
+ function isDatabaseInitialized() {
3119
+ return getRequestDatabaseHandle() !== void 0 || false;
3120
+ }
3118
3121
  function getDatabaseHandle$1() {
3119
3122
  const scoped = getRequestDatabaseHandle();
3120
3123
  if (scoped) return scoped;
@@ -3141,7 +3144,7 @@ const agents = pgTable("agents", {
3141
3144
  systemPrompt: text$1("system_prompt").notNull(),
3142
3145
  toolCount: integer$1("tool_count"),
3143
3146
  credentialCount: integer$1("credential_count"),
3144
- credentialKeys: jsonb("credential_keys").$type(),
3147
+ appSlugs: jsonb("app_slugs").$type(),
3145
3148
  registeredAt: timestamp("registered_at", { withTimezone: true }).notNull(),
3146
3149
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull(),
3147
3150
  deletedAt: timestamp("deleted_at", { withTimezone: true })
@@ -3158,7 +3161,7 @@ const agentsSqlite = sqliteTable("agents", {
3158
3161
  systemPrompt: text("system_prompt").notNull(),
3159
3162
  toolCount: integer("tool_count"),
3160
3163
  credentialCount: integer("credential_count"),
3161
- credentialKeys: text("credential_keys", { mode: "json" }).$type(),
3164
+ appSlugs: text("app_slugs", { mode: "json" }).$type(),
3162
3165
  registeredAt: integer("registered_at", { mode: "timestamp_ms" }).notNull(),
3163
3166
  updatedAt: integer("updated_at", { mode: "timestamp_ms" }).notNull(),
3164
3167
  deletedAt: integer("deleted_at", { mode: "timestamp_ms" })
@@ -3426,7 +3429,9 @@ const workflowHooksSqlite = sqliteTable("workflow_hooks", {
3426
3429
  const credentialInstances = pgTable("credential_instances", {
3427
3430
  id: text$1("id").primaryKey(),
3428
3431
  projectId: text$1("project_id").notNull(),
3432
+ appSlug: text$1("app_slug").notNull(),
3429
3433
  slug: text$1("slug").notNull(),
3434
+ name: text$1("name"),
3430
3435
  scopeType: text$1("scope_type").$type().notNull(),
3431
3436
  scopeId: text$1("scope_id"),
3432
3437
  label: text$1("label"),
@@ -3438,11 +3443,13 @@ const credentialInstances = pgTable("credential_instances", {
3438
3443
  sharedConnectionId: text$1("shared_connection_id"),
3439
3444
  createdAt: timestamp("created_at", { withTimezone: true }).notNull(),
3440
3445
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull()
3441
- }, (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)]);
3446
+ }, (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)]);
3442
3447
  const credentialInstancesSqlite = sqliteTable("credential_instances", {
3443
3448
  id: text("id").primaryKey(),
3444
3449
  projectId: text("project_id").notNull(),
3450
+ appSlug: text("app_slug").notNull(),
3445
3451
  slug: text("slug").notNull(),
3452
+ name: text("name"),
3446
3453
  scopeType: text("scope_type").$type().notNull(),
3447
3454
  scopeId: text("scope_id"),
3448
3455
  label: text("label"),
@@ -3454,7 +3461,30 @@ const credentialInstancesSqlite = sqliteTable("credential_instances", {
3454
3461
  sharedConnectionId: text("shared_connection_id"),
3455
3462
  createdAt: integer("created_at", { mode: "timestamp_ms" }).notNull(),
3456
3463
  updatedAt: integer("updated_at", { mode: "timestamp_ms" }).notNull()
3457
- }, (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)]);
3464
+ }, (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)]);
3465
+ const credentialAssignments = pgTable("credential_assignments", {
3466
+ id: text$1("id").primaryKey(),
3467
+ projectId: text$1("project_id").notNull(),
3468
+ targetType: text$1("target_type").$type().notNull(),
3469
+ targetKey: text$1("target_key").notNull(),
3470
+ /** '*' = wildcard; else runtime consumer id (step correlation id or tool slug). */
3471
+ consumerId: text$1("consumer_id").notNull(),
3472
+ credentialSlug: text$1("credential_slug").notNull(),
3473
+ instanceId: text$1("instance_id").notNull(),
3474
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull(),
3475
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull()
3476
+ }, (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)]);
3477
+ const credentialAssignmentsSqlite = sqliteTable("credential_assignments", {
3478
+ id: text("id").primaryKey(),
3479
+ projectId: text("project_id").notNull(),
3480
+ targetType: text("target_type").$type().notNull(),
3481
+ targetKey: text("target_key").notNull(),
3482
+ consumerId: text("consumer_id").notNull(),
3483
+ credentialSlug: text("credential_slug").notNull(),
3484
+ instanceId: text("instance_id").notNull(),
3485
+ createdAt: integer("created_at", { mode: "timestamp_ms" }).notNull(),
3486
+ updatedAt: integer("updated_at", { mode: "timestamp_ms" }).notNull()
3487
+ }, (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)]);
3458
3488
  const jobs = pgTable("jobs", {
3459
3489
  id: text$1("id").primaryKey(),
3460
3490
  projectId: text$1("project_id").notNull(),
@@ -3691,6 +3721,10 @@ const tableRegistry$1 = {
3691
3721
  pg: credentialInstances,
3692
3722
  sqlite: credentialInstancesSqlite
3693
3723
  },
3724
+ credentialAssignments: {
3725
+ pg: credentialAssignments,
3726
+ sqlite: credentialAssignmentsSqlite
3727
+ },
3694
3728
  jobs: {
3695
3729
  pg: jobs,
3696
3730
  sqlite: jobsSqlite
@@ -3813,13 +3847,16 @@ function credentialScopeAnd(scopeType, ...conditions) {
3813
3847
  if (scopeType === "project") return scopedAnd$1(credentialInstances, ...conditions);
3814
3848
  return and(...conditions.filter(Boolean));
3815
3849
  }
3816
- async function selectCredentialInstanceById$1(id) {
3850
+ async function selectCredentialInstanceById(id) {
3817
3851
  return (await getDb$1().select().from(credentialInstances).where(eq(credentialInstances.id, id)).limit(1))[0];
3818
3852
  }
3819
- async function selectCredentialInstancesForScope$1(slug, scopeType, scopeId) {
3853
+ async function selectCredentialInstancesForScope(appSlug, scopeType, scopeId) {
3820
3854
  const db = getDb$1();
3821
3855
  const scopeCondition = scopeId === null ? and(eq(credentialInstances.scopeType, scopeType), isNull(credentialInstances.scopeId)) : and(eq(credentialInstances.scopeType, scopeType), eq(credentialInstances.scopeId, scopeId));
3822
- return db.select().from(credentialInstances).where(credentialScopeAnd(scopeType, eq(credentialInstances.slug, slug), scopeCondition));
3856
+ return db.select().from(credentialInstances).where(credentialScopeAnd(scopeType, eq(credentialInstances.appSlug, appSlug), scopeCondition));
3857
+ }
3858
+ async function listCredentialAssignmentsByTarget(options) {
3859
+ return getDb$1().select().from(credentialAssignments).where(scopedAnd$1(credentialAssignments, eq(credentialAssignments.targetType, options.targetType), eq(credentialAssignments.targetKey, options.targetKey)));
3823
3860
  }
3824
3861
  async function selectTraceSpanById(id) {
3825
3862
  const db = getDb$1();
@@ -17211,7 +17248,7 @@ async function connectMcpServer(name, options) {
17211
17248
  }
17212
17249
  async function createTransport(url, transport, requestInit, fetchImpl) {
17213
17250
  if (transport === "sse") {
17214
- const { SSEClientTransport } = await import("./sse-DI7TsPKG.mjs");
17251
+ const { SSEClientTransport } = await import("./sse-CDOw-yuH.mjs");
17215
17252
  return new SSEClientTransport(url, {
17216
17253
  requestInit,
17217
17254
  fetch: fetchImpl
@@ -18001,6 +18038,26 @@ async function resolveOAuthAccessToken(connection, app, tokenRefresh) {
18001
18038
  return refreshed.accessToken;
18002
18039
  }
18003
18040
  //#endregion
18041
+ //#region ../credentials/dist/store-BokhwcCi.mjs
18042
+ function normalizeRow(row) {
18043
+ const { projectId: _projectId, ...rest } = row;
18044
+ return rest;
18045
+ }
18046
+ async function listCredentialAssignmentsByTarget$1(options) {
18047
+ return (await listCredentialAssignmentsByTarget(options)).map(normalizeRow);
18048
+ }
18049
+ function normalizeLocalRow(row) {
18050
+ const { projectId: _projectId, ...rest } = row;
18051
+ return rest;
18052
+ }
18053
+ async function selectCredentialInstanceById$1(id) {
18054
+ const row = await selectCredentialInstanceById(id);
18055
+ return row ? normalizeLocalRow(row) : void 0;
18056
+ }
18057
+ async function selectCredentialInstancesForScope$1(appSlug, scopeType, scopeId) {
18058
+ return (await selectCredentialInstancesForScope(appSlug, scopeType, scopeId)).map(normalizeLocalRow);
18059
+ }
18060
+ //#endregion
18004
18061
  //#region ../secrets/dist/index.mjs
18005
18062
  const ALGORITHM = "aes-256-gcm";
18006
18063
  const IV_LENGTH = 12;
@@ -18072,19 +18129,6 @@ async function readCredentialInstanceSecret(instanceId) {
18072
18129
  });
18073
18130
  }
18074
18131
  //#endregion
18075
- //#region ../credentials/dist/store/index.mjs
18076
- function normalizeLocalRow(row) {
18077
- const { projectId: _projectId, ...rest } = row;
18078
- return rest;
18079
- }
18080
- async function selectCredentialInstanceById(id) {
18081
- const row = await selectCredentialInstanceById$1(id);
18082
- return row ? normalizeLocalRow(row) : void 0;
18083
- }
18084
- async function selectCredentialInstancesForScope(key, scopeType, scopeId) {
18085
- return (await selectCredentialInstancesForScope$1(key, scopeType, scopeId)).map(normalizeLocalRow);
18086
- }
18087
- //#endregion
18088
18132
  //#region ../credentials/dist/index.mjs
18089
18133
  var MissingCredentialsError = class extends Error {
18090
18134
  code = "missing_credentials";
@@ -18163,6 +18207,93 @@ function captureCredentialToolErrors(tools) {
18163
18207
  }
18164
18208
  };
18165
18209
  }
18210
+ const EMPTY_ASSIGNMENT_SET = {
18211
+ byConsumer: {},
18212
+ wildcard: {}
18213
+ };
18214
+ function selectAssignedInstanceId(assignments, consumerId, credentialSlug) {
18215
+ if (!assignments) return;
18216
+ if (consumerId) {
18217
+ const specific = assignments.byConsumer[consumerId]?.[credentialSlug];
18218
+ if (specific) return specific;
18219
+ }
18220
+ return assignments.wildcard[credentialSlug];
18221
+ }
18222
+ function buildAssignmentSet(rows) {
18223
+ const byConsumer = {};
18224
+ const wildcard = {};
18225
+ for (const row of rows) {
18226
+ if (row.consumerId === "*") {
18227
+ wildcard[row.credentialSlug] = row.instanceId;
18228
+ continue;
18229
+ }
18230
+ const bucket = byConsumer[row.consumerId] ?? {};
18231
+ bucket[row.credentialSlug] = row.instanceId;
18232
+ byConsumer[row.consumerId] = bucket;
18233
+ }
18234
+ return {
18235
+ byConsumer,
18236
+ wildcard
18237
+ };
18238
+ }
18239
+ async function loadCredentialAssignments(options) {
18240
+ if (!isDatabaseInitialized()) return EMPTY_ASSIGNMENT_SET;
18241
+ return buildAssignmentSet(await listCredentialAssignmentsByTarget$1(options));
18242
+ }
18243
+ async function withCredentialAssignments(context, options) {
18244
+ const assignments = await loadCredentialAssignments(options);
18245
+ return {
18246
+ ...context,
18247
+ assignments
18248
+ };
18249
+ }
18250
+ function pickKeystrokeInstanceRow(rows, key, consumer) {
18251
+ if (rows.length === 0) return;
18252
+ if (rows.length === 1) return rows[0];
18253
+ const defaults = rows.filter((row) => row.isDefault);
18254
+ if (defaults.length === 1) return defaults[0];
18255
+ if (consumer !== void 0) throw new NeedsSelectionError({
18256
+ key,
18257
+ options: rows.map((row) => ({
18258
+ id: row.id,
18259
+ label: row.name ?? row.label,
18260
+ scopeType: row.scopeType,
18261
+ scopeId: row.scopeId
18262
+ })),
18263
+ consumer
18264
+ });
18265
+ return rows.find((row) => row.isDefault) ?? rows[0];
18266
+ }
18267
+ async function resolveAssignedKeystrokeInstance(app, assignments, consumerId) {
18268
+ const assignedId = selectAssignedInstanceId(assignments, consumerId, app);
18269
+ if (!assignedId) return;
18270
+ const row = await selectCredentialInstanceById$1(assignedId);
18271
+ if (!row || row.authKind !== "keystroke" || !row.connectionId || row.appSlug !== app) return;
18272
+ return {
18273
+ instanceId: assignedId,
18274
+ scopeType: row.scopeType,
18275
+ scopeId: row.scopeId
18276
+ };
18277
+ }
18278
+ /** Assignment lookup (when assignments provided) then ordered scope walk. User scope only when included in scopes. */
18279
+ async function resolveKeystrokeInstanceId(options) {
18280
+ const assignments = options.assignments ?? (options.assignmentTarget ? await loadCredentialAssignments({
18281
+ targetType: options.assignmentTarget.type,
18282
+ targetKey: options.assignmentTarget.key
18283
+ }) : void 0);
18284
+ if (assignments) {
18285
+ const assigned = await resolveAssignedKeystrokeInstance(options.app, assignments, options.consumerId);
18286
+ if (assigned) return assigned;
18287
+ }
18288
+ for (const [scopeType, scopeId] of options.scopes) {
18289
+ const row = pickKeystrokeInstanceRow((await selectCredentialInstancesForScope$1(options.app, scopeType, scopeId)).filter((row) => row.authKind === "keystroke" && row.connectionId), options.app, options.consumer);
18290
+ if (row) return {
18291
+ instanceId: row.id,
18292
+ scopeType: row.scopeType,
18293
+ scopeId: row.scopeId
18294
+ };
18295
+ }
18296
+ }
18166
18297
  function buildCredentialRunContext(input) {
18167
18298
  const subscription = input.subscription;
18168
18299
  const request = input.request ?? {};
@@ -18180,7 +18311,7 @@ function createLocalCredentialBackend(options = {}) {
18180
18311
  const { tokenRefresh } = options;
18181
18312
  return {
18182
18313
  async resolveApiKey(instanceId, schema) {
18183
- const row = await selectCredentialInstanceById$1(instanceId);
18314
+ const row = await selectCredentialInstanceById(instanceId);
18184
18315
  if (!row) throw new MissingCredentialsError({
18185
18316
  key: instanceId,
18186
18317
  chainAttempted: ["api_key"]
@@ -18192,7 +18323,7 @@ function createLocalCredentialBackend(options = {}) {
18192
18323
  const secret = await readCredentialInstanceSecret(instanceId);
18193
18324
  if (secret) return schema.parse(JSON.parse(secret));
18194
18325
  throw new MissingCredentialsError({
18195
- key: row.slug,
18326
+ key: row.appSlug,
18196
18327
  chainAttempted: ["api_key"]
18197
18328
  });
18198
18329
  },
@@ -18272,7 +18403,7 @@ function createCredentialBackend(options = {}) {
18272
18403
  function toSelectionOption(row) {
18273
18404
  return {
18274
18405
  id: row.id,
18275
- label: row.label,
18406
+ label: row.name ?? row.label,
18276
18407
  scopeType: row.scopeType,
18277
18408
  scopeId: row.scopeId
18278
18409
  };
@@ -18298,12 +18429,12 @@ function pickInstance(rows, key, consumer) {
18298
18429
  async function resolveInstanceValue(row, requirement, backend) {
18299
18430
  if (row.authKind === "keystroke") {
18300
18431
  if (!row.connectionId) throw new MissingCredentialsError({
18301
- key: row.slug,
18432
+ key: row.appSlug,
18302
18433
  chainAttempted: ["keystroke"]
18303
18434
  });
18304
18435
  const scopeId = row.scopeType === "organization" ? getServerTenantScopeId() : row.scopeId ?? "";
18305
18436
  if (!scopeId) throw new MissingCredentialsError({
18306
- key: row.slug,
18437
+ key: row.appSlug,
18307
18438
  chainAttempted: ["keystroke"]
18308
18439
  });
18309
18440
  const value = {
@@ -18315,7 +18446,7 @@ async function resolveInstanceValue(row, requirement, backend) {
18315
18446
  }
18316
18447
  if (row.authKind === "oauth_managed") {
18317
18448
  if (!row.connectionId) throw new MissingCredentialsError({
18318
- key: row.slug,
18449
+ key: row.appSlug,
18319
18450
  chainAttempted: ["oauth_managed"]
18320
18451
  });
18321
18452
  const token = await backend.getOAuthAccessToken(row.connectionId);
@@ -18326,8 +18457,8 @@ async function resolveInstanceValue(row, requirement, backend) {
18326
18457
  return backend.resolveApiKey(row.id, requirement.schema);
18327
18458
  }
18328
18459
  async function resolveSelectedInstance(key, instanceId, context, consumer) {
18329
- const row = await selectCredentialInstanceById(instanceId);
18330
- if (!row || row.slug !== key) throw new MissingCredentialsError({
18460
+ const row = await selectCredentialInstanceById$1(instanceId);
18461
+ if (!row || row.appSlug !== key) throw new MissingCredentialsError({
18331
18462
  key,
18332
18463
  chainAttempted: ["selection"],
18333
18464
  consumer
@@ -18349,26 +18480,58 @@ function scopeIdForScope(scope, key, context) {
18349
18480
  }
18350
18481
  }
18351
18482
  async function resolveAtScope(key, scopeType, scopeId, consumer) {
18352
- const rows = await selectCredentialInstancesForScope(key, scopeType, scopeId);
18483
+ const rows = await selectCredentialInstancesForScope$1(key, scopeType, scopeId);
18353
18484
  if (rows.length === 0) return;
18354
- try {
18355
- return pickInstance(rows, key, consumer);
18356
- } catch (error) {
18357
- if (error instanceof NeedsSelectionError) throw error;
18358
- throw error;
18485
+ return pickInstance(rows, key, consumer);
18486
+ }
18487
+ async function resolveBoundInstance(instanceId, requirement, context, consumer, backend) {
18488
+ const row = await selectCredentialInstanceById$1(instanceId);
18489
+ if (!row || row.appSlug !== requirement.key) throw new MissingCredentialsError({
18490
+ key: requirement.key,
18491
+ chainAttempted: ["binding"],
18492
+ consumer
18493
+ });
18494
+ if (!bindingTenantReachable(row, context)) throw new CredentialAccessDeniedError(instanceId);
18495
+ return resolveInstanceValue(row, requirement, backend ?? createCredentialBackend());
18496
+ }
18497
+ function bindingTenantReachable(row, context) {
18498
+ switch (row.scopeType) {
18499
+ case "organization": return row.scopeId === context.orgId;
18500
+ case "project": return row.scopeId === context.projectId;
18501
+ case "user": return Boolean(row.scopeId);
18502
+ default: return false;
18359
18503
  }
18360
18504
  }
18361
18505
  /**
18362
18506
  * Resolution order:
18363
- * 1. A platform-provided binding (explicit instance id in `context.selection`) wins.
18364
- * 2. A scope pinned on the requirement (`.scope("user")`) resolves only at that scope.
18365
- * 3. Otherwise the project default, then the org default. No configurable chain.
18366
- * If nothing matches, throw there is no binding.
18507
+ * 1. Platform assignment (consumer-specific, then wildcard).
18508
+ * 2. Client selection in `context.selection`.
18509
+ * 3. Scope pinned on the requirement (`.scope("user")`).
18510
+ * 4. Project default, then org default.
18367
18511
  */
18368
18512
  async function resolvePolicy(requirement, context, consumer, backend) {
18369
18513
  const attempted = [];
18370
18514
  const materialBackend = backend ?? createCredentialBackend();
18371
18515
  const scoped = withTenantScope(context);
18516
+ const boundId = requirement.kind !== "keystroke" ? selectAssignedInstanceId(scoped.assignments, consumer?.id, requirement.key) : void 0;
18517
+ if (boundId) return resolveBoundInstance(boundId, requirement, scoped, consumer, materialBackend);
18518
+ if (requirement.kind === "keystroke") {
18519
+ const bound = await resolveKeystrokeInstanceId({
18520
+ app: requirement.key,
18521
+ scopes: [],
18522
+ assignments: scoped.assignments,
18523
+ consumerId: consumer?.id
18524
+ });
18525
+ if (bound) {
18526
+ const row = await selectCredentialInstanceById$1(bound.instanceId);
18527
+ if (!row) throw new MissingCredentialsError({
18528
+ key: requirement.key,
18529
+ chainAttempted: ["binding"],
18530
+ consumer
18531
+ });
18532
+ return resolveInstanceValue(row, requirement, materialBackend);
18533
+ }
18534
+ }
18372
18535
  const selectionId = context.selection?.[requirement.key];
18373
18536
  if (selectionId) return resolveInstanceValue(await resolveSelectedInstance(requirement.key, selectionId, scoped, consumer), requirement, materialBackend);
18374
18537
  if (requirement.scope) {
@@ -18384,6 +18547,32 @@ async function resolvePolicy(requirement, context, consumer, backend) {
18384
18547
  consumer
18385
18548
  });
18386
18549
  }
18550
+ if (requirement.kind === "keystroke") {
18551
+ const scopes = [];
18552
+ if (scoped.projectId) {
18553
+ attempted.push("project");
18554
+ scopes.push(["project", scoped.projectId]);
18555
+ }
18556
+ if (scoped.orgId) {
18557
+ attempted.push("organization");
18558
+ scopes.push(["organization", scoped.orgId]);
18559
+ }
18560
+ const resolved = await resolveKeystrokeInstanceId({
18561
+ app: requirement.key,
18562
+ scopes,
18563
+ consumerId: consumer?.id,
18564
+ consumer
18565
+ });
18566
+ if (resolved) {
18567
+ const row = await selectCredentialInstanceById$1(resolved.instanceId);
18568
+ if (row) return resolveInstanceValue(row, requirement, materialBackend);
18569
+ }
18570
+ throw new MissingCredentialsError({
18571
+ key: requirement.key,
18572
+ chainAttempted: attempted,
18573
+ consumer
18574
+ });
18575
+ }
18387
18576
  if (scoped.projectId) {
18388
18577
  attempted.push("project");
18389
18578
  const row = await resolveAtScope(requirement.key, "project", scoped.projectId, consumer);
@@ -18520,6 +18709,6 @@ async function resolveActionCredentials(requirements, options) {
18520
18709
  return parseResolvedCredentials(requirements, await resolveCredentials(requirements, options.consumer, options.contextOverride));
18521
18710
  }
18522
18711
  //#endregion
18523
- export { resolveRunSourceFromTraceContext as A, clearLiveMessage as C, getSession as D, getProjectScopeId as E, getTraceContext as F, logSystem as I, withSpan as L, setSessionTitle as M, touchSession as N, listMessageEvents as O, captureConsole as P, appendEvent as S, getAgentByRoute as T, normalizeHeaders as _, resolveActionCredentials as a, MESSAGE_EVENT_TYPE as b, connectMcpServer as c, isMcp as d, createParser as f, createFetchWithInit as g, extractWWWAuthenticateParams as h, isCredentialError as i, setSessionLiveMessage as j, recordLlmUsageFromAssistantMessage as k, connectMcpStdio as l, auth as m, captureCredentialToolErrors as n, resolveMcpTools as o, UnauthorizedError as p, createCredentialResolver as r, connectMcpDefinition as s, buildCredentialRunContext as t, defineMcp as u, zodToJsonSchema as v, createSession as w, addAgentSessionDuration as x, JSONRPCMessageSchema as y };
18712
+ export { recordLlmUsageFromAssistantMessage as A, appendEvent as C, getProjectScopeId as D, getAgentByRoute as E, captureConsole as F, getTraceContext as I, logSystem as L, setSessionLiveMessage as M, setSessionTitle as N, getSession as O, touchSession as P, withSpan as R, addAgentSessionDuration as S, createSession as T, createFetchWithInit as _, resolveActionCredentials as a, JSONRPCMessageSchema as b, connectMcpDefinition as c, defineMcp as d, isMcp as f, extractWWWAuthenticateParams as g, auth as h, isCredentialError as i, resolveRunSourceFromTraceContext as j, listMessageEvents as k, connectMcpServer as l, UnauthorizedError as m, captureCredentialToolErrors as n, resolveMcpTools as o, createParser as p, createCredentialResolver as r, withCredentialAssignments as s, buildCredentialRunContext as t, connectMcpStdio as u, normalizeHeaders as v, clearLiveMessage as w, MESSAGE_EVENT_TYPE as x, zodToJsonSchema as y };
18524
18713
 
18525
- //# sourceMappingURL=dist-IUl7Bexl.mjs.map
18714
+ //# sourceMappingURL=dist-UzTnzZem.mjs.map