@yaklabs-ai/plugin-sdk 0.27.1 → 0.28.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.
package/README.md CHANGED
@@ -13,7 +13,7 @@ it under the name your plugin code actually imports:
13
13
  ```json
14
14
  {
15
15
  "dependencies": {
16
- "@bonsai/plugin-sdk": "npm:@yaklabs-ai/plugin-sdk@^0.27.1"
16
+ "@bonsai/plugin-sdk": "npm:@yaklabs-ai/plugin-sdk@^0.28.0"
17
17
  }
18
18
  }
19
19
  ```
@@ -62,7 +62,7 @@ Every tool the entrypoint registers is declared in the manifest too:
62
62
  "description": "Greets people by name.",
63
63
  "version": "0.1.0",
64
64
  "namespace": "widgets",
65
- "compatibility": { "sdk": "^0.27.1" },
65
+ "compatibility": { "sdk": "^0.28.0" },
66
66
  "targets": {
67
67
  "kay": {
68
68
  "agent": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "package": "@yaklabs-ai/plugin-sdk",
4
- "version": "0.27.1",
4
+ "version": "0.28.0",
5
5
  "target": "npm",
6
6
  "firstPartyLicense": "MIT",
7
7
  "bundled": [
@@ -34,6 +34,20 @@ declare interface AccountIdentity {
34
34
  readonly providerSessionId?: string;
35
35
  }
36
36
 
37
+ /**
38
+ * Whose credential this is: every provider account it reaches. One sign-in can reach several
39
+ * (Cloudflare), so the answer is always a list. A bad credential throws.
40
+ */
41
+ declare type AccountLookup = (input: AccountLookupInput) => Promise<readonly LookedUpAccount[]>;
42
+
43
+ /** What an account lookup is asked about: a fresh credential. */
44
+ declare interface AccountLookupInput {
45
+ readonly accessToken: string;
46
+ /** Every declared field of a multi-field api-key scheme; empty for anything else. */
47
+ readonly fields: Readonly<Record<string, string>>;
48
+ readonly signal: AbortSignal;
49
+ }
50
+
37
51
  /**
38
52
  * Structured, non-secret *provenance* for a connected account: which record on the provider's side
39
53
  * this credential points at. Says nothing about the human - a Notion `displayName` here is the
@@ -2318,8 +2332,17 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2318
2332
  * hosted module's code and manifest must agree on it, and the daemon reads it to find an
2319
2333
  * external-CLI scheme without running the module. A module that runs in the daemon is unchanged,
2320
2334
  * so this is additive; a plugin whose manifest sets `authScheme` declares ^0.27.1.
2335
+ *
2336
+ * 0.28.0 makes "whose credential is this?" one call (#15714). `api.auth.registerAccountLookup`
2337
+ * replaces `registerValidator` and `registerAccountResolver`: it takes the credential, its fields and
2338
+ * a cancel signal, and returns every account the credential reaches. A manifest says `account:
2339
+ * "lookup"` on any `oauth2` or `api-key` scheme the plugin answers for, in place of `validates: true`
2340
+ * and the `"resolveAccountId"` and `"resolveAccounts"` values, and a `pkce` scheme on a client the
2341
+ * host holds may name one too. A plugin using a removed member or value stops loading until it is
2342
+ * rebuilt; a code search found none outside this repo. A plugin with a sign-in declares ^0.28.0. 0.26.3 and 0.27.1
2343
+ * stay served for a plugin that uses none of these.
2321
2344
  */
2322
- declare const KAY_PLUGIN_SDK_VERSION: "0.27.1";
2345
+ declare const KAY_PLUGIN_SDK_VERSION: "0.28.0";
2323
2346
 
2324
2347
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2325
2348
 
@@ -2697,16 +2720,12 @@ declare interface KayAgentPluginApi {
2697
2720
  */
2698
2721
  readonly auth: {
2699
2722
  /**
2700
- * The check for an `api-key` scheme the manifest marks `validates: true`. `serviceId` and
2701
- * `schemeId` are the manifest's global ids (`github.account`, `github.pat`).
2723
+ * Whose credential this is, for a scheme whose manifest says `account: "lookup"`. `serviceId` and
2724
+ * `schemeId` are the manifest's global ids (`github.account`, `github.pat`). On an `api-key`
2725
+ * scheme it also checks the key before it is saved, and must name exactly one account. Refused
2726
+ * on any other scheme.
2702
2727
  */
2703
- registerValidator(serviceId: string, schemeId: string, validate: ValidatePluginApiKeyCredential): void;
2704
- /**
2705
- * The account lookup for an `oauth2` scheme whose manifest names it as where the account comes
2706
- * from (`account: "resolveAccountId"` or `"resolveAccounts"`), registering that function only.
2707
- * Refused on any other scheme.
2708
- */
2709
- registerAccountResolver(serviceId: string, schemeId: string, resolver: PluginAccountResolver): void;
2728
+ registerAccountLookup(serviceId: string, schemeId: string, lookup: PluginAccountLookup): void;
2710
2729
  /**
2711
2730
  * Declare a delegated scheme (plugin-provided connect/refresh over opaque material) for a
2712
2731
  * service. The host maps it onto the kernel's `DelegatedAuthScheme` and drives its `connect`
@@ -3330,6 +3349,15 @@ declare const LocalContributionId: z.ZodString;
3330
3349
 
3331
3350
  declare type LocalContributionId = z.infer<typeof LocalContributionId>;
3332
3351
 
3352
+ /** One provider account a credential reaches. */
3353
+ declare interface LookedUpAccount {
3354
+ readonly accountId: string;
3355
+ readonly label?: string;
3356
+ readonly identity?: AccountIdentity;
3357
+ /** Non-secret observations the host may surface without retaining credential material. */
3358
+ readonly capabilityChecks?: readonly ApiKeyCapabilityCheck[];
3359
+ }
3360
+
3333
3361
  /** Applies a Lowercase action to the given type. */
3334
3362
  declare function Lowercase_2<Type extends TSchema>(type: Type, options?: TSchemaOptions): TLowercase<Type>;
3335
3363
 
@@ -4184,13 +4212,10 @@ export declare const PLUGIN_DISCLOSURE_CONTRACT = 2;
4184
4212
  export declare const PLUGIN_DISCLOSURE_RULES: readonly ["agent-hint-missing", "agent-hint-summary-empty", "agent-hint-flows-empty", "agent-hint-triggers-missing", "scheme-claim-missing", "help-missing", "help-malformed", "help-throws", "help-uri-malformed", "help-uri-throws", "verb-coverage-missing", "template-operation-docs-missing", "verb-docs-missing", "template-accepts-missing", "template-address-unmatchable", "template-delete-effect-missing", "template-operations-missing", "template-parameter-unknown", "template-scheme-mismatch", "clamp-summary", "clamp-flow-label", "clamp-flow-when", "clamp-flow-example", "clamp-trigger-count", "clamp-trigger-item", "clamp-help-uri", "skill-link-dangling", "skill-link-missing-scheme", "skill-twin-count-mismatch", "skill-twin-missing-declaration", "skill-twin-description-mismatch", "skill-twin-file-unreadable", "skill-twin-frontmatter-name-mismatch", "skill-twin-frontmatter-description-mismatch", "skill-twin-body-mismatch"];
4185
4213
 
4186
4214
  /**
4187
- * How a plugin learns which provider account a fresh OAuth token belongs to: one account, or every
4188
- * account the grant reaches. Registered with `api.auth.registerAccountResolver`.
4215
+ * Whose credential this is: every provider account it reaches, usually one. A bad credential throws.
4216
+ * Registered with `api.auth.registerAccountLookup`.
4189
4217
  */
4190
- declare interface PluginAccountResolver {
4191
- readonly resolveAccountId?: ResolvePluginAccountId;
4192
- readonly resolveAccounts?: ResolvePluginAccounts;
4193
- }
4218
+ declare type PluginAccountLookup = AccountLookup;
4194
4219
 
4195
4220
  /** The kinds of capability a plugin service can advertise (mirrors the host capability taxonomy). */
4196
4221
  declare type PluginCapabilityKind = "uri-module" | "tool" | "search-provider";
@@ -4651,28 +4676,6 @@ declare interface ResolvedCredential {
4651
4676
  readonly fields?: Readonly<Record<string, string>>;
4652
4677
  }
4653
4678
 
4654
- /**
4655
- * Derive a stable provider account id (and optional label) from a freshly connected access token,
4656
- * plus - when known - who the account belongs to.
4657
- *
4658
- * A resolver almost always calls the provider's profile endpoint to derive `accountId` at all, so
4659
- * the identity fields are already in the response: return them rather than flattening the person
4660
- * into `label`. Populating `identity` is what lets the agent know the user's handle/email for a
4661
- * connected service without asking.
4662
- */
4663
- declare type ResolvePluginAccountId = (accessToken: string) => Promise<{
4664
- readonly accountId: string;
4665
- readonly label?: string;
4666
- readonly identity?: AccountIdentity;
4667
- }>;
4668
-
4669
- /** Enumerate every provider account a fresh OAuth grant powers. */
4670
- declare type ResolvePluginAccounts = (accessToken: string) => Promise<readonly {
4671
- readonly accountId: string;
4672
- readonly label?: string;
4673
- readonly identity?: AccountIdentity;
4674
- }[]>;
4675
-
4676
4679
  /** Match remaining characters in the buffer until end. If no characters are in buffer, no match */
4677
4680
  declare function Rest<Input extends string>(input: Input): TRest<Input>;
4678
4681
 
@@ -10213,26 +10216,6 @@ declare interface Usage {
10213
10216
  };
10214
10217
  }
10215
10218
 
10216
- /** Validate freshly-entered material and resolve the provider account before persistence. */
10217
- declare type ValidateApiKeyCredential = (input: ValidateApiKeyCredentialInput) => Promise<ValidateApiKeyCredentialResult>;
10218
-
10219
- declare interface ValidateApiKeyCredentialInput {
10220
- readonly accessToken: string;
10221
- /** Every declared field; empty for a classic single-secret scheme. */
10222
- readonly fields: Readonly<Record<string, string>>;
10223
- readonly signal: AbortSignal;
10224
- }
10225
-
10226
- declare interface ValidateApiKeyCredentialResult {
10227
- readonly accountId: string;
10228
- readonly label?: string;
10229
- readonly identity?: AccountIdentity;
10230
- /** Non-secret observations the host may surface without retaining credential material. */
10231
- readonly capabilityChecks?: readonly ApiKeyCapabilityCheck[];
10232
- }
10233
-
10234
- declare type ValidatePluginApiKeyCredential = ValidateApiKeyCredential;
10235
-
10236
10219
  /**
10237
10220
  * ---
10238
10221
  * responsibility: The one interface through which a vendored-MCP plugin's code calls a tool on its
@@ -932,9 +932,7 @@ function collectUriModulesFromKayAgentActivate(activate) {
932
932
  registerConverter: () => {
933
933
  },
934
934
  auth: {
935
- registerValidator: () => {
936
- },
937
- registerAccountResolver: () => {
935
+ registerAccountLookup: () => {
938
936
  },
939
937
  declareDelegatedScheme: () => {
940
938
  },
@@ -34,6 +34,20 @@ declare interface AccountIdentity {
34
34
  readonly providerSessionId?: string;
35
35
  }
36
36
 
37
+ /**
38
+ * Whose credential this is: every provider account it reaches. One sign-in can reach several
39
+ * (Cloudflare), so the answer is always a list. A bad credential throws.
40
+ */
41
+ declare type AccountLookup = (input: AccountLookupInput) => Promise<readonly LookedUpAccount[]>;
42
+
43
+ /** What an account lookup is asked about: a fresh credential. */
44
+ declare interface AccountLookupInput {
45
+ readonly accessToken: string;
46
+ /** Every declared field of a multi-field api-key scheme; empty for anything else. */
47
+ readonly fields: Readonly<Record<string, string>>;
48
+ readonly signal: AbortSignal;
49
+ }
50
+
37
51
  /**
38
52
  * Structured, non-secret *provenance* for a connected account: which record on the provider's side
39
53
  * this credential points at. Says nothing about the human - a Notion `displayName` here is the
@@ -2372,8 +2386,17 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2372
2386
  * hosted module's code and manifest must agree on it, and the daemon reads it to find an
2373
2387
  * external-CLI scheme without running the module. A module that runs in the daemon is unchanged,
2374
2388
  * so this is additive; a plugin whose manifest sets `authScheme` declares ^0.27.1.
2389
+ *
2390
+ * 0.28.0 makes "whose credential is this?" one call (#15714). `api.auth.registerAccountLookup`
2391
+ * replaces `registerValidator` and `registerAccountResolver`: it takes the credential, its fields and
2392
+ * a cancel signal, and returns every account the credential reaches. A manifest says `account:
2393
+ * "lookup"` on any `oauth2` or `api-key` scheme the plugin answers for, in place of `validates: true`
2394
+ * and the `"resolveAccountId"` and `"resolveAccounts"` values, and a `pkce` scheme on a client the
2395
+ * host holds may name one too. A plugin using a removed member or value stops loading until it is
2396
+ * rebuilt; a code search found none outside this repo. A plugin with a sign-in declares ^0.28.0. 0.26.3 and 0.27.1
2397
+ * stay served for a plugin that uses none of these.
2375
2398
  */
2376
- declare const KAY_PLUGIN_SDK_VERSION: "0.27.1";
2399
+ declare const KAY_PLUGIN_SDK_VERSION: "0.28.0";
2377
2400
 
2378
2401
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2379
2402
 
@@ -2748,16 +2771,12 @@ declare interface KayAgentPluginApi {
2748
2771
  */
2749
2772
  readonly auth: {
2750
2773
  /**
2751
- * The check for an `api-key` scheme the manifest marks `validates: true`. `serviceId` and
2752
- * `schemeId` are the manifest's global ids (`github.account`, `github.pat`).
2774
+ * Whose credential this is, for a scheme whose manifest says `account: "lookup"`. `serviceId` and
2775
+ * `schemeId` are the manifest's global ids (`github.account`, `github.pat`). On an `api-key`
2776
+ * scheme it also checks the key before it is saved, and must name exactly one account. Refused
2777
+ * on any other scheme.
2753
2778
  */
2754
- registerValidator(serviceId: string, schemeId: string, validate: ValidatePluginApiKeyCredential): void;
2755
- /**
2756
- * The account lookup for an `oauth2` scheme whose manifest names it as where the account comes
2757
- * from (`account: "resolveAccountId"` or `"resolveAccounts"`), registering that function only.
2758
- * Refused on any other scheme.
2759
- */
2760
- registerAccountResolver(serviceId: string, schemeId: string, resolver: PluginAccountResolver): void;
2779
+ registerAccountLookup(serviceId: string, schemeId: string, lookup: PluginAccountLookup): void;
2761
2780
  /**
2762
2781
  * Declare a delegated scheme (plugin-provided connect/refresh over opaque material) for a
2763
2782
  * service. The host maps it onto the kernel's `DelegatedAuthScheme` and drives its `connect`
@@ -3381,6 +3400,15 @@ declare const LocalContributionId: z.ZodString;
3381
3400
 
3382
3401
  declare type LocalContributionId = z.infer<typeof LocalContributionId>;
3383
3402
 
3403
+ /** One provider account a credential reaches. */
3404
+ declare interface LookedUpAccount {
3405
+ readonly accountId: string;
3406
+ readonly label?: string;
3407
+ readonly identity?: AccountIdentity;
3408
+ /** Non-secret observations the host may surface without retaining credential material. */
3409
+ readonly capabilityChecks?: readonly ApiKeyCapabilityCheck[];
3410
+ }
3411
+
3384
3412
  /** Applies a Lowercase action to the given type. */
3385
3413
  declare function Lowercase_2<Type extends TSchema>(type: Type, options?: TSchemaOptions): TLowercase<Type>;
3386
3414
 
@@ -4202,13 +4230,10 @@ declare function Pick_2<Type extends TSchema, Indexer extends TSchema>(type: Typ
4202
4230
  declare function PickDeferred<Type extends TSchema, Indexer extends TSchema>(type: Type, indexer: Indexer, options?: TSchemaOptions): TPickDeferred<Type, Indexer>;
4203
4231
 
4204
4232
  /**
4205
- * How a plugin learns which provider account a fresh OAuth token belongs to: one account, or every
4206
- * account the grant reaches. Registered with `api.auth.registerAccountResolver`.
4233
+ * Whose credential this is: every provider account it reaches, usually one. A bad credential throws.
4234
+ * Registered with `api.auth.registerAccountLookup`.
4207
4235
  */
4208
- declare interface PluginAccountResolver {
4209
- readonly resolveAccountId?: ResolvePluginAccountId;
4210
- readonly resolveAccounts?: ResolvePluginAccounts;
4211
- }
4236
+ declare type PluginAccountLookup = AccountLookup;
4212
4237
 
4213
4238
  /** The kinds of capability a plugin service can advertise (mirrors the host capability taxonomy). */
4214
4239
  declare type PluginCapabilityKind = "uri-module" | "tool" | "search-provider";
@@ -4763,10 +4788,7 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
4763
4788
  }>>;
4764
4789
  clientId: z.ZodOptional<z.ZodString>;
4765
4790
  clientSecret: z.ZodOptional<z.ZodString>;
4766
- account: z.ZodOptional<z.ZodEnum<{
4767
- resolveAccountId: "resolveAccountId";
4768
- resolveAccounts: "resolveAccounts";
4769
- }>>;
4791
+ account: z.ZodOptional<z.ZodLiteral<"lookup">>;
4770
4792
  localId: z.ZodString;
4771
4793
  globalId: z.ZodString;
4772
4794
  kind: z.ZodLiteral<"oauth2">;
@@ -4795,8 +4817,7 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
4795
4817
  exchange: z.ZodLiteral<"confidential">;
4796
4818
  clientSuppliers: z.ZodTuple<[z.ZodLiteral<"kay">], null>;
4797
4819
  account: z.ZodEnum<{
4798
- resolveAccountId: "resolveAccountId";
4799
- resolveAccounts: "resolveAccounts";
4820
+ lookup: "lookup";
4800
4821
  "sign-in": "sign-in";
4801
4822
  }>;
4802
4823
  localId: z.ZodString;
@@ -4837,7 +4858,7 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
4837
4858
  instructions: z.ZodString;
4838
4859
  url: z.ZodURL;
4839
4860
  }, z.core.$strict>>;
4840
- validates: z.ZodOptional<z.ZodLiteral<true>>;
4861
+ account: z.ZodOptional<z.ZodLiteral<"lookup">>;
4841
4862
  displayName: z.ZodOptional<z.ZodString>;
4842
4863
  agentHint: z.ZodOptional<z.ZodString>;
4843
4864
  summary: z.ZodOptional<z.ZodString>;
@@ -5687,28 +5708,6 @@ declare type ResolveExternalCliResult = {
5687
5708
  readonly accounts?: readonly AuthAccount[];
5688
5709
  };
5689
5710
 
5690
- /**
5691
- * Derive a stable provider account id (and optional label) from a freshly connected access token,
5692
- * plus - when known - who the account belongs to.
5693
- *
5694
- * A resolver almost always calls the provider's profile endpoint to derive `accountId` at all, so
5695
- * the identity fields are already in the response: return them rather than flattening the person
5696
- * into `label`. Populating `identity` is what lets the agent know the user's handle/email for a
5697
- * connected service without asking.
5698
- */
5699
- declare type ResolvePluginAccountId = (accessToken: string) => Promise<{
5700
- readonly accountId: string;
5701
- readonly label?: string;
5702
- readonly identity?: AccountIdentity;
5703
- }>;
5704
-
5705
- /** Enumerate every provider account a fresh OAuth grant powers. */
5706
- declare type ResolvePluginAccounts = (accessToken: string) => Promise<readonly {
5707
- readonly accountId: string;
5708
- readonly label?: string;
5709
- readonly identity?: AccountIdentity;
5710
- }[]>;
5711
-
5712
5711
  declare interface ResolveTokenFailure {
5713
5712
  readonly ok: false;
5714
5713
  readonly reason: ResolveTokenFailureReason;
@@ -11280,26 +11279,6 @@ declare interface Usage {
11280
11279
  };
11281
11280
  }
11282
11281
 
11283
- /** Validate freshly-entered material and resolve the provider account before persistence. */
11284
- declare type ValidateApiKeyCredential = (input: ValidateApiKeyCredentialInput) => Promise<ValidateApiKeyCredentialResult>;
11285
-
11286
- declare interface ValidateApiKeyCredentialInput {
11287
- readonly accessToken: string;
11288
- /** Every declared field; empty for a classic single-secret scheme. */
11289
- readonly fields: Readonly<Record<string, string>>;
11290
- readonly signal: AbortSignal;
11291
- }
11292
-
11293
- declare interface ValidateApiKeyCredentialResult {
11294
- readonly accountId: string;
11295
- readonly label?: string;
11296
- readonly identity?: AccountIdentity;
11297
- /** Non-secret observations the host may surface without retaining credential material. */
11298
- readonly capabilityChecks?: readonly ApiKeyCapabilityCheck[];
11299
- }
11300
-
11301
- declare type ValidatePluginApiKeyCredential = ValidateApiKeyCredential;
11302
-
11303
11282
  /**
11304
11283
  * ---
11305
11284
  * responsibility: The one interface through which a vendored-MCP plugin's code calls a tool on its
@@ -35,6 +35,20 @@ export declare interface AccountIdentity {
35
35
  readonly providerSessionId?: string;
36
36
  }
37
37
 
38
+ /**
39
+ * Whose credential this is: every provider account it reaches. One sign-in can reach several
40
+ * (Cloudflare), so the answer is always a list. A bad credential throws.
41
+ */
42
+ declare type AccountLookup = (input: AccountLookupInput) => Promise<readonly LookedUpAccount[]>;
43
+
44
+ /** What an account lookup is asked about: a fresh credential. */
45
+ declare interface AccountLookupInput {
46
+ readonly accessToken: string;
47
+ /** Every declared field of a multi-field api-key scheme; empty for anything else. */
48
+ readonly fields: Readonly<Record<string, string>>;
49
+ readonly signal: AbortSignal;
50
+ }
51
+
38
52
  /**
39
53
  * Structured, non-secret *provenance* for a connected account: which record on the provider's side
40
54
  * this credential points at. Says nothing about the human - a Notion `displayName` here is the
@@ -2647,8 +2661,17 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2647
2661
  * hosted module's code and manifest must agree on it, and the daemon reads it to find an
2648
2662
  * external-CLI scheme without running the module. A module that runs in the daemon is unchanged,
2649
2663
  * so this is additive; a plugin whose manifest sets `authScheme` declares ^0.27.1.
2664
+ *
2665
+ * 0.28.0 makes "whose credential is this?" one call (#15714). `api.auth.registerAccountLookup`
2666
+ * replaces `registerValidator` and `registerAccountResolver`: it takes the credential, its fields and
2667
+ * a cancel signal, and returns every account the credential reaches. A manifest says `account:
2668
+ * "lookup"` on any `oauth2` or `api-key` scheme the plugin answers for, in place of `validates: true`
2669
+ * and the `"resolveAccountId"` and `"resolveAccounts"` values, and a `pkce` scheme on a client the
2670
+ * host holds may name one too. A plugin using a removed member or value stops loading until it is
2671
+ * rebuilt; a code search found none outside this repo. A plugin with a sign-in declares ^0.28.0. 0.26.3 and 0.27.1
2672
+ * stay served for a plugin that uses none of these.
2650
2673
  */
2651
- declare const KAY_PLUGIN_SDK_VERSION: "0.27.1";
2674
+ declare const KAY_PLUGIN_SDK_VERSION: "0.28.0";
2652
2675
 
2653
2676
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2654
2677
 
@@ -3055,16 +3078,12 @@ export declare interface KayAgentPluginApi {
3055
3078
  */
3056
3079
  readonly auth: {
3057
3080
  /**
3058
- * The check for an `api-key` scheme the manifest marks `validates: true`. `serviceId` and
3059
- * `schemeId` are the manifest's global ids (`github.account`, `github.pat`).
3060
- */
3061
- registerValidator(serviceId: string, schemeId: string, validate: ValidatePluginApiKeyCredential): void;
3062
- /**
3063
- * The account lookup for an `oauth2` scheme whose manifest names it as where the account comes
3064
- * from (`account: "resolveAccountId"` or `"resolveAccounts"`), registering that function only.
3065
- * Refused on any other scheme.
3081
+ * Whose credential this is, for a scheme whose manifest says `account: "lookup"`. `serviceId` and
3082
+ * `schemeId` are the manifest's global ids (`github.account`, `github.pat`). On an `api-key`
3083
+ * scheme it also checks the key before it is saved, and must name exactly one account. Refused
3084
+ * on any other scheme.
3066
3085
  */
3067
- registerAccountResolver(serviceId: string, schemeId: string, resolver: PluginAccountResolver): void;
3086
+ registerAccountLookup(serviceId: string, schemeId: string, lookup: PluginAccountLookup): void;
3068
3087
  /**
3069
3088
  * Declare a delegated scheme (plugin-provided connect/refresh over opaque material) for a
3070
3089
  * service. The host maps it onto the kernel's `DelegatedAuthScheme` and drives its `connect`
@@ -3747,6 +3766,15 @@ declare const LocalContributionId: z.ZodString;
3747
3766
 
3748
3767
  declare type LocalContributionId = z.infer<typeof LocalContributionId>;
3749
3768
 
3769
+ /** One provider account a credential reaches. */
3770
+ declare interface LookedUpAccount {
3771
+ readonly accountId: string;
3772
+ readonly label?: string;
3773
+ readonly identity?: AccountIdentity;
3774
+ /** Non-secret observations the host may surface without retaining credential material. */
3775
+ readonly capabilityChecks?: readonly ApiKeyCapabilityCheck[];
3776
+ }
3777
+
3750
3778
  /** Applies a Lowercase action to the given type. */
3751
3779
  declare function Lowercase_2<Type extends TSchema>(type: Type, options?: TSchemaOptions): TLowercase<Type>;
3752
3780
 
@@ -4821,13 +4849,21 @@ declare function Pick_2<Type extends TSchema, Indexer extends TSchema>(type: Typ
4821
4849
  declare function PickDeferred<Type extends TSchema, Indexer extends TSchema>(type: Type, indexer: Indexer, options?: TSchemaOptions): TPickDeferred<Type, Indexer>;
4822
4850
 
4823
4851
  /**
4824
- * How a plugin learns which provider account a fresh OAuth token belongs to: one account, or every
4825
- * account the grant reaches. Registered with `api.auth.registerAccountResolver`.
4852
+ * One provider account a credential reaches. A lookup almost always calls the provider's profile
4853
+ * endpoint to find `accountId`, so the identity fields are already in the response: return them
4854
+ * rather than flattening the person into `label`. `identity` is what lets the agent know the user's
4855
+ * handle or email for a connected service without asking.
4826
4856
  */
4827
- export declare interface PluginAccountResolver {
4828
- readonly resolveAccountId?: ResolvePluginAccountId;
4829
- readonly resolveAccounts?: ResolvePluginAccounts;
4830
- }
4857
+ export declare type PluginAccount = LookedUpAccount;
4858
+
4859
+ /**
4860
+ * Whose credential this is: every provider account it reaches, usually one. A bad credential throws.
4861
+ * Registered with `api.auth.registerAccountLookup`.
4862
+ */
4863
+ export declare type PluginAccountLookup = AccountLookup;
4864
+
4865
+ /** What an account lookup is asked about: a fresh credential, its fields, and a cancel signal. */
4866
+ export declare type PluginAccountLookupInput = AccountLookupInput;
4831
4867
 
4832
4868
  /** Per-call options every method accepts. No construction-time credentials (see module doc) - an
4833
4869
  * `Authorization`/`Api-Key`/etc header goes here, per call, after `withResolvedAuth` resolves it. */
@@ -5733,28 +5769,6 @@ declare type ResolveExternalCliResult = {
5733
5769
  readonly accounts?: readonly AuthAccount[];
5734
5770
  };
5735
5771
 
5736
- /**
5737
- * Derive a stable provider account id (and optional label) from a freshly connected access token,
5738
- * plus - when known - who the account belongs to.
5739
- *
5740
- * A resolver almost always calls the provider's profile endpoint to derive `accountId` at all, so
5741
- * the identity fields are already in the response: return them rather than flattening the person
5742
- * into `label`. Populating `identity` is what lets the agent know the user's handle/email for a
5743
- * connected service without asking.
5744
- */
5745
- export declare type ResolvePluginAccountId = (accessToken: string) => Promise<{
5746
- readonly accountId: string;
5747
- readonly label?: string;
5748
- readonly identity?: AccountIdentity;
5749
- }>;
5750
-
5751
- /** Enumerate every provider account a fresh OAuth grant powers. */
5752
- export declare type ResolvePluginAccounts = (accessToken: string) => Promise<readonly {
5753
- readonly accountId: string;
5754
- readonly label?: string;
5755
- readonly identity?: AccountIdentity;
5756
- }[]>;
5757
-
5758
5772
  declare interface ResolveTokenFailure {
5759
5773
  readonly ok: false;
5760
5774
  readonly reason: ResolveTokenFailureReason;
@@ -11688,30 +11702,6 @@ declare interface Usage {
11688
11702
  };
11689
11703
  }
11690
11704
 
11691
- /** Validate freshly-entered material and resolve the provider account before persistence. */
11692
- declare type ValidateApiKeyCredential = (input: ValidateApiKeyCredentialInput) => Promise<ValidateApiKeyCredentialResult>;
11693
-
11694
- declare interface ValidateApiKeyCredentialInput {
11695
- readonly accessToken: string;
11696
- /** Every declared field; empty for a classic single-secret scheme. */
11697
- readonly fields: Readonly<Record<string, string>>;
11698
- readonly signal: AbortSignal;
11699
- }
11700
-
11701
- declare interface ValidateApiKeyCredentialResult {
11702
- readonly accountId: string;
11703
- readonly label?: string;
11704
- readonly identity?: AccountIdentity;
11705
- /** Non-secret observations the host may surface without retaining credential material. */
11706
- readonly capabilityChecks?: readonly ApiKeyCapabilityCheck[];
11707
- }
11708
-
11709
- export declare type ValidatePluginApiKeyCredential = ValidateApiKeyCredential;
11710
-
11711
- export declare type ValidatePluginApiKeyCredentialInput = ValidateApiKeyCredentialInput;
11712
-
11713
- export declare type ValidatePluginApiKeyCredentialResult = ValidateApiKeyCredentialResult;
11714
-
11715
11705
  /**
11716
11706
  * ---
11717
11707
  * responsibility: The one interface through which a vendored-MCP plugin's code calls a tool on its
package/dist/kay-app.d.ts CHANGED
@@ -2618,8 +2618,17 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2618
2618
  * hosted module's code and manifest must agree on it, and the daemon reads it to find an
2619
2619
  * external-CLI scheme without running the module. A module that runs in the daemon is unchanged,
2620
2620
  * so this is additive; a plugin whose manifest sets `authScheme` declares ^0.27.1.
2621
+ *
2622
+ * 0.28.0 makes "whose credential is this?" one call (#15714). `api.auth.registerAccountLookup`
2623
+ * replaces `registerValidator` and `registerAccountResolver`: it takes the credential, its fields and
2624
+ * a cancel signal, and returns every account the credential reaches. A manifest says `account:
2625
+ * "lookup"` on any `oauth2` or `api-key` scheme the plugin answers for, in place of `validates: true`
2626
+ * and the `"resolveAccountId"` and `"resolveAccounts"` values, and a `pkce` scheme on a client the
2627
+ * host holds may name one too. A plugin using a removed member or value stops loading until it is
2628
+ * rebuilt; a code search found none outside this repo. A plugin with a sign-in declares ^0.28.0. 0.26.3 and 0.27.1
2629
+ * stay served for a plugin that uses none of these.
2621
2630
  */
2622
- declare const KAY_PLUGIN_SDK_VERSION: "0.27.1";
2631
+ declare const KAY_PLUGIN_SDK_VERSION: "0.28.0";
2623
2632
 
2624
2633
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2625
2634
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaklabs-ai/plugin-sdk",
3
- "version": "0.27.1",
3
+ "version": "0.28.0",
4
4
  "description": "The Kay plugin SDK — types and helpers for authoring a Kay directory plugin.",
5
5
  "author": "YakLabs",
6
6
  "type": "module",