@kindgi/api 0.1.3 → 0.1.4-rc.1

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 (222) hide show
  1. package/dist/agent-binding.d.ts +26 -4
  2. package/dist/agent-binding.d.ts.map +1 -1
  3. package/dist/agent-pins.d.ts +48 -0
  4. package/dist/agent-pins.d.ts.map +1 -0
  5. package/dist/agent-pins.js +102 -0
  6. package/dist/agent-pins.js.map +1 -0
  7. package/dist/app.d.ts +22 -0
  8. package/dist/app.d.ts.map +1 -1
  9. package/dist/app.js +27 -3
  10. package/dist/app.js.map +1 -1
  11. package/dist/block-binding.d.ts +132 -0
  12. package/dist/block-binding.d.ts.map +1 -0
  13. package/dist/block-binding.js +4 -0
  14. package/dist/block-binding.js.map +1 -0
  15. package/dist/block-pins.d.ts +22 -0
  16. package/dist/block-pins.d.ts.map +1 -0
  17. package/dist/block-pins.js +112 -0
  18. package/dist/block-pins.js.map +1 -0
  19. package/dist/cost-binding.d.ts +20 -1
  20. package/dist/cost-binding.d.ts.map +1 -1
  21. package/dist/cost-binding.js +4 -0
  22. package/dist/cost-binding.js.map +1 -1
  23. package/dist/deploy-versions.d.ts +60 -0
  24. package/dist/deploy-versions.d.ts.map +1 -0
  25. package/dist/deploy-versions.js +91 -0
  26. package/dist/deploy-versions.js.map +1 -0
  27. package/dist/deployment-binding.d.ts +24 -3
  28. package/dist/deployment-binding.d.ts.map +1 -1
  29. package/dist/derive-agent-version.d.ts +77 -0
  30. package/dist/derive-agent-version.d.ts.map +1 -0
  31. package/dist/derive-agent-version.js +149 -0
  32. package/dist/derive-agent-version.js.map +1 -0
  33. package/dist/errors.d.ts.map +1 -1
  34. package/dist/errors.js +18 -0
  35. package/dist/errors.js.map +1 -1
  36. package/dist/eval-case-binding.d.ts +65 -0
  37. package/dist/eval-case-binding.d.ts.map +1 -0
  38. package/dist/eval-case-binding.js +4 -0
  39. package/dist/eval-case-binding.js.map +1 -0
  40. package/dist/eval-run-binding.d.ts +37 -0
  41. package/dist/eval-run-binding.d.ts.map +1 -1
  42. package/dist/eval-run-binding.js.map +1 -1
  43. package/dist/eval-run-dispatcher.d.ts +41 -3
  44. package/dist/eval-run-dispatcher.d.ts.map +1 -1
  45. package/dist/eval-run-dispatcher.js +21 -15
  46. package/dist/eval-run-dispatcher.js.map +1 -1
  47. package/dist/eval-suite-binding.d.ts +1 -1
  48. package/dist/eval-suite-binding.d.ts.map +1 -1
  49. package/dist/eval-suite-binding.js +2 -0
  50. package/dist/eval-suite-binding.js.map +1 -1
  51. package/dist/flow-binding.d.ts +18 -4
  52. package/dist/flow-binding.d.ts.map +1 -1
  53. package/dist/flow-pins.d.ts +36 -0
  54. package/dist/flow-pins.d.ts.map +1 -0
  55. package/dist/flow-pins.js +81 -0
  56. package/dist/flow-pins.js.map +1 -0
  57. package/dist/guardrail-binding.d.ts +8 -0
  58. package/dist/guardrail-binding.d.ts.map +1 -1
  59. package/dist/handler-binding.d.ts +3 -0
  60. package/dist/handler-binding.d.ts.map +1 -1
  61. package/dist/index.d.ts +18 -6
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +8 -2
  64. package/dist/index.js.map +1 -1
  65. package/dist/judged-dispatcher.d.ts +138 -0
  66. package/dist/judged-dispatcher.d.ts.map +1 -0
  67. package/dist/judged-dispatcher.js +308 -0
  68. package/dist/judged-dispatcher.js.map +1 -0
  69. package/dist/judged-items.d.ts +86 -0
  70. package/dist/judged-items.d.ts.map +1 -0
  71. package/dist/judged-items.js +184 -0
  72. package/dist/judged-items.js.map +1 -0
  73. package/dist/judgment-binding.d.ts +316 -0
  74. package/dist/judgment-binding.d.ts.map +1 -0
  75. package/dist/judgment-binding.js +19 -0
  76. package/dist/judgment-binding.js.map +1 -0
  77. package/dist/openapi/generate.d.ts.map +1 -1
  78. package/dist/openapi/generate.js +4 -1
  79. package/dist/openapi/generate.js.map +1 -1
  80. package/dist/openapi/operations.d.ts.map +1 -1
  81. package/dist/openapi/operations.js +482 -13
  82. package/dist/openapi/operations.js.map +1 -1
  83. package/dist/openapi/schemas.d.ts +46 -0
  84. package/dist/openapi/schemas.d.ts.map +1 -1
  85. package/dist/openapi/schemas.js +1350 -175
  86. package/dist/openapi/schemas.js.map +1 -1
  87. package/dist/provider-binding.d.ts +12 -7
  88. package/dist/provider-binding.d.ts.map +1 -1
  89. package/dist/registry-read-only.d.ts +32 -0
  90. package/dist/registry-read-only.d.ts.map +1 -0
  91. package/dist/registry-read-only.js +22 -0
  92. package/dist/registry-read-only.js.map +1 -0
  93. package/dist/routes/agents.d.ts +9 -1
  94. package/dist/routes/agents.d.ts.map +1 -1
  95. package/dist/routes/agents.js +181 -11
  96. package/dist/routes/agents.js.map +1 -1
  97. package/dist/routes/blocks.d.ts +19 -0
  98. package/dist/routes/blocks.d.ts.map +1 -0
  99. package/dist/routes/blocks.js +306 -0
  100. package/dist/routes/blocks.js.map +1 -0
  101. package/dist/routes/cost.d.ts.map +1 -1
  102. package/dist/routes/cost.js +47 -2
  103. package/dist/routes/cost.js.map +1 -1
  104. package/dist/routes/deployments.d.ts +3 -0
  105. package/dist/routes/deployments.d.ts.map +1 -1
  106. package/dist/routes/deployments.js +224 -55
  107. package/dist/routes/deployments.js.map +1 -1
  108. package/dist/routes/eval-comparison.d.ts +15 -0
  109. package/dist/routes/eval-comparison.d.ts.map +1 -0
  110. package/dist/routes/eval-comparison.js +123 -0
  111. package/dist/routes/eval-comparison.js.map +1 -0
  112. package/dist/routes/eval-runs.d.ts +7 -1
  113. package/dist/routes/eval-runs.d.ts.map +1 -1
  114. package/dist/routes/eval-runs.js +42 -3
  115. package/dist/routes/eval-runs.js.map +1 -1
  116. package/dist/routes/eval-versions.d.ts +25 -0
  117. package/dist/routes/eval-versions.d.ts.map +1 -0
  118. package/dist/routes/eval-versions.js +66 -0
  119. package/dist/routes/eval-versions.js.map +1 -0
  120. package/dist/routes/flows.d.ts +13 -1
  121. package/dist/routes/flows.d.ts.map +1 -1
  122. package/dist/routes/flows.js +48 -3
  123. package/dist/routes/flows.js.map +1 -1
  124. package/dist/routes/guardrails.d.ts.map +1 -1
  125. package/dist/routes/guardrails.js +4 -0
  126. package/dist/routes/guardrails.js.map +1 -1
  127. package/dist/routes/hierarchy-errors.d.ts +45 -0
  128. package/dist/routes/hierarchy-errors.d.ts.map +1 -0
  129. package/dist/routes/hierarchy-errors.js +47 -0
  130. package/dist/routes/hierarchy-errors.js.map +1 -0
  131. package/dist/routes/judged-suites.d.ts +20 -0
  132. package/dist/routes/judged-suites.d.ts.map +1 -0
  133. package/dist/routes/judged-suites.js +272 -0
  134. package/dist/routes/judged-suites.js.map +1 -0
  135. package/dist/routes/judgment-context.d.ts +22 -0
  136. package/dist/routes/judgment-context.d.ts.map +1 -0
  137. package/dist/routes/judgment-context.js +88 -0
  138. package/dist/routes/judgment-context.js.map +1 -0
  139. package/dist/routes/judgment-flow-context.d.ts +32 -0
  140. package/dist/routes/judgment-flow-context.d.ts.map +1 -0
  141. package/dist/routes/judgment-flow-context.js +195 -0
  142. package/dist/routes/judgment-flow-context.js.map +1 -0
  143. package/dist/routes/judgments.d.ts +41 -0
  144. package/dist/routes/judgments.d.ts.map +1 -0
  145. package/dist/routes/judgments.js +566 -0
  146. package/dist/routes/judgments.js.map +1 -0
  147. package/dist/routes/orgs.d.ts +5 -2
  148. package/dist/routes/orgs.d.ts.map +1 -1
  149. package/dist/routes/orgs.js +38 -22
  150. package/dist/routes/orgs.js.map +1 -1
  151. package/dist/routes/policies.d.ts.map +1 -1
  152. package/dist/routes/policies.js +12 -1
  153. package/dist/routes/policies.js.map +1 -1
  154. package/dist/routes/projects.d.ts +10 -2
  155. package/dist/routes/projects.d.ts.map +1 -1
  156. package/dist/routes/projects.js +94 -80
  157. package/dist/routes/projects.js.map +1 -1
  158. package/dist/routes/providers.d.ts.map +1 -1
  159. package/dist/routes/providers.js +6 -1
  160. package/dist/routes/providers.js.map +1 -1
  161. package/dist/routes/runs.js +25 -3
  162. package/dist/routes/runs.js.map +1 -1
  163. package/dist/routes/teams.d.ts +6 -2
  164. package/dist/routes/teams.d.ts.map +1 -1
  165. package/dist/routes/teams.js +83 -73
  166. package/dist/routes/teams.js.map +1 -1
  167. package/dist/routes/tools.d.ts.map +1 -1
  168. package/dist/routes/tools.js +4 -0
  169. package/dist/routes/tools.js.map +1 -1
  170. package/dist/tool-binding.d.ts +8 -0
  171. package/dist/tool-binding.d.ts.map +1 -1
  172. package/openapi.json +14253 -10099
  173. package/package.json +21 -21
  174. package/src/agent-binding.ts +28 -4
  175. package/src/agent-pins.ts +147 -0
  176. package/src/app.ts +81 -3
  177. package/src/block-binding.ts +137 -0
  178. package/src/block-pins.ts +148 -0
  179. package/src/cost-binding.ts +21 -1
  180. package/src/deploy-versions.ts +157 -0
  181. package/src/deployment-binding.ts +27 -3
  182. package/src/derive-agent-version.ts +217 -0
  183. package/src/errors.ts +18 -0
  184. package/src/eval-case-binding.ts +71 -0
  185. package/src/eval-run-binding.ts +40 -0
  186. package/src/eval-run-dispatcher.ts +60 -16
  187. package/src/eval-suite-binding.ts +2 -0
  188. package/src/flow-binding.ts +20 -4
  189. package/src/flow-pins.ts +113 -0
  190. package/src/guardrail-binding.ts +9 -0
  191. package/src/handler-binding.ts +3 -0
  192. package/src/index.ts +86 -2
  193. package/src/judged-dispatcher.ts +530 -0
  194. package/src/judged-items.ts +263 -0
  195. package/src/judgment-binding.ts +349 -0
  196. package/src/openapi/generate.ts +7 -1
  197. package/src/openapi/operations.ts +579 -13
  198. package/src/openapi/schemas.ts +1408 -128
  199. package/src/provider-binding.ts +12 -7
  200. package/src/registry-read-only.ts +43 -0
  201. package/src/routes/agents.ts +252 -19
  202. package/src/routes/blocks.ts +387 -0
  203. package/src/routes/cost.ts +55 -1
  204. package/src/routes/deployments.ts +291 -56
  205. package/src/routes/eval-comparison.ts +135 -0
  206. package/src/routes/eval-runs.ts +57 -3
  207. package/src/routes/eval-versions.ts +110 -0
  208. package/src/routes/flows.ts +70 -5
  209. package/src/routes/guardrails.ts +7 -0
  210. package/src/routes/hierarchy-errors.ts +60 -0
  211. package/src/routes/judged-suites.ts +363 -0
  212. package/src/routes/judgment-context.ts +128 -0
  213. package/src/routes/judgment-flow-context.ts +245 -0
  214. package/src/routes/judgments.ts +743 -0
  215. package/src/routes/orgs.ts +44 -27
  216. package/src/routes/policies.ts +19 -0
  217. package/src/routes/projects.ts +118 -96
  218. package/src/routes/providers.ts +5 -0
  219. package/src/routes/runs.ts +29 -3
  220. package/src/routes/teams.ts +104 -90
  221. package/src/routes/tools.ts +7 -0
  222. package/src/tool-binding.ts +9 -0
@@ -19,6 +19,7 @@ import type { Cursor, OrgId, TeamId, TenantId, UserId } from '@kindgi/types';
19
19
  import { statusFor, toWireError } from '../errors.js';
20
20
  import type { Authorizer } from '../middleware/authorize.js';
21
21
  import type { AppEnv } from '../types.js';
22
+ import { orgNotFoundError, slugConflictError } from './hierarchy-errors.js';
22
23
  import { clampLimit } from './pagination.js';
23
24
 
24
25
  /**
@@ -29,9 +30,13 @@ import { clampLimit } from './pagination.js';
29
30
  * `?limit=` / `?cursor=` / `?orgId=` /
30
31
  * `?nameContains=`.
31
32
  * - `POST /` — create; body `{ name, slug,
32
- * description?, orgId? }`; 201 `{ id }`.
33
+ * description?, orgId? }`; 201 `{ id }`;
34
+ * 409 `slug-conflict` when the tenant
35
+ * has a team with that slug.
33
36
  * - `GET /:teamId` — get; 200 or 404 `team-not-found`.
34
- * - `PATCH /:teamId` — partial update; 204 or 404.
37
+ * - `PATCH /:teamId` — partial update; 204, 404
38
+ * `team-not-found` or 409
39
+ * `slug-conflict`.
35
40
  * - `DELETE /:teamId` — 204 idempotent.
36
41
  * - `GET /:teamId/memberships` — list; cursor-paginated.
37
42
  * - `POST /:teamId/memberships` — add member; body `{ userId, role }`;
@@ -193,17 +198,29 @@ export function teamsRouter(
193
198
  : ('00000000-0000-0000-0000-000000000000' as UserId);
194
199
  const result = await tenantHierarchy.createTeam({ tenantId, creatorUserId, spec });
195
200
  if (result.kind === 'err') {
196
- const code =
197
- result.error.code === 'slug-conflict' ? 'slug-conflict' : 'internal-server-error';
198
- c.status(statusFor(code) as never);
199
- return c.json(toWireError({ code, message: result.error.message }, requestId));
201
+ const error =
202
+ result.error.code === 'slug-conflict'
203
+ ? slugConflictError('team', spec.slug)
204
+ : result.error.code === 'org-not-found'
205
+ ? orgNotFoundError(result.error.orgId as unknown as string)
206
+ : { code: 'internal-server-error', message: result.error.message };
207
+ c.status(statusFor(error.code) as never);
208
+ return c.json(toWireError(error, requestId));
200
209
  }
201
210
  c.status(201);
202
211
  return c.json({ id: result.value.teamId as unknown as string });
203
212
  }
204
- const id = await binding.create(tenantId, spec);
213
+ const outcome = await binding.create(tenantId, spec);
214
+ if (outcome.kind === 'slug-conflict' || outcome.kind === 'org-not-found') {
215
+ const error =
216
+ outcome.kind === 'slug-conflict'
217
+ ? slugConflictError('team', outcome.slug)
218
+ : orgNotFoundError(outcome.orgId as unknown as string);
219
+ c.status(statusFor(error.code) as never);
220
+ return c.json(toWireError(error, requestId));
221
+ }
205
222
  c.status(201);
206
- return c.json({ id: id as unknown as string });
223
+ return c.json({ id: outcome.teamId as unknown as string });
207
224
  });
208
225
 
209
226
  // ---------- GET /:teamId/memberships ----------
@@ -300,39 +317,38 @@ export function teamsRouter(
300
317
  ),
301
318
  );
302
319
  }
303
- try {
304
- if (authorizer !== undefined) {
305
- const res = await tenantHierarchy.addTeamMember({
306
- tenantId,
307
- teamId,
308
- userId: b.userId as unknown as UserId,
309
- role: b.role as TeamRole,
310
- });
311
- if (res.kind === 'err') throw new Error(res.error.message);
312
- } else {
313
- await membershipBinding.add(tenantId, {
314
- teamId,
315
- userId: b.userId as unknown as UserId,
316
- role: b.role,
317
- });
318
- }
319
- } catch (cause) {
320
- const message = cause instanceof Error ? cause.message : String(cause);
321
- if (message.startsWith('team-not-found')) {
322
- // Racy — team was deleted between the preliminary get and the add.
323
- c.status(statusFor('team-not-found') as never);
324
- return c.json(
325
- toWireError(
326
- {
327
- code: 'team-not-found',
328
- message: `No team with id "${teamId as unknown as string}"`,
329
- teamId: teamId as unknown as string,
330
- },
331
- requestId,
332
- ),
333
- );
320
+ // Racy — the team can be deleted between the preliminary get and the add.
321
+ const teamGone = () => {
322
+ c.status(statusFor('team-not-found') as never);
323
+ return c.json(
324
+ toWireError(
325
+ {
326
+ code: 'team-not-found',
327
+ message: `No team with id "${teamId as unknown as string}"`,
328
+ teamId: teamId as unknown as string,
329
+ },
330
+ requestId,
331
+ ),
332
+ );
333
+ };
334
+ if (authorizer !== undefined) {
335
+ const res = await tenantHierarchy.addTeamMember({
336
+ tenantId,
337
+ teamId,
338
+ userId: b.userId as unknown as UserId,
339
+ role: b.role as TeamRole,
340
+ });
341
+ if (res.kind === 'err') {
342
+ if (res.error.code === 'team-not-found') return teamGone();
343
+ throw new Error(res.error.message, { cause: res.error });
334
344
  }
335
- throw cause;
345
+ } else {
346
+ const outcome = await membershipBinding.add(tenantId, {
347
+ teamId,
348
+ userId: b.userId as unknown as UserId,
349
+ role: b.role,
350
+ });
351
+ if (outcome.kind === 'team-not-found') return teamGone();
336
352
  }
337
353
  c.status(201);
338
354
  return c.json({
@@ -387,38 +403,33 @@ export function teamsRouter(
387
403
  ),
388
404
  );
389
405
  }
390
- try {
391
- await membershipBinding.updateRole(tenantId, teamId, userId, b.role);
392
- } catch (cause) {
393
- const message = cause instanceof Error ? cause.message : String(cause);
394
- if (message.startsWith('team-membership-not-found')) {
395
- c.status(statusFor('team-membership-not-found') as never);
396
- return c.json(
397
- toWireError(
398
- {
399
- code: 'team-membership-not-found',
400
- message: `No membership for team "${teamId as unknown as string}" + user "${userId as unknown as string}"`,
401
- teamId: teamId as unknown as string,
402
- userId: userId as unknown as string,
403
- },
404
- requestId,
405
- ),
406
- );
407
- }
408
- if (message.startsWith('team-not-found')) {
409
- c.status(statusFor('team-not-found') as never);
410
- return c.json(
411
- toWireError(
412
- {
413
- code: 'team-not-found',
414
- message: `No team with id "${teamId as unknown as string}"`,
415
- teamId: teamId as unknown as string,
416
- },
417
- requestId,
418
- ),
419
- );
420
- }
421
- throw cause;
406
+ const outcome = await membershipBinding.updateRole(tenantId, teamId, userId, b.role);
407
+ if (outcome.kind === 'team-membership-not-found') {
408
+ c.status(statusFor('team-membership-not-found') as never);
409
+ return c.json(
410
+ toWireError(
411
+ {
412
+ code: 'team-membership-not-found',
413
+ message: `No membership for team "${teamId as unknown as string}" + user "${userId as unknown as string}"`,
414
+ teamId: teamId as unknown as string,
415
+ userId: userId as unknown as string,
416
+ },
417
+ requestId,
418
+ ),
419
+ );
420
+ }
421
+ if (outcome.kind === 'team-not-found') {
422
+ c.status(statusFor('team-not-found') as never);
423
+ return c.json(
424
+ toWireError(
425
+ {
426
+ code: 'team-not-found',
427
+ message: `No team with id "${teamId as unknown as string}"`,
428
+ teamId: teamId as unknown as string,
429
+ },
430
+ requestId,
431
+ ),
432
+ );
422
433
  }
423
434
  c.status(204);
424
435
  return c.body(null);
@@ -522,24 +533,27 @@ export function teamsRouter(
522
533
  );
523
534
  }
524
535
  }
525
- try {
526
- await binding.update(tenantId, teamId, shaped);
527
- } catch (cause) {
528
- const message = cause instanceof Error ? cause.message : String(cause);
529
- if (message.startsWith('team-not-found')) {
530
- c.status(statusFor('team-not-found') as never);
531
- return c.json(
532
- toWireError(
533
- {
534
- code: 'team-not-found',
535
- message: `No team with id "${teamId as unknown as string}"`,
536
- teamId: teamId as unknown as string,
537
- },
538
- requestId,
539
- ),
540
- );
541
- }
542
- throw cause;
536
+ const outcome = await binding.update(tenantId, teamId, shaped);
537
+ if (outcome.kind === 'team-not-found') {
538
+ c.status(statusFor('team-not-found') as never);
539
+ return c.json(
540
+ toWireError(
541
+ {
542
+ code: 'team-not-found',
543
+ message: `No team with id "${teamId as unknown as string}"`,
544
+ teamId: teamId as unknown as string,
545
+ },
546
+ requestId,
547
+ ),
548
+ );
549
+ }
550
+ if (outcome.kind === 'slug-conflict' || outcome.kind === 'org-not-found') {
551
+ const error =
552
+ outcome.kind === 'slug-conflict'
553
+ ? slugConflictError('team', outcome.slug)
554
+ : orgNotFoundError(outcome.orgId as unknown as string);
555
+ c.status(statusFor(error.code) as never);
556
+ return c.json(toWireError(error, requestId));
543
557
  }
544
558
  c.status(204);
545
559
  return c.body(null);
@@ -9,6 +9,7 @@ import type { Cursor, ProjectId, TenantId, ToolId, UserId } from '@kindgi/types'
9
9
 
10
10
  import { statusFor, toWireError } from '../errors.js';
11
11
  import type { Authorizer } from '../middleware/authorize.js';
12
+ import { refuseWritesWhenReadOnly } from '../registry-read-only.js';
12
13
  import type { ToolRegistryBinding } from '../tool-binding.js';
13
14
  import type { AppEnv } from '../types.js';
14
15
  import { clampLimit } from './pagination.js';
@@ -47,6 +48,12 @@ export function toolsRouter(
47
48
  onWrite?: ToolWriteHook,
48
49
  ): Hono<AppEnv> {
49
50
  const r = new Hono<AppEnv>();
51
+ // A read-only registry (under `kindgi dev`, the pack's files) refuses
52
+ // every write before anything else runs.
53
+ r.use(
54
+ '*',
55
+ refuseWritesWhenReadOnly(() => binding.readOnly),
56
+ );
50
57
 
51
58
  // Authorization (PEP) — mirrors agents. Cascade via `tool#parent@project`
52
59
  // written in-tx by publish; direct check via `ref('tool', businessId)`.
@@ -6,6 +6,8 @@ import type { Scope } from '@kindgi/platform';
6
6
  import type { ToolManifest } from '@kindgi/tools';
7
7
  import type { Cursor, ProjectId, Semver, TenantId, ToolId } from '@kindgi/types';
8
8
 
9
+ import type { RegistryReadOnly } from './registry-read-only.js';
10
+
9
11
  /**
10
12
  * Caller-plugged surface for the tool catalog. Versioned CRUD mirroring
11
13
  * `AgentRegistryBinding` — the API package does NOT own registry
@@ -30,6 +32,13 @@ import type { Cursor, ProjectId, Semver, TenantId, ToolId } from '@kindgi/types'
30
32
  * not-found via `headExists`).
31
33
  */
32
34
  export interface ToolRegistryBinding {
35
+ /**
36
+ * Set when this registry takes no writes (under `kindgi dev`, the
37
+ * pack's files are the source of its tools): every write is refused
38
+ * with `409 registry-read-only` and this reason, before the binding is
39
+ * called. See `RegistryReadOnly`.
40
+ */
41
+ readonly readOnly?: RegistryReadOnly;
33
42
  /**
34
43
  * Cursor-paginated list of tools (latest active version per id).
35
44
  * Optional `nameFilter` is a prefix match on the tool id — tools use