@lessly/sdk-app 61.2.0 → 62.1.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 (38) hide show
  1. package/dist/_types/gen/client.gen.d.ts +53 -2
  2. package/dist/_types/gen/manifest.gen.d.ts +1 -1
  3. package/dist/_types/gen/organization/index.d.ts +1 -1
  4. package/dist/_types/gen/organization/queryOptions.gen.d.ts +57 -5
  5. package/dist/_types/gen/playground/connect.gen.d.ts +3 -0
  6. package/dist/_types/gen/playground/index.d.ts +3 -0
  7. package/dist/_types/gen/playground/queryOptions.gen.d.ts +50 -0
  8. package/dist/_types/gen/types.gen.d.ts +374 -10
  9. package/dist/_types/index.d.ts +1 -0
  10. package/dist/_types/runtime/access-reason.d.ts +20 -0
  11. package/dist/chunk-2YAA3AF4.js +10437 -0
  12. package/dist/chunk-2YAA3AF4.js.map +1 -0
  13. package/dist/index.cjs +444 -66
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.js +60 -10106
  16. package/dist/index.js.map +1 -1
  17. package/dist/organization/index.cjs +70 -5
  18. package/dist/organization/index.cjs.map +1 -1
  19. package/dist/organization/index.js +57 -5
  20. package/dist/organization/index.js.map +1 -1
  21. package/dist/playground/index.cjs +81 -0
  22. package/dist/playground/index.cjs.map +1 -0
  23. package/dist/playground/index.d.cts +1 -0
  24. package/dist/playground/index.d.ts +1 -0
  25. package/dist/playground/index.js +58 -0
  26. package/dist/playground/index.js.map +1 -0
  27. package/docs/recipes/access.md +456 -15
  28. package/docs/rules.md +92 -0
  29. package/package.json +12 -2
  30. package/src/gen/bindings.gen.ts +395 -40
  31. package/src/gen/client.gen.ts +104 -3
  32. package/src/gen/manifest.gen.ts +53 -28
  33. package/src/gen/organization/index.ts +1 -1
  34. package/src/gen/organization/queryOptions.gen.ts +87 -6
  35. package/src/gen/playground/connect.gen.ts +9 -0
  36. package/src/gen/playground/index.ts +4 -0
  37. package/src/gen/playground/queryOptions.gen.ts +86 -0
  38. package/src/gen/types.gen.ts +441 -12
@@ -90027,12 +90027,6 @@ export interface OrganizationBillingBudgetsGetInput {
90027
90027
  export interface OrganizationBillingBudgetsGetOutput {
90028
90028
  [k: string]: unknown;
90029
90029
  }
90030
- export interface OrganizationBillingBudgetsSetInput {
90031
- ceiling_minor: number;
90032
- }
90033
- export interface OrganizationBillingBudgetsSetOutput {
90034
- [k: string]: unknown;
90035
- }
90036
90030
  export interface OrganizationBillingCapsClearInput {
90037
90031
  productId: string;
90038
90032
  }
@@ -90136,10 +90130,13 @@ export type OrganizationConnectorsListOutput = {
90136
90130
  origin: ("product" | "org");
90137
90131
  status: string;
90138
90132
  provider: string;
90133
+ reauthAt: (string | null);
90139
90134
  createdAt: string;
90140
90135
  customerId: (string | null);
90141
90136
  externalId: string;
90142
90137
  displayName: string;
90138
+ needsReauth: boolean;
90139
+ reauthReason: (string | null);
90143
90140
  }[];
90144
90141
  export interface OrganizationConnectorsListAttachmentsInput {
90145
90142
  id: string;
@@ -90161,8 +90158,11 @@ export type OrganizationConnectorsListAvailableOutput = {
90161
90158
  id: string;
90162
90159
  status: string;
90163
90160
  provider: string;
90161
+ reauthAt: (string | null);
90164
90162
  externalId: string;
90165
90163
  displayName: string;
90164
+ needsReauth: boolean;
90165
+ reauthReason: (string | null);
90166
90166
  requestStatus: (("pending" | "denied") | null);
90167
90167
  organizationId: string;
90168
90168
  }[];
@@ -90176,9 +90176,12 @@ export type OrganizationConnectorsListOrgOutput = {
90176
90176
  };
90177
90177
  status: string;
90178
90178
  provider: string;
90179
+ reauthAt: (string | null);
90179
90180
  createdAt: string;
90180
90181
  externalId: string;
90181
90182
  displayName: string;
90183
+ needsReauth: boolean;
90184
+ reauthReason: (string | null);
90182
90185
  organizationId: string;
90183
90186
  attachedProducts: {
90184
90187
  createdAt: string;
@@ -90219,8 +90222,8 @@ export interface OrganizationConnectorsRequestOutput {
90219
90222
  }
90220
90223
  export interface OrganizationCreateInput {
90221
90224
  name: string;
90222
- legalName?: string;
90223
- ownerName?: string;
90225
+ legalName: string;
90226
+ ownerName: string;
90224
90227
  /**
90225
90228
  * @maxItems 50
90226
90229
  */
@@ -90229,9 +90232,9 @@ export interface OrganizationCreateInput {
90229
90232
  country: string;
90230
90233
  share_pct: number;
90231
90234
  }[];
90232
- residencyCountry?: string;
90235
+ residencyCountry: string;
90233
90236
  ownershipConfirmed?: boolean;
90234
- countryOfIncorporation?: string;
90237
+ countryOfIncorporation: string;
90235
90238
  }
90236
90239
  export interface OrganizationCreateOutput {
90237
90240
  id: string;
@@ -90365,6 +90368,131 @@ export interface OrganizationGoogleadsInstallInput {
90365
90368
  export interface OrganizationGoogleadsInstallOutput {
90366
90369
  url: string;
90367
90370
  }
90371
+ export interface OrganizationGroupsCreateInput {
90372
+ name: string;
90373
+ orgId: string;
90374
+ description?: string;
90375
+ }
90376
+ export interface OrganizationGroupsCreateOutput {
90377
+ id: string;
90378
+ name: string;
90379
+ grants: {
90380
+ roleId: string;
90381
+ productId: string;
90382
+ }[];
90383
+ members: {
90384
+ userId: string;
90385
+ }[];
90386
+ createdAt: string;
90387
+ updatedAt: string;
90388
+ description: (string | null);
90389
+ organizationId: string;
90390
+ }
90391
+ export interface OrganizationGroupsDeleteInput {
90392
+ orgId: string;
90393
+ groupId: string;
90394
+ }
90395
+ export interface OrganizationGroupsDeleteOutput {
90396
+ [k: string]: unknown;
90397
+ }
90398
+ export interface OrganizationGroupsGetInput {
90399
+ orgId: string;
90400
+ groupId: string;
90401
+ }
90402
+ export interface OrganizationGroupsGetOutput {
90403
+ id: string;
90404
+ name: string;
90405
+ grants: {
90406
+ roleId: string;
90407
+ productId: string;
90408
+ }[];
90409
+ members: {
90410
+ userId: string;
90411
+ }[];
90412
+ createdAt: string;
90413
+ updatedAt: string;
90414
+ description: (string | null);
90415
+ organizationId: string;
90416
+ }
90417
+ export interface OrganizationGroupsGrantRemoveInput {
90418
+ orgId: string;
90419
+ groupId: string;
90420
+ productId: string;
90421
+ }
90422
+ export interface OrganizationGroupsGrantRemoveOutput {
90423
+ [k: string]: unknown;
90424
+ }
90425
+ export interface OrganizationGroupsGrantSetInput {
90426
+ orgId: string;
90427
+ roleId: string;
90428
+ groupId: string;
90429
+ productId: string;
90430
+ }
90431
+ export interface OrganizationGroupsGrantSetOutput {
90432
+ [k: string]: unknown;
90433
+ }
90434
+ export interface OrganizationGroupsListInput {
90435
+ orgId: string;
90436
+ }
90437
+ export interface OrganizationGroupsListOutput {
90438
+ groups: {
90439
+ id: string;
90440
+ name: string;
90441
+ grants: {
90442
+ roleId: string;
90443
+ productId: string;
90444
+ }[];
90445
+ members: {
90446
+ userId: string;
90447
+ }[];
90448
+ createdAt: string;
90449
+ updatedAt: string;
90450
+ description: (string | null);
90451
+ organizationId: string;
90452
+ }[];
90453
+ }
90454
+ export interface OrganizationGroupsMemberAddInput {
90455
+ orgId: string;
90456
+ userId: string;
90457
+ groupId: string;
90458
+ }
90459
+ export interface OrganizationGroupsMemberAddOutput {
90460
+ [k: string]: unknown;
90461
+ }
90462
+ export interface OrganizationGroupsMemberRemoveInput {
90463
+ orgId: string;
90464
+ userId: string;
90465
+ groupId: string;
90466
+ }
90467
+ export interface OrganizationGroupsMemberRemoveOutput {
90468
+ [k: string]: unknown;
90469
+ }
90470
+ export interface OrganizationGroupsUpdateInput {
90471
+ name?: string;
90472
+ orgId: string;
90473
+ groupId: string;
90474
+ description?: (string | null);
90475
+ }
90476
+ export interface OrganizationGroupsUpdateOutput {
90477
+ id: string;
90478
+ name: string;
90479
+ grants: {
90480
+ roleId: string;
90481
+ productId: string;
90482
+ }[];
90483
+ members: {
90484
+ userId: string;
90485
+ }[];
90486
+ createdAt: string;
90487
+ updatedAt: string;
90488
+ description: (string | null);
90489
+ organizationId: string;
90490
+ }
90491
+ export interface OrganizationLinkedinMemberInstallInput {
90492
+ }
90493
+ export interface OrganizationLinkedinMemberInstallOutput {
90494
+ url: string;
90495
+ }
90368
90496
  export interface OrganizationListInput {
90369
90497
  }
90370
90498
  export interface OrganizationListOutput {
@@ -90373,6 +90501,7 @@ export interface OrganizationListOutput {
90373
90501
  name: string;
90374
90502
  role: ("owner" | "admin" | "member");
90375
90503
  active: boolean;
90504
+ logoUrl: (string | null);
90376
90505
  blockedAt: (string | null);
90377
90506
  blockReason: (("no_subscription" | "under_review") | null);
90378
90507
  }[];
@@ -90470,21 +90599,28 @@ export interface OrganizationMemberListProductAccessOutput {
90470
90599
  role: string;
90471
90600
  slug: string;
90472
90601
  isCustom: boolean;
90602
+ viaGroup: ({
90603
+ id: string;
90604
+ name: string;
90605
+ } | null);
90473
90606
  expiresAt: (string | null);
90474
90607
  productId: string;
90475
90608
  sourceRole: ({
90476
90609
  id: string;
90477
90610
  name: string;
90478
90611
  } | null);
90612
+ viaGroupId: (string | null);
90479
90613
  grantSource: string;
90480
90614
  permissions: ({
90481
90615
  deny: string[];
90482
90616
  allow: string[];
90483
90617
  } | null);
90618
+ directGrantRole: (string | null);
90484
90619
  effectivePermissions: {
90485
90620
  deny: string[];
90486
90621
  allow: string[];
90487
90622
  };
90623
+ directGrantNotInForce: boolean;
90488
90624
  }[];
90489
90625
  }
90490
90626
  export interface OrganizationMemberRemoveInput {
@@ -90580,6 +90716,7 @@ export interface OrganizationProductCreateOutput {
90580
90716
  role: string;
90581
90717
  slug: string;
90582
90718
  demoAt: (string | null);
90719
+ region: string;
90583
90720
  status: string;
90584
90721
  logoUrl: (string | null);
90585
90722
  blockedAt: (string | null);
@@ -90597,6 +90734,7 @@ export interface OrganizationProductListOutput {
90597
90734
  role: string;
90598
90735
  slug: string;
90599
90736
  demoAt: (string | null);
90737
+ region: string;
90600
90738
  status: string;
90601
90739
  logoUrl: (string | null);
90602
90740
  blockedAt: (string | null);
@@ -90671,6 +90809,17 @@ export interface OrganizationProductListRolesOutput {
90671
90809
  productId: (string | null);
90672
90810
  }[];
90673
90811
  }
90812
+ export interface OrganizationProductMeInput {
90813
+ productId: string;
90814
+ }
90815
+ export interface OrganizationProductMeOutput {
90816
+ deny: string[];
90817
+ role: string;
90818
+ allow: string[];
90819
+ roleId: (string | null);
90820
+ roleName: (string | null);
90821
+ roleType: (("system" | "custom") | null);
90822
+ }
90674
90823
  export interface OrganizationProductRevokeAccessInput {
90675
90824
  userId: string;
90676
90825
  productId: string;
@@ -90708,6 +90857,7 @@ export interface OrganizationProductUpdateOutput {
90708
90857
  role: string;
90709
90858
  slug: string;
90710
90859
  demoAt: (string | null);
90860
+ region: string;
90711
90861
  status: string;
90712
90862
  logoUrl: (string | null);
90713
90863
  blockedAt: (string | null);
@@ -90812,6 +90962,11 @@ export interface OrganizationPublicRoutesListOutput {
90812
90962
  publicUrl: string;
90813
90963
  }[];
90814
90964
  }
90965
+ export interface OrganizationRedditInstallInput {
90966
+ }
90967
+ export interface OrganizationRedditInstallOutput {
90968
+ url: string;
90969
+ }
90815
90970
  export interface OrganizationRolesCreateInput {
90816
90971
  deny?: string[];
90817
90972
  name: string;
@@ -90905,6 +91060,7 @@ export interface OrganizationSupportThreadCreateInput {
90905
91060
  export interface OrganizationSupportThreadCreateOutput {
90906
91061
  id: string;
90907
91062
  title: string;
91063
+ legacy: boolean;
90908
91064
  status: string;
90909
91065
  category: ("open" | "pending" | "resolved" | "closed");
90910
91066
  messages: {
@@ -90917,6 +91073,7 @@ export interface OrganizationSupportThreadCreateOutput {
90917
91073
  createdAt: string;
90918
91074
  }[];
90919
91075
  createdAt: string;
91076
+ openedByName: string;
90920
91077
  lastMessageAt: string;
90921
91078
  lastMessagePreview: (string | null);
90922
91079
  }
@@ -90926,6 +91083,7 @@ export interface OrganizationSupportThreadGetInput {
90926
91083
  export interface OrganizationSupportThreadGetOutput {
90927
91084
  id: string;
90928
91085
  title: string;
91086
+ legacy: boolean;
90929
91087
  status: string;
90930
91088
  category: ("open" | "pending" | "resolved" | "closed");
90931
91089
  messages: {
@@ -90938,6 +91096,7 @@ export interface OrganizationSupportThreadGetOutput {
90938
91096
  createdAt: string;
90939
91097
  }[];
90940
91098
  createdAt: string;
91099
+ openedByName: string;
90941
91100
  lastMessageAt: string;
90942
91101
  lastMessagePreview: (string | null);
90943
91102
  }
@@ -90948,6 +91107,7 @@ export interface OrganizationSupportThreadReplyInput {
90948
91107
  export interface OrganizationSupportThreadReplyOutput {
90949
91108
  id: string;
90950
91109
  title: string;
91110
+ legacy: boolean;
90951
91111
  status: string;
90952
91112
  category: ("open" | "pending" | "resolved" | "closed");
90953
91113
  messages: {
@@ -90960,6 +91120,7 @@ export interface OrganizationSupportThreadReplyOutput {
90960
91120
  createdAt: string;
90961
91121
  }[];
90962
91122
  createdAt: string;
91123
+ openedByName: string;
90963
91124
  lastMessageAt: string;
90964
91125
  lastMessagePreview: (string | null);
90965
91126
  }
@@ -90969,13 +91130,216 @@ export interface OrganizationSupportThreadsListOutput {
90969
91130
  threads: {
90970
91131
  id: string;
90971
91132
  title: string;
91133
+ legacy: boolean;
90972
91134
  status: string;
90973
91135
  category: ("open" | "pending" | "resolved" | "closed");
90974
91136
  createdAt: string;
91137
+ openedByName: string;
90975
91138
  lastMessageAt: string;
90976
91139
  lastMessagePreview: (string | null);
90977
91140
  }[];
90978
91141
  }
91142
+ export interface OrganizationXInstallInput {
91143
+ }
91144
+ export interface OrganizationXInstallOutput {
91145
+ url: string;
91146
+ }
91147
+ export interface OrganizationYoutubeInstallInput {
91148
+ }
91149
+ export interface OrganizationYoutubeInstallOutput {
91150
+ url: string;
91151
+ }
91152
+ export interface PlaygroundAnalyticsOverviewInput {
91153
+ /**
91154
+ * Max records per entity in recent[]; omit for the endpoint default
91155
+ */
91156
+ limit?: number;
91157
+ }
91158
+ export interface PlaygroundAnalyticsOverviewOutput {
91159
+ ok: boolean;
91160
+ minted: boolean;
91161
+ overview?: unknown;
91162
+ http_status: number;
91163
+ }
91164
+ export interface PlaygroundBillingEntitlementsInput {
91165
+ }
91166
+ export interface PlaygroundBillingEntitlementsOutput {
91167
+ ok: boolean;
91168
+ minted: boolean;
91169
+ http_status: number;
91170
+ entitlements?: unknown;
91171
+ }
91172
+ export interface PlaygroundBillingRecordUsageInput {
91173
+ /**
91174
+ * Quantity of events to record against playground-events (SUM); defaults to 1
91175
+ */
91176
+ value?: number;
91177
+ }
91178
+ export interface PlaygroundBillingRecordUsageOutput {
91179
+ minted: boolean;
91180
+ accepted: (number | null);
91181
+ recorded: boolean;
91182
+ duplicates: (number | null);
91183
+ http_status: number;
91184
+ }
91185
+ export interface PlaygroundClickupCreateTaskInput {
91186
+ /**
91187
+ * Task title; defaults to a fixture label
91188
+ */
91189
+ name?: string;
91190
+ /**
91191
+ * ClickUp list id; falls back to CLICKUP_TEST_LIST_ID
91192
+ */
91193
+ listId?: string;
91194
+ }
91195
+ export interface PlaygroundClickupCreateTaskOutput {
91196
+ minted: boolean;
91197
+ task_id: (string | null);
91198
+ list_status: number;
91199
+ vend_status: number;
91200
+ clickup_status: number;
91201
+ installation_count: number;
91202
+ }
91203
+ export interface PlaygroundClickupGetLastWebhookInput {
91204
+ }
91205
+ export type PlaygroundClickupGetLastWebhookOutput = ({
91206
+ payload: string;
91207
+ event_id: string;
91208
+ provider: string;
91209
+ verified: boolean;
91210
+ product_id: string;
91211
+ occurred_at: string;
91212
+ connector_id: string;
91213
+ clickup_event: (string | null);
91214
+ receipt_count: number;
91215
+ } | {
91216
+ found: false;
91217
+ });
91218
+ export interface PlaygroundClickupGetOverviewInput {
91219
+ }
91220
+ export interface PlaygroundClickupGetOverviewOutput {
91221
+ team: ({
91222
+ teamId: string;
91223
+ teamName: string;
91224
+ } | null);
91225
+ lists: PlaygroundClickupGetOverviewOutputItems[];
91226
+ tasks: {
91227
+ id: string;
91228
+ name: string;
91229
+ status: (string | null);
91230
+ }[];
91231
+ minted: boolean;
91232
+ spaces: PlaygroundClickupGetOverviewOutputItems[];
91233
+ list_status: number;
91234
+ vend_status: number;
91235
+ lists_status: number;
91236
+ tasks_status: number;
91237
+ spaces_status: number;
91238
+ folders_status: number;
91239
+ installation_count: number;
91240
+ }
91241
+ export interface PlaygroundClickupGetOverviewOutputItems {
91242
+ id: string;
91243
+ name: string;
91244
+ }
91245
+ export interface PlaygroundGdriveGetLastChangeInput {
91246
+ }
91247
+ export type PlaygroundGdriveGetLastChangeOutput = ({
91248
+ file_id: string;
91249
+ removed: boolean;
91250
+ file_name: (string | null);
91251
+ mime_type: (string | null);
91252
+ product_id: string;
91253
+ occurred_at: string;
91254
+ connector_id: string;
91255
+ resource_state: string;
91256
+ } | {
91257
+ found: false;
91258
+ });
91259
+ export interface PlaygroundGdriveReadFileInput {
91260
+ /**
91261
+ * Drive file id; falls back to GDRIVE_TEST_FILE_ID, then the first picked file
91262
+ */
91263
+ fileId?: string;
91264
+ }
91265
+ export interface PlaygroundGdriveReadFileOutput {
91266
+ minted: boolean;
91267
+ file_id: (string | null);
91268
+ file_name: (string | null);
91269
+ mime_type: (string | null);
91270
+ file_count: number;
91271
+ get_status: number;
91272
+ list_status: number;
91273
+ vend_status: number;
91274
+ content_bytes: (number | null);
91275
+ }
91276
+ export interface PlaygroundGoogleadsReadCustomerInput {
91277
+ }
91278
+ export interface PlaygroundGoogleadsReadCustomerOutput {
91279
+ minted: boolean;
91280
+ vended: boolean;
91281
+ customer_id: (string | null);
91282
+ vend_status: number;
91283
+ result_count: number;
91284
+ search_status: number;
91285
+ login_customer_id: (string | null);
91286
+ }
91287
+ export interface PlaygroundLifecycleGetStateInput {
91288
+ }
91289
+ export interface PlaygroundLifecycleGetStateOutput {
91290
+ blocked: boolean;
91291
+ archived: boolean;
91292
+ productId: string;
91293
+ lastBlockTransition: ({
91294
+ eventId: string;
91295
+ eventName: string;
91296
+ productId: string;
91297
+ occurredAt: string;
91298
+ recordedAt: string;
91299
+ receiptCount: number;
91300
+ organizationId: string;
91301
+ cascadedFromOrg: boolean;
91302
+ } | null);
91303
+ lastArchiveTransition: ({
91304
+ eventId: string;
91305
+ eventName: string;
91306
+ productId: string;
91307
+ occurredAt: string;
91308
+ recordedAt: string;
91309
+ receiptCount: number;
91310
+ organizationId: string;
91311
+ cascadedFromOrg: boolean;
91312
+ } | null);
91313
+ }
91314
+ export interface PlaygroundLifecycleListEventsInput {
91315
+ }
91316
+ export type PlaygroundLifecycleListEventsOutput = {
91317
+ eventId: string;
91318
+ eventName: string;
91319
+ productId: string;
91320
+ occurredAt: string;
91321
+ recordedAt: string;
91322
+ receiptCount: number;
91323
+ organizationId: string;
91324
+ cascadedFromOrg: boolean;
91325
+ }[];
91326
+ export interface PlaygroundWebhookGetLastInput {
91327
+ }
91328
+ export type PlaygroundWebhookGetLastOutput = ({
91329
+ payload?: unknown;
91330
+ event_id: string;
91331
+ provider: string;
91332
+ verified: boolean;
91333
+ product_id: string;
91334
+ occurred_at: string;
91335
+ connector_id: string;
91336
+ delivery_count: number;
91337
+ } | {
91338
+ found: false;
91339
+ });
91340
+ export interface PlaygroundWsEchoInput {
91341
+ }
91342
+ export type PlaygroundWsEchoOutput = unknown;
90979
91343
  export interface RealtimeArchiveExportInput {
90980
91344
  /**
90981
91345
  * Only entries with ts <= to_ts (epoch ms)
@@ -2,6 +2,7 @@ export { createLesslyApp } from './runtime/createLesslyApp.js';
2
2
  export type { LesslyClientBase } from './runtime/createLesslyApp.js';
3
3
  export { connectStream } from './runtime/connectStream.js';
4
4
  export { LesslyApiError, isAccessDenied } from './runtime/errors.js';
5
+ export { accessReason } from './runtime/access-reason.js';
5
6
  export type { LesslyAppOptions, HttpMethod, Binding, BindingsMap, ParamSpec, ParamIn, ToolLevel, Operation, } from './runtime/types.js';
6
7
  export type { WsBinding, WsBindingsMap, LesslyStream, LesslyStreamOpener, StreamCloseInfo, StreamData, WebSocketCtor, WebSocketLike, } from './runtime/types.js';
7
8
  export type { Access, AccessState, AccessApi } from './runtime/access.js';
@@ -0,0 +1,20 @@
1
+ import type { Operation } from './types.js';
2
+ /**
3
+ * The one reason string every App shows on a gated control (APP-012).
4
+ *
5
+ * Both values come from the generated method, so the sentence cannot drift when the catalog
6
+ * re-levels a tool. It names the operation key as well as the level because a level alone does not
7
+ * identify a grant — a screenful of controls can all require `write` — and an admin grants by
8
+ * level AND by exact key, so the user has to be able to pass on both.
9
+ *
10
+ * It explains ONE operation. Picking which one — the first that `can()` denied, among the several
11
+ * a button performs — is the caller's job: the rule differs between a button that runs every
12
+ * operation and one that dispatches to a single one, so this takes no array.
13
+ *
14
+ * A bare key is the fallback for a control with no generated method to point at (a runtime probe,
15
+ * an operation no method covers). It drops the level rather than inventing one: there is nothing
16
+ * to read it from, and `level:undefined` in front of a user is worse than saying less. It is a
17
+ * DEGRADATION, not an equal input — an App whose every gate holds an `Operation` never reaches for
18
+ * it, and that is the normal shape, not an omission.
19
+ */
20
+ export declare function accessReason(op: Operation | string): string;