mirab 0.0.0 → 0.2.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 (106) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +223 -3
  3. package/package.json +56 -7
  4. package/src/agent/approved.ts +261 -0
  5. package/src/agent/define.ts +235 -0
  6. package/src/agent/guest.ts +138 -0
  7. package/src/agent/init.ts +150 -0
  8. package/src/agent/manifest.ts +141 -0
  9. package/src/agent/modules.ts +23 -0
  10. package/src/agent/runtime.ts +239 -0
  11. package/src/agent-profiles.ts +327 -0
  12. package/src/api/bootstrap-contract.ts +95 -0
  13. package/src/api/channel-contract.ts +19 -0
  14. package/src/api/client.ts +100 -0
  15. package/src/api/contract.ts +2454 -0
  16. package/src/api/events-contract.ts +103 -0
  17. package/src/api/import-contract.ts +22 -0
  18. package/src/api/orchestrator-contract.ts +73 -0
  19. package/src/api/runner-contract.ts +25 -0
  20. package/src/api/scopes.ts +41 -0
  21. package/src/api/sessions-contract.ts +71 -0
  22. package/src/api/settings-contract.ts +50 -0
  23. package/src/channel/bridge.ts +97 -0
  24. package/src/channel/local.ts +154 -0
  25. package/src/channel/state.ts +11 -0
  26. package/src/channel/wire.ts +104 -0
  27. package/src/dev-sync.ts +206 -0
  28. package/src/dev.ts +453 -0
  29. package/src/events-tail.ts +75 -0
  30. package/src/images.ts +498 -0
  31. package/src/index.ts +21 -0
  32. package/src/invocation.ts +34 -0
  33. package/src/isolation/anchored-fs.ts +284 -0
  34. package/src/isolation/colima.ts +159 -0
  35. package/src/isolation/container.ts +189 -0
  36. package/src/isolation/firecracker.ts +414 -0
  37. package/src/isolation/guest-protocol.json +1 -0
  38. package/src/isolation/host-user.ts +247 -0
  39. package/src/isolation/image.ts +336 -0
  40. package/src/isolation/index.ts +477 -0
  41. package/src/isolation/multipass.ts +541 -0
  42. package/src/isolation/network.ts +167 -0
  43. package/src/isolation/policy.ts +86 -0
  44. package/src/isolation/session.ts +385 -0
  45. package/src/isolation/sync.ts +329 -0
  46. package/src/isolation/vz-network-setup.ts +247 -0
  47. package/src/isolation/vz.ts +312 -0
  48. package/src/mirab-main.ts +536 -0
  49. package/src/mirab.ts +13 -0
  50. package/src/runner/define.ts +187 -0
  51. package/src/runner/image.ts +239 -0
  52. package/src/runner/index.ts +37 -0
  53. package/src/runner/serve.ts +491 -0
  54. package/src/runner/toolsets.ts +205 -0
  55. package/src/spawn-adapters/claude.ts +112 -0
  56. package/src/spawn-adapters/codex-logs.ts +130 -0
  57. package/src/spawn-adapters/codex-notify.ts +73 -0
  58. package/src/spawn-adapters/codex.ts +89 -0
  59. package/src/spawn-adapters/index.ts +40 -0
  60. package/src/spawn-adapters/types.ts +55 -0
  61. package/src/spawn-attach.ts +243 -0
  62. package/src/spawn-binary.ts +90 -0
  63. package/src/spawn-bridge.ts +504 -0
  64. package/src/spawn-bundle.ts +16 -0
  65. package/src/spawn-detach.ts +301 -0
  66. package/src/spawn-events.ts +35 -0
  67. package/src/spawn-hook.ts +86 -0
  68. package/src/spawn-input.ts +107 -0
  69. package/src/spawn-native.ts +49 -0
  70. package/src/spawn-nudge-worker.ts +61 -0
  71. package/src/spawn-nudge.ts +446 -0
  72. package/src/spawn-output.ts +45 -0
  73. package/src/spawn-queue.ts +135 -0
  74. package/src/spawn-quiet.ts +69 -0
  75. package/src/spawn-report.ts +114 -0
  76. package/src/spawn-sessions.ts +166 -0
  77. package/src/spawn-vm.ts +356 -0
  78. package/src/spawn-worker.ts +766 -0
  79. package/src/spawn.ts +468 -0
  80. package/src/station/config.ts +89 -0
  81. package/src/station/gateway.ts +94 -0
  82. package/src/station/vault.ts +96 -0
  83. package/src/test-cli.ts +90 -0
  84. package/src/tools.ts +3 -0
  85. package/types/agent/define.d.ts +76 -0
  86. package/types/agent/manifest.d.ts +53 -0
  87. package/types/agent/modules.d.ts +1 -0
  88. package/types/images.d.ts +124 -0
  89. package/types/index.d.ts +6 -0
  90. package/types/isolation/colima.d.ts +37 -0
  91. package/types/isolation/container.d.ts +25 -0
  92. package/types/isolation/firecracker.d.ts +55 -0
  93. package/types/isolation/host-user.d.ts +47 -0
  94. package/types/isolation/image.d.ts +158 -0
  95. package/types/isolation/index.d.ts +128 -0
  96. package/types/isolation/network.d.ts +33 -0
  97. package/types/isolation/policy.d.ts +29 -0
  98. package/types/isolation/session.d.ts +99 -0
  99. package/types/isolation/vz.d.ts +63 -0
  100. package/types/runner/define.d.ts +101 -0
  101. package/types/runner/image.d.ts +52 -0
  102. package/types/runner/index.d.ts +13 -0
  103. package/types/runner/serve.d.ts +69 -0
  104. package/types/runner/toolsets.d.ts +35 -0
  105. package/types/tools.d.ts +2 -0
  106. package/index.js +0 -1
@@ -0,0 +1,2454 @@
1
+ // Generated by gild-site/scripts/generate-api-client.mjs. Edit the site source.
2
+ import { channelMessage, channelPage, channelInput, channelQuery, channelParticipants, channelCursor } from './channel-contract.ts'
3
+ import { orchestratorList, orchestratorGrant, orchestratorInput, orchestratorRevoked, childInput, childAgent, spawnedChild, suspension } from './orchestrator-contract.ts'
4
+ import { importInput, importSummary, importStatus, importAssignment, importCredentials, importProgress, importBatch } from './import-contract.ts'
5
+ import {
6
+ runnerRegistration,
7
+ runnerGroup,
8
+ groupInput,
9
+ } from './runner-contract.ts'
10
+ import {
11
+ renameStatus,
12
+ profileSchema,
13
+ profileInput,
14
+ } from './settings-contract.ts'
15
+ import { sessionInput, receiptSchema } from './sessions-contract.ts'
16
+ import {
17
+ hookInput,
18
+ hookPatch,
19
+ hookSchema,
20
+ deliverySchema,
21
+ eventPage,
22
+ } from './events-contract.ts'
23
+ // Canonical API contract. Runtime validation, wiring, docs, OpenAPI and the
24
+ // generated CLI client consume these definitions; do not maintain route lists.
25
+ import { z } from 'zod'
26
+ import { SCOPES, type Scope } from './scopes.ts'
27
+ const text = z.string(),
28
+ integer = z.number().int(),
29
+ sha = text.regex(/^[a-f0-9]{40}$/),
30
+ url = text
31
+ const user = z.object({
32
+ login: text,
33
+ id: integer,
34
+ type: z.enum(['User', 'Organization', 'Bot']),
35
+ html_url: url,
36
+ })
37
+ const label = z.object({
38
+ id: integer,
39
+ name: text,
40
+ color: text,
41
+ description: text.nullable(),
42
+ })
43
+ const repository = z.object({
44
+ id: integer,
45
+ name: text,
46
+ full_name: text,
47
+ owner: user,
48
+ private: z.boolean(),
49
+ stargazers_count: integer.nonnegative(),
50
+ description: text.nullable(),
51
+ default_branch: text,
52
+ html_url: url,
53
+ url,
54
+ clone_url: url,
55
+ created_at: text,
56
+ updated_at: text,
57
+ })
58
+ const comment = z.object({
59
+ id: integer,
60
+ node_id: text,
61
+ user,
62
+ body: text,
63
+ created_at: text,
64
+ updated_at: text,
65
+ html_url: url,
66
+ url,
67
+ })
68
+ const issue = z.object({
69
+ id: integer,
70
+ number: integer,
71
+ title: text,
72
+ body: text,
73
+ user,
74
+ state: z.enum(['open', 'closed']),
75
+ labels: z.array(label),
76
+ comments: integer,
77
+ created_at: text,
78
+ updated_at: text,
79
+ closed_at: text.nullable(),
80
+ html_url: url,
81
+ url,
82
+ pull_request: z.object({ url, html_url: url }).optional(),
83
+ })
84
+ const branch = z.object({
85
+ name: text,
86
+ commit: z.object({ sha, url }),
87
+ protected: z.boolean(),
88
+ })
89
+ const ref = z.object({
90
+ ref: text,
91
+ node_id: text,
92
+ url,
93
+ object: z.object({ type: z.enum(['commit', 'tag']), sha, url }),
94
+ })
95
+ const gitAuthor = z.object({ name: text, email: text, date: text })
96
+ const commit = z.object({
97
+ sha,
98
+ node_id: text,
99
+ url,
100
+ html_url: url,
101
+ commit: z.object({
102
+ message: text,
103
+ author: gitAuthor,
104
+ committer: gitAuthor,
105
+ tree: z.object({ sha, url }),
106
+ comment_count: integer,
107
+ }),
108
+ author: user.nullable(),
109
+ committer: user.nullable(),
110
+ parents: z.array(z.object({ sha, url, html_url: url })),
111
+ })
112
+ const fileDiff = z.object({
113
+ sha,
114
+ filename: text,
115
+ status: z.enum(['added', 'removed', 'modified', 'renamed']),
116
+ additions: integer,
117
+ deletions: integer,
118
+ changes: integer,
119
+ patch: text.optional(),
120
+ blob_url: url,
121
+ raw_url: url,
122
+ contents_url: url,
123
+ })
124
+ const pull = issue.extend({
125
+ head: z.object({ label: text, ref: text, sha, repo: repository }),
126
+ base: z.object({ label: text, ref: text, sha, repo: repository }),
127
+ merged: z.boolean(),
128
+ merged_at: text.nullable(),
129
+ merge_commit_sha: sha.nullable(),
130
+ mergeable: z.boolean().nullable(),
131
+ draft: z.boolean(),
132
+ diff_url: url,
133
+ patch_url: url,
134
+ })
135
+ const review = z.object({
136
+ id: integer,
137
+ user,
138
+ body: text,
139
+ state: z.enum(['APPROVED', 'CHANGES_REQUESTED', 'COMMENTED']),
140
+ submitted_at: text,
141
+ commit_id: sha.nullable(),
142
+ html_url: url,
143
+ })
144
+ const content = z.object({
145
+ type: z.enum(['file', 'dir', 'symlink', 'submodule']),
146
+ name: text,
147
+ path: text,
148
+ sha,
149
+ size: integer,
150
+ url,
151
+ html_url: url,
152
+ git_url: url,
153
+ download_url: url.nullable(),
154
+ encoding: text.optional(),
155
+ content: text.optional(),
156
+ })
157
+ const treeEntry = z.object({
158
+ path: text,
159
+ mode: text,
160
+ type: z.enum(['tree', 'blob', 'commit']),
161
+ sha,
162
+ size: integer.optional(),
163
+ url,
164
+ })
165
+ const changeFile = z.object({
166
+ path: text,
167
+ status: z.enum(['added', 'removed', 'modified']),
168
+ additions: integer,
169
+ deletions: integer,
170
+ hunks: z.array(
171
+ z.object({ oldStart: integer, newStart: integer, lines: z.array(text) }),
172
+ ),
173
+ note: text.optional(),
174
+ })
175
+ const change = z.object({
176
+ from: sha.nullable(),
177
+ to: sha,
178
+ files: z.array(changeFile),
179
+ truncated: z.boolean(),
180
+ total: integer,
181
+ sizes: z.array(z.object({ path: text, lines: integer })),
182
+ })
183
+ // cqx's report is extensible, but the measured fields are required.
184
+ const health = z
185
+ .object({
186
+ lines: integer,
187
+ incomplete: z
188
+ .enum(['c-family-unavailable', 'c-family-too-large', 'unavailable'])
189
+ .optional(),
190
+ scores: z
191
+ .object({
192
+ quality: z.number(),
193
+ containment: z.number(),
194
+ legibility: z.number(),
195
+ security: z.number(),
196
+ modularity: z.number(),
197
+ })
198
+ .nullable(),
199
+ rules: z.array(
200
+ z.object({
201
+ rule: text,
202
+ category: text,
203
+ language: text,
204
+ describes: text,
205
+ remedy: text,
206
+ deducted: z.number(),
207
+ total_findings: integer,
208
+ findings: z.array(
209
+ z.object({
210
+ what: text,
211
+ file: text,
212
+ line: integer,
213
+ text: text.optional(),
214
+ }),
215
+ ),
216
+ }),
217
+ ),
218
+ calibrated: z.boolean(),
219
+ })
220
+ .nullable()
221
+ const ok = z.object({ ok: z.boolean() })
222
+ const token = z.object({
223
+ id: text,
224
+ label: text,
225
+ scopes: z.array(z.enum(SCOPES)),
226
+ repos: z.array(text).nullable(),
227
+ created_at: text,
228
+ expires_at: text,
229
+ })
230
+ const agent = z.object({
231
+ name: text,
232
+ sponsor: text,
233
+ label: text,
234
+ publicKey: text.nullable(),
235
+ createdAt: text,
236
+ revokedAt: text.nullable(),
237
+ approver: z.boolean(),
238
+ approvedBy: text.nullable(),
239
+ })
240
+ const join = z.object({
241
+ id: text,
242
+ sponsor: text,
243
+ label: text,
244
+ publicKey: text,
245
+ repo: text.nullable(),
246
+ grants: z.array(text),
247
+ note: text.nullable(),
248
+ status: z.enum(['pending', 'approved', 'denied']),
249
+ createdAt: text,
250
+ decidedAt: text.nullable(),
251
+ decidedBy: text.nullable(),
252
+ tokenIssued: z.boolean(),
253
+ })
254
+ const title = text.trim().min(1).max(200),
255
+ body = text.max(64000),
256
+ labels = z.array(text.min(1).max(31)).max(10)
257
+ const empty = z.object({}).strict()
258
+ const pagination = z.object({
259
+ per_page: z.coerce.number().int().min(1).max(100).default(30),
260
+ page: z.coerce.number().int().min(1).max(10000).default(1),
261
+ cursor: text.optional(),
262
+ })
263
+ const listing = pagination.extend({
264
+ state: z.enum(['open', 'closed', 'all']).default('open'),
265
+ sort: z.enum(['created', 'updated', 'comments']).default('created'),
266
+ direction: z.enum(['asc', 'desc']).default('desc'),
267
+ labels: text.optional(),
268
+ })
269
+ const reference = z.object({ ref: text.optional() })
270
+ export const errorSchema = z.object({
271
+ message: text,
272
+ documentation_url: url,
273
+ errors: z
274
+ .array(
275
+ z.object({
276
+ resource: text.optional(),
277
+ field: text.optional(),
278
+ code: text.optional(),
279
+ message: text,
280
+ }),
281
+ )
282
+ .optional(),
283
+ })
284
+ export type CachePolicy =
285
+ 'immutable' | 'resolved-hash' | 'index' | 'no-store' | 'static'
286
+ function route<
287
+ const I extends string,
288
+ B extends z.ZodType,
289
+ O extends z.ZodType,
290
+ Q extends z.ZodType = typeof empty,
291
+ >(
292
+ id: I,
293
+ method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE',
294
+ path: string,
295
+ scope: Scope | null,
296
+ output: O,
297
+ input: B,
298
+ cache: CachePolicy,
299
+ github = true,
300
+ query: Q = empty as unknown as Q,
301
+ status = 200,
302
+ phase: 'A' | 'B' | 'C' | 'D' = 'A',
303
+ ) {
304
+ const params = z.object(
305
+ Object.fromEntries(
306
+ [...path.matchAll(/\{(\w+)\}/g)].map((m) => [
307
+ m[1],
308
+ m[1] === 'owner' || m[1] === 'org'
309
+ ? text.regex(/^[a-z0-9][a-z0-9-]{0,38}$/i)
310
+ : m[1] === 'repo'
311
+ ? text.regex(/^[a-z0-9][a-z0-9._-]{0,99}$/i)
312
+ : ['number', 'run', 'job', 'hook', 'delivery'].includes(m[1])
313
+ ? text.regex(/^[1-9][0-9]{0,14}$/)
314
+ : text.min(1).max(4096),
315
+ ]),
316
+ ),
317
+ )
318
+ return {
319
+ id,
320
+ method,
321
+ path,
322
+ scope,
323
+ input,
324
+ output,
325
+ query,
326
+ params,
327
+ cache,
328
+ github,
329
+ status,
330
+ phase,
331
+ }
332
+ }
333
+ const actionStatus = z.enum(['queued', 'in_progress', 'completed'])
334
+ const conclusion = z
335
+ .enum(['success', 'failure', 'cancelled', 'skipped'])
336
+ .nullable()
337
+ const actionRun = z.object({
338
+ id: integer,
339
+ name: text,
340
+ head_branch: text,
341
+ head_sha: sha,
342
+ event: text,
343
+ status: actionStatus,
344
+ conclusion,
345
+ run_number: integer,
346
+ created_at: text,
347
+ updated_at: text,
348
+ html_url: url,
349
+ url,
350
+ workflow_id: integer,
351
+ started_at: text.nullable().optional(),
352
+ completed_at: text.nullable().optional(),
353
+ reason: text.nullable().optional(),
354
+ actor: user,
355
+ })
356
+ const actionJob = z.object({
357
+ id: integer,
358
+ run_id: integer,
359
+ name: text,
360
+ head_sha: sha,
361
+ status: actionStatus,
362
+ conclusion,
363
+ started_at: text.nullable(),
364
+ completed_at: text.nullable(),
365
+ runner_id: integer.nullable(),
366
+ runner_name: text.nullable(),
367
+ reason: text.nullable().optional(),
368
+ steps: z.array(
369
+ z.object({
370
+ name: text,
371
+ status: actionStatus,
372
+ conclusion,
373
+ number: integer,
374
+ exit_code: integer.nullable().optional(),
375
+ started_at: text.nullable(),
376
+ completed_at: text.nullable(),
377
+ }),
378
+ ),
379
+ })
380
+ const runner = z.object({
381
+ arch: text.optional(),
382
+ last_seen: integer.optional(),
383
+ group: text.optional(),
384
+ group_name: text.optional(),
385
+ inherited: z.boolean().optional(),
386
+ eligible: z.boolean().optional(),
387
+ ineligible_reason: text.nullable().optional(),
388
+ assignment: z
389
+ .object({ repository: text, job: integer, run: integer, lease: text })
390
+ .nullable()
391
+ .optional(),
392
+ id: integer,
393
+ gild_id: text,
394
+ name: text,
395
+ os: text,
396
+ status: z.enum(['online', 'offline']),
397
+ busy: z.boolean(),
398
+ labels: z.array(
399
+ z.object({ id: integer, name: text, type: z.literal('custom') }),
400
+ ),
401
+ })
402
+ const assignment = z.object({
403
+ schema: z.literal(1),
404
+ checkoutToken: text.optional(),
405
+ workspaceToken: text,
406
+ github: z.record(text, z.unknown()),
407
+ job: integer,
408
+ run: integer,
409
+ lease: text,
410
+ sha,
411
+ ref: text,
412
+ repository: text,
413
+ spec: z.object({ id: text }).passthrough(),
414
+ steps: z.array(
415
+ z
416
+ .object({
417
+ name: text,
418
+ when: z.object({
419
+ success: z.boolean(),
420
+ failure: z.boolean(),
421
+ cancelled: z.boolean(),
422
+ }),
423
+ })
424
+ .passthrough(),
425
+ ),
426
+ timeout: z.number(),
427
+ })
428
+ const R = '/repos/{owner}/{repo}'
429
+ // IDs are stable client operation names; paths follow GitHub REST v3.
430
+ const registration = z.object({ token: text, expires_at: text })
431
+ const runnerJobs = z.object({
432
+ jobs: z.array(
433
+ z.object({
434
+ repository: text,
435
+ run: integer,
436
+ job: integer,
437
+ status: text,
438
+ name: text,
439
+ }),
440
+ ),
441
+ })
442
+ function poolRoutes<const P extends 'org' | 'user'>(prefix: P, path: string) {
443
+ return [
444
+ route(
445
+ `${prefix}PoolRecent`,
446
+ 'GET',
447
+ path + '/runners/{runner}/jobs',
448
+ 'actions',
449
+ runnerJobs,
450
+ empty,
451
+ 'no-store',
452
+ ),
453
+ route(
454
+ `${prefix}PoolRunners`,
455
+ 'GET',
456
+ path + '/runners',
457
+ 'actions',
458
+ z.object({ total_count: integer, runners: z.array(runner) }),
459
+ empty,
460
+ 'no-store',
461
+ ),
462
+ route(
463
+ `${prefix}PoolRegister`,
464
+ 'POST',
465
+ path + '/runners',
466
+ 'actions',
467
+ z.object({ id: text, token: text }),
468
+ runnerRegistration,
469
+ 'no-store',
470
+ true,
471
+ empty,
472
+ 201,
473
+ ),
474
+ route(
475
+ `${prefix}PoolRegistration`,
476
+ 'POST',
477
+ path + '/runners/registration-token',
478
+ 'actions',
479
+ registration,
480
+ z.object({ group: text.default('default') }),
481
+ 'no-store',
482
+ true,
483
+ empty,
484
+ 201,
485
+ ),
486
+ route(
487
+ `${prefix}PoolPoll`,
488
+ 'POST',
489
+ path + '/runners/poll',
490
+ 'actions',
491
+ z.object({ job: assignment.nullable() }),
492
+ z.object({ wait: integer.min(0).max(20000).default(20000) }),
493
+ 'no-store',
494
+ ),
495
+ route(
496
+ `${prefix}PoolPatchRunner`,
497
+ 'PATCH',
498
+ path + '/runners/{runner}',
499
+ 'actions',
500
+ runner,
501
+ z.object({
502
+ group: text.optional(),
503
+ labels: runnerRegistration.shape.labels.optional(),
504
+ }),
505
+ 'no-store',
506
+ ),
507
+ route(
508
+ `${prefix}PoolRemove`,
509
+ 'DELETE',
510
+ path + '/runners/{runner}',
511
+ 'actions',
512
+ ok,
513
+ empty,
514
+ 'no-store',
515
+ ),
516
+ route(
517
+ `${prefix}PoolGroups`,
518
+ 'GET',
519
+ path + '/runner-groups',
520
+ 'actions',
521
+ z.object({ total_count: integer, runner_groups: z.array(runnerGroup) }),
522
+ empty,
523
+ 'no-store',
524
+ ),
525
+ route(
526
+ `${prefix}PoolCreateGroup`,
527
+ 'POST',
528
+ path + '/runner-groups',
529
+ 'actions',
530
+ runnerGroup,
531
+ groupInput,
532
+ 'no-store',
533
+ true,
534
+ empty,
535
+ 201,
536
+ ),
537
+ route(
538
+ `${prefix}PoolGroup`,
539
+ 'GET',
540
+ path + '/runner-groups/{group}',
541
+ 'actions',
542
+ runnerGroup,
543
+ empty,
544
+ 'no-store',
545
+ ),
546
+ route(
547
+ `${prefix}PoolPatchGroup`,
548
+ 'PATCH',
549
+ path + '/runner-groups/{group}',
550
+ 'actions',
551
+ runnerGroup,
552
+ groupInput.partial(),
553
+ 'no-store',
554
+ ),
555
+ route(
556
+ `${prefix}PoolDeleteGroup`,
557
+ 'DELETE',
558
+ path + '/runner-groups/{group}',
559
+ 'actions',
560
+ ok,
561
+ empty,
562
+ 'no-store',
563
+ ),
564
+ route(
565
+ `${prefix}PoolClearRepositories`,
566
+ 'DELETE',
567
+ path + '/runner-groups/{group}/repositories',
568
+ 'actions',
569
+ ok,
570
+ empty,
571
+ 'no-store',
572
+ ),
573
+ route(
574
+ `${prefix}PoolRepositories`,
575
+ 'GET',
576
+ path + '/runner-groups/{group}/repositories',
577
+ 'actions',
578
+ z.object({ repositories: z.array(text) }),
579
+ empty,
580
+ 'no-store',
581
+ ),
582
+ route(
583
+ `${prefix}PoolPutRepositories`,
584
+ 'PUT',
585
+ path + '/runner-groups/{group}/repositories',
586
+ 'actions',
587
+ ok,
588
+ z.object({
589
+ repositories: runnerGroup.shape.repositories,
590
+ }),
591
+ 'no-store',
592
+ ),
593
+ route(
594
+ `${prefix}PoolAddRepository`,
595
+ 'PUT',
596
+ path + '/runner-groups/{group}/repositories/{repo}',
597
+ 'actions',
598
+ ok,
599
+ empty,
600
+ 'no-store',
601
+ ),
602
+ route(
603
+ `${prefix}PoolRemoveRepository`,
604
+ 'DELETE',
605
+ path + '/runner-groups/{group}/repositories/{repo}',
606
+ 'actions',
607
+ ok,
608
+ empty,
609
+ 'no-store',
610
+ ),
611
+ ] as const
612
+ }
613
+ export const routes = [
614
+ route('channelMessages','GET',R+'/channel/messages','repo:read',channelPage,empty,'no-store',false,channelQuery),
615
+ route('channelPost','POST',R+'/channel/messages',null,channelMessage,channelInput,'no-store',false,empty,201),
616
+ route('channelParticipants','GET',R+'/channel/participants','repo:read',channelParticipants,empty,'no-store',false),
617
+ route('channelStream','GET',R+'/channel/stream','repo:read',z.null(),empty,'no-store',false,z.object({after:channelCursor.optional()}),101),
618
+ // Orchestrators. Granting takes a person with the agents scope; the agent
619
+ // routes take no token scope because the orchestrator grant is the authority.
620
+ route('repoOrchestrators','GET',R+'/orchestrators','repo:read',orchestratorList,empty,'no-store',false),
621
+ route('setRepoOrchestrator','POST',R+'/orchestrators','agents',orchestratorGrant,orchestratorInput,'no-store',false),
622
+ route('deleteRepoOrchestrator','DELETE',R+'/orchestrators/{sponsor}/{label}','agents',orchestratorRevoked,empty,'no-store',false),
623
+ route('orgOrchestrators','GET','/orgs/{org}/orchestrators','agents',orchestratorList,empty,'no-store',false),
624
+ route('setOrgOrchestrator','POST','/orgs/{org}/orchestrators','agents',orchestratorGrant,orchestratorInput,'no-store',false),
625
+ route('deleteOrgOrchestrator','DELETE','/orgs/{org}/orchestrators/{sponsor}/{label}','agents',orchestratorRevoked,empty,'no-store',false),
626
+ route('childAgents','GET',R+'/agents/children',null,z.array(childAgent),empty,'no-store',false),
627
+ route('createChildAgent','POST',R+'/agents/children',null,spawnedChild,childInput,'no-store',false,empty,201),
628
+ route('suspendAgent','POST',R+'/agents/{sponsor}/{label}/suspend',null,suspension,empty,'no-store',false),
629
+ route('resumeAgent','POST',R+'/agents/{sponsor}/{label}/resume',null,suspension,empty,'no-store',false),
630
+ route('importCreate','POST','/user/imports','repo:write',importStatus,importInput,'no-store',false,empty,202,'D'),
631
+ route('importOrgCreate','POST','/orgs/{org}/imports','repo:write',importStatus,importInput,'no-store',false,empty,202,'D'),
632
+ route('importStatus','GET',R+'/import','repo:read',importStatus,empty,'no-store',false,empty,200,'D'),
633
+ route('importClaim','POST',R+'/import/claim','repo:write',importAssignment.nullable(),empty,'no-store',false,empty,200,'D'),
634
+ route('importUserPoll','POST','/users/{name}/imports/poll','actions',importAssignment.nullable(),empty,'no-store',false,empty,200,'D'),
635
+ route('importOrgPoll','POST','/orgs/{org}/imports/poll','actions',importAssignment.nullable(),empty,'no-store',false,empty,200,'D'),
636
+ route('importCredentials','POST',R+'/import/credentials','repo:write',importCredentials,empty,'no-store',false,empty,200,'D'),
637
+ route('importHeartbeat','POST',R+'/import/heartbeat','repo:write',importStatus,z.object({progress:importProgress.optional()}),'no-store',false,empty,200,'D'),
638
+ route('importBatch','POST',R+'/import/batch','repo:write',ok,importBatch,'no-store',false,empty,200,'D'),
639
+ route('importWorkflow','POST',R+'/import/workflow','repo:write',z.object({warnings:z.array(text)}),z.object({file:text.max(300),text:text.max(128*1024)}),'no-store',false,empty,200,'D'),
640
+ route('importFinish','POST',R+'/import/finish','repo:write',importStatus,z.object({warnings:z.array(text.max(500)).max(500),error:text.max(200).optional(),default_branch:text.max(300).optional(),summary:importSummary.optional()}),'no-store',false,empty,200,'D'),
641
+ route('importRetry','POST',R+'/import/retry','repo:write',importStatus,z.object({source_token:text.max(16384).optional()}),'no-store',false,empty,200,'D'),
642
+ route('importCutover','POST',R+'/import/cutover','repo:write',importStatus,empty,'no-store',false,empty,200,'D'),
643
+ route('importPatch','GET',R+'/import/pulls/{number}/patch','repo:read',z.null(),empty,'no-store',false,empty,200,'D'),
644
+
645
+ route(
646
+ 'star',
647
+ 'PUT',
648
+ '/user/starred/{owner}/{repo}',
649
+ 'repo:read',
650
+ z.null(),
651
+ empty,
652
+ 'no-store',
653
+ true,
654
+ empty,
655
+ 204,
656
+ ),
657
+ route(
658
+ 'unstar',
659
+ 'DELETE',
660
+ '/user/starred/{owner}/{repo}',
661
+ 'repo:read',
662
+ z.null(),
663
+ empty,
664
+ 'no-store',
665
+ true,
666
+ empty,
667
+ 204,
668
+ ),
669
+ route(
670
+ 'stargazers',
671
+ 'GET',
672
+ R + '/stargazers',
673
+ 'repo:read',
674
+ z.array(user),
675
+ empty,
676
+ 'no-store',
677
+ true,
678
+ pagination,
679
+ ),
680
+ ...poolRoutes('org', '/orgs/{org}/actions'),
681
+ ...poolRoutes('user', '/users/{name}/actions'),
682
+ route(
683
+ 'actionRunnerJobs',
684
+ 'GET',
685
+ R + '/actions/runners/{runner}/jobs',
686
+ 'actions',
687
+ runnerJobs,
688
+ empty,
689
+ 'no-store',
690
+ ),
691
+ route(
692
+ 'actionRegistration',
693
+ 'POST',
694
+ R + '/actions/runners/registration-token',
695
+ 'actions',
696
+ registration,
697
+ empty,
698
+ 'no-store',
699
+ true,
700
+ empty,
701
+ 201,
702
+ ),
703
+ route(
704
+ 'actionApprove',
705
+ 'POST',
706
+ R + '/actions/runs/{run}/approve',
707
+ 'actions',
708
+ ok,
709
+ empty,
710
+ 'no-store',
711
+ ),
712
+ ...[
713
+ route(
714
+ 'profile',
715
+ 'GET',
716
+ '/user/profile',
717
+ 'admin',
718
+ profileSchema,
719
+ empty,
720
+ 'no-store',
721
+ false,
722
+ ),
723
+ route(
724
+ 'updateProfile',
725
+ 'PATCH',
726
+ '/user/profile',
727
+ 'admin',
728
+ profileSchema,
729
+ profileInput,
730
+ 'no-store',
731
+ false,
732
+ ),
733
+ route(
734
+ 'updatePicture',
735
+ 'PUT',
736
+ '/user/picture',
737
+ 'admin',
738
+ profileSchema,
739
+ z.object({ data: text.max(90000) }),
740
+ 'no-store',
741
+ false,
742
+ ),
743
+ route(
744
+ 'deletePicture',
745
+ 'DELETE',
746
+ '/user/picture',
747
+ 'admin',
748
+ profileSchema,
749
+ empty,
750
+ 'no-store',
751
+ false,
752
+ ),
753
+ route(
754
+ 'orgProfile',
755
+ 'GET',
756
+ '/orgs/{org}/profile',
757
+ 'admin',
758
+ profileSchema,
759
+ empty,
760
+ 'no-store',
761
+ false,
762
+ ),
763
+ route(
764
+ 'updateOrgProfile',
765
+ 'PATCH',
766
+ '/orgs/{org}/profile',
767
+ 'admin',
768
+ profileSchema,
769
+ profileInput,
770
+ 'no-store',
771
+ false,
772
+ ),
773
+ route(
774
+ 'updateOrgPicture',
775
+ 'PUT',
776
+ '/orgs/{org}/picture',
777
+ 'admin',
778
+ profileSchema,
779
+ z.object({ data: text.max(90000) }),
780
+ 'no-store',
781
+ false,
782
+ ),
783
+ route(
784
+ 'deleteOrgPicture',
785
+ 'DELETE',
786
+ '/orgs/{org}/picture',
787
+ 'admin',
788
+ profileSchema,
789
+ empty,
790
+ 'no-store',
791
+ false,
792
+ ),
793
+ route(
794
+ 'putMembership',
795
+ 'PUT',
796
+ '/orgs/{org}/memberships/{name}',
797
+ 'admin',
798
+ z.object({
799
+ ok: z.literal(true),
800
+ org: text,
801
+ member: text,
802
+ role: z.enum(['owner', 'admin', 'member']),
803
+ }),
804
+ z.object({ role: z.enum(['owner', 'admin', 'member']) }),
805
+ 'no-store',
806
+ ),
807
+ route(
808
+ 'deleteMembership',
809
+ 'DELETE',
810
+ '/orgs/{org}/memberships/{name}',
811
+ 'admin',
812
+ z.object({
813
+ ok: z.literal(true),
814
+ org: text,
815
+ member: text,
816
+ role: z.null(),
817
+ }),
818
+ empty,
819
+ 'no-store',
820
+ ),
821
+ route(
822
+ 'leaveOrg',
823
+ 'DELETE',
824
+ '/user/memberships/orgs/{org}',
825
+ 'admin',
826
+ z.object({
827
+ ok: z.literal(true),
828
+ org: text,
829
+ member: text,
830
+ role: z.null(),
831
+ }),
832
+ empty,
833
+ 'no-store',
834
+ false,
835
+ ),
836
+ route(
837
+ 'renameStatusOrg',
838
+ 'GET',
839
+ '/orgs/{org}/rename',
840
+ 'admin',
841
+ renameStatus,
842
+ empty,
843
+ 'no-store',
844
+ false,
845
+ ),
846
+ route(
847
+ 'renameOrg',
848
+ 'POST',
849
+ '/orgs/{org}/rename',
850
+ 'admin',
851
+ z.object({ ok: z.literal(true), name: text }),
852
+ z.object({ name: text }),
853
+ 'no-store',
854
+ false,
855
+ ),
856
+ route(
857
+ 'archiveOrg',
858
+ 'PUT',
859
+ '/orgs/{org}/archive',
860
+ 'admin',
861
+ ok,
862
+ z.object({ archived: z.boolean() }),
863
+ 'no-store',
864
+ false,
865
+ ),
866
+ route(
867
+ 'deleteOrg',
868
+ 'DELETE',
869
+ '/orgs/{org}',
870
+ 'admin',
871
+ z.object({ ok: z.literal(true), restoreUntil: text }),
872
+ z.object({ confirm: text }),
873
+ 'no-store',
874
+ ),
875
+ route(
876
+ 'restoreOrg',
877
+ 'POST',
878
+ '/orgs/{org}/restore',
879
+ 'admin',
880
+ ok,
881
+ empty,
882
+ 'no-store',
883
+ false,
884
+ ),
885
+ route(
886
+ 'updateRepository',
887
+ 'PATCH',
888
+ R,
889
+ 'admin',
890
+ ok,
891
+ z
892
+ .object({
893
+ description: text.max(1000).optional(),
894
+ defaultBranch: text.max(255).optional(),
895
+ })
896
+ .strict()
897
+ .refine(
898
+ (b) => b.description !== undefined || b.defaultBranch !== undefined,
899
+ ),
900
+ 'no-store',
901
+ ),
902
+ route(
903
+ 'renameStatusRepo',
904
+ 'GET',
905
+ R + '/rename',
906
+ 'admin',
907
+ renameStatus,
908
+ empty,
909
+ 'no-store',
910
+ false,
911
+ ),
912
+ route(
913
+ 'renameRepo',
914
+ 'POST',
915
+ R + '/rename',
916
+ 'admin',
917
+ z.object({ ok: z.literal(true), name: text }),
918
+ z.object({ name: text }),
919
+ 'no-store',
920
+ false,
921
+ ),
922
+ route(
923
+ 'archiveRepo',
924
+ 'PUT',
925
+ R + '/archive',
926
+ 'admin',
927
+ ok,
928
+ z.object({ archived: z.boolean() }),
929
+ 'no-store',
930
+ false,
931
+ ),
932
+ route(
933
+ 'deleteRepo',
934
+ 'DELETE',
935
+ R,
936
+ 'admin',
937
+ z.object({ ok: z.literal(true), restoreUntil: text }),
938
+ z.object({ confirm: text }),
939
+ 'no-store',
940
+ ),
941
+ route(
942
+ 'restoreRepo',
943
+ 'POST',
944
+ R + '/restore',
945
+ 'admin',
946
+ ok,
947
+ empty,
948
+ 'no-store',
949
+ false,
950
+ ),
951
+ ].map((r) => ({ ...r, phase: 'D' as const })),
952
+
953
+ route(
954
+ 'pullSessions',
955
+ 'GET',
956
+ R + '/pulls/{number}/sessions',
957
+ 'repo:read',
958
+ z.array(receiptSchema),
959
+ empty,
960
+ 'no-store',
961
+ false,
962
+ pagination,
963
+ 200,
964
+ 'C',
965
+ ),
966
+ route(
967
+ 'createPullSession',
968
+ 'POST',
969
+ R + '/pulls/{number}/sessions',
970
+ 'pulls:write',
971
+ receiptSchema,
972
+ sessionInput,
973
+ 'no-store',
974
+ false,
975
+ empty,
976
+ 201,
977
+ 'C',
978
+ ),
979
+ route(
980
+ 'commitSessions',
981
+ 'GET',
982
+ R + '/commits/{sha}/sessions',
983
+ 'repo:read',
984
+ z.array(receiptSchema),
985
+ empty,
986
+ 'no-store',
987
+ false,
988
+ pagination,
989
+ 200,
990
+ 'C',
991
+ ),
992
+ route(
993
+ 'createCommitSession',
994
+ 'POST',
995
+ R + '/commits/{sha}/sessions',
996
+ 'repo:write',
997
+ receiptSchema,
998
+ sessionInput,
999
+ 'no-store',
1000
+ false,
1001
+ empty,
1002
+ 201,
1003
+ 'C',
1004
+ ),
1005
+ route(
1006
+ 'events',
1007
+ 'GET',
1008
+ '/events',
1009
+ 'repo:read',
1010
+ eventPage,
1011
+ empty,
1012
+ 'no-store',
1013
+ false,
1014
+ z.object({
1015
+ repos: text.optional(),
1016
+ since: text.optional(),
1017
+ wait: z.coerce.number().int().min(0).max(20000).default(20000),
1018
+ }),
1019
+ 200,
1020
+ 'B',
1021
+ ),
1022
+ route(
1023
+ 'repoHooks',
1024
+ 'GET',
1025
+ R + '/hooks',
1026
+ 'hooks',
1027
+ z.array(hookSchema),
1028
+ empty,
1029
+ 'no-store',
1030
+ true,
1031
+ pagination,
1032
+ 200,
1033
+ 'B',
1034
+ ),
1035
+ route(
1036
+ 'repoCreateHook',
1037
+ 'POST',
1038
+ R + '/hooks',
1039
+ 'hooks',
1040
+ hookSchema,
1041
+ hookInput,
1042
+ 'no-store',
1043
+ true,
1044
+ empty,
1045
+ 201,
1046
+ 'B',
1047
+ ),
1048
+ route(
1049
+ 'repoHook',
1050
+ 'GET',
1051
+ R + '/hooks/{hook}',
1052
+ 'hooks',
1053
+ hookSchema,
1054
+ empty,
1055
+ 'no-store',
1056
+ true,
1057
+ empty,
1058
+ 200,
1059
+ 'B',
1060
+ ),
1061
+ route(
1062
+ 'repoUpdateHook',
1063
+ 'PATCH',
1064
+ R + '/hooks/{hook}',
1065
+ 'hooks',
1066
+ hookSchema,
1067
+ hookPatch,
1068
+ 'no-store',
1069
+ true,
1070
+ empty,
1071
+ 200,
1072
+ 'B',
1073
+ ),
1074
+ route(
1075
+ 'repoDeleteHook',
1076
+ 'DELETE',
1077
+ R + '/hooks/{hook}',
1078
+ 'hooks',
1079
+ ok,
1080
+ empty,
1081
+ 'no-store',
1082
+ false,
1083
+ empty,
1084
+ 200,
1085
+ 'B',
1086
+ ),
1087
+ route(
1088
+ 'repoHookDeliveries',
1089
+ 'GET',
1090
+ R + '/hooks/{hook}/deliveries',
1091
+ 'hooks',
1092
+ z.array(deliverySchema),
1093
+ empty,
1094
+ 'no-store',
1095
+ true,
1096
+ pagination,
1097
+ 200,
1098
+ 'B',
1099
+ ),
1100
+ route(
1101
+ 'repoHookDelivery',
1102
+ 'GET',
1103
+ R + '/hooks/{hook}/deliveries/{delivery}',
1104
+ 'hooks',
1105
+ deliverySchema,
1106
+ empty,
1107
+ 'no-store',
1108
+ true,
1109
+ empty,
1110
+ 200,
1111
+ 'B',
1112
+ ),
1113
+ route(
1114
+ 'repoRedeliverHook',
1115
+ 'POST',
1116
+ R + '/hooks/{hook}/deliveries/{delivery}/attempts',
1117
+ 'hooks',
1118
+ z.object({ id: integer, guid: text }),
1119
+ empty,
1120
+ 'no-store',
1121
+ false,
1122
+ empty,
1123
+ 202,
1124
+ 'B',
1125
+ ),
1126
+ route(
1127
+ 'repoPingHook',
1128
+ 'POST',
1129
+ R + '/hooks/{hook}/pings',
1130
+ 'hooks',
1131
+ z.object({ id: integer, guid: text }),
1132
+ empty,
1133
+ 'no-store',
1134
+ false,
1135
+ empty,
1136
+ 202,
1137
+ 'B',
1138
+ ),
1139
+ route(
1140
+ 'orgHooks',
1141
+ 'GET',
1142
+ '/orgs/{org}' + '/hooks',
1143
+ 'hooks',
1144
+ z.array(hookSchema),
1145
+ empty,
1146
+ 'no-store',
1147
+ true,
1148
+ pagination,
1149
+ 200,
1150
+ 'B',
1151
+ ),
1152
+ route(
1153
+ 'orgCreateHook',
1154
+ 'POST',
1155
+ '/orgs/{org}' + '/hooks',
1156
+ 'hooks',
1157
+ hookSchema,
1158
+ hookInput,
1159
+ 'no-store',
1160
+ true,
1161
+ empty,
1162
+ 201,
1163
+ 'B',
1164
+ ),
1165
+ route(
1166
+ 'orgHook',
1167
+ 'GET',
1168
+ '/orgs/{org}' + '/hooks/{hook}',
1169
+ 'hooks',
1170
+ hookSchema,
1171
+ empty,
1172
+ 'no-store',
1173
+ true,
1174
+ empty,
1175
+ 200,
1176
+ 'B',
1177
+ ),
1178
+ route(
1179
+ 'orgUpdateHook',
1180
+ 'PATCH',
1181
+ '/orgs/{org}' + '/hooks/{hook}',
1182
+ 'hooks',
1183
+ hookSchema,
1184
+ hookPatch,
1185
+ 'no-store',
1186
+ true,
1187
+ empty,
1188
+ 200,
1189
+ 'B',
1190
+ ),
1191
+ route(
1192
+ 'orgDeleteHook',
1193
+ 'DELETE',
1194
+ '/orgs/{org}' + '/hooks/{hook}',
1195
+ 'hooks',
1196
+ ok,
1197
+ empty,
1198
+ 'no-store',
1199
+ false,
1200
+ empty,
1201
+ 200,
1202
+ 'B',
1203
+ ),
1204
+ route(
1205
+ 'orgHookDeliveries',
1206
+ 'GET',
1207
+ '/orgs/{org}' + '/hooks/{hook}/deliveries',
1208
+ 'hooks',
1209
+ z.array(deliverySchema),
1210
+ empty,
1211
+ 'no-store',
1212
+ true,
1213
+ pagination,
1214
+ 200,
1215
+ 'B',
1216
+ ),
1217
+ route(
1218
+ 'orgHookDelivery',
1219
+ 'GET',
1220
+ '/orgs/{org}' + '/hooks/{hook}/deliveries/{delivery}',
1221
+ 'hooks',
1222
+ deliverySchema,
1223
+ empty,
1224
+ 'no-store',
1225
+ true,
1226
+ empty,
1227
+ 200,
1228
+ 'B',
1229
+ ),
1230
+ route(
1231
+ 'orgRedeliverHook',
1232
+ 'POST',
1233
+ '/orgs/{org}' + '/hooks/{hook}/deliveries/{delivery}/attempts',
1234
+ 'hooks',
1235
+ z.object({ id: integer, guid: text }),
1236
+ empty,
1237
+ 'no-store',
1238
+ false,
1239
+ empty,
1240
+ 202,
1241
+ 'B',
1242
+ ),
1243
+ route(
1244
+ 'orgPingHook',
1245
+ 'POST',
1246
+ '/orgs/{org}' + '/hooks/{hook}/pings',
1247
+ 'hooks',
1248
+ z.object({ id: integer, guid: text }),
1249
+ empty,
1250
+ 'no-store',
1251
+ false,
1252
+ empty,
1253
+ 202,
1254
+ 'B',
1255
+ ),
1256
+
1257
+ route(
1258
+ 'org',
1259
+ 'GET',
1260
+ '/orgs/{org}',
1261
+ 'repo:read',
1262
+ z.object({
1263
+ login: text,
1264
+ id: integer,
1265
+ type: z.literal('Organization'),
1266
+ html_url: url,
1267
+ description: text.nullable(),
1268
+ created_at: text,
1269
+ }),
1270
+ empty,
1271
+ 'index',
1272
+ ),
1273
+ route(
1274
+ 'orgMembers',
1275
+ 'GET',
1276
+ '/orgs/{org}/members',
1277
+ 'repo:read',
1278
+ z.array(user),
1279
+ empty,
1280
+ 'index',
1281
+ true,
1282
+ pagination,
1283
+ ),
1284
+ route(
1285
+ 'updateAgent',
1286
+ 'PATCH',
1287
+ '/agents/{label}',
1288
+ 'agents',
1289
+ ok,
1290
+ z.object({ approver: z.boolean() }),
1291
+ 'no-store',
1292
+ false,
1293
+ ),
1294
+ route(
1295
+ 'agentRequest',
1296
+ 'GET',
1297
+ '/agents/requests/{id}',
1298
+ 'agents',
1299
+ join,
1300
+ empty,
1301
+ 'no-store',
1302
+ false,
1303
+ ),
1304
+ route(
1305
+ 'repoAgents',
1306
+ 'GET',
1307
+ R + '/agents',
1308
+ 'repo:read',
1309
+ z.object({
1310
+ agents: z.record(text, z.array(z.enum(['pr', 'review', 'merge', 'coordinate', 'queue']))),
1311
+ }),
1312
+ empty,
1313
+ 'index',
1314
+ false,
1315
+ ),
1316
+ route(
1317
+ 'setRepoAgent',
1318
+ 'POST',
1319
+ R + '/agents',
1320
+ 'agents',
1321
+ z.object({ ok: z.literal(true), agent: text, grants: z.array(text) }),
1322
+ z.object({
1323
+ agent: text,
1324
+ grants: z.array(z.enum(['pr', 'review', 'merge', 'coordinate', 'queue'])),
1325
+ }),
1326
+ 'no-store',
1327
+ false,
1328
+ ),
1329
+ route(
1330
+ 'claimIssue',
1331
+ 'POST',
1332
+ R + '/issues/{number}/claim',
1333
+ 'issues:write',
1334
+ ok,
1335
+ z.object({ action: z.enum(['claim', 'unclaim']) }),
1336
+ 'no-store',
1337
+ false,
1338
+ ),
1339
+ route(
1340
+ 'dequeuePull',
1341
+ 'DELETE',
1342
+ R + '/merge-queue/{number}',
1343
+ 'pulls:write',
1344
+ ok,
1345
+ empty,
1346
+ 'no-store',
1347
+ false,
1348
+ ),
1349
+ route(
1350
+ 'actionOverview',
1351
+ 'GET',
1352
+ R + '/actions',
1353
+ 'actions',
1354
+ z.object({
1355
+ workflow_runs: z.array(actionRun),
1356
+ runners: z.array(runner),
1357
+ required: z.array(text),
1358
+ }),
1359
+ empty,
1360
+ 'index',
1361
+ false,
1362
+ ),
1363
+ route(
1364
+ 'actionCommitRuns',
1365
+ 'GET',
1366
+ R + '/actions/commits/{sha}',
1367
+ 'actions',
1368
+ z.array(actionRun),
1369
+ empty,
1370
+ 'index',
1371
+ false,
1372
+ ),
1373
+ route(
1374
+ 'actionSettings',
1375
+ 'PUT',
1376
+ R + '/actions/settings',
1377
+ 'admin',
1378
+ z.object({ required: z.array(text) }),
1379
+ z.object({ required: z.array(text.regex(/^[\w.-]+\.ya?ml$/)).max(64) }),
1380
+ 'no-store',
1381
+ false,
1382
+ ),
1383
+ route(
1384
+ 'actionSecrets',
1385
+ 'GET',
1386
+ R + '/actions/settings/secrets',
1387
+ 'admin',
1388
+ z.object({ secrets: z.array(z.object({ name: text, updated_at: text })) }),
1389
+ empty,
1390
+ 'no-store',
1391
+ false,
1392
+ ),
1393
+ route(
1394
+ 'actionPutSecret',
1395
+ 'PUT',
1396
+ R + '/actions/settings/secrets/{secret}',
1397
+ 'admin',
1398
+ ok,
1399
+ z.object({ value: text.min(1).max(16384) }),
1400
+ 'no-store',
1401
+ false,
1402
+ ),
1403
+ route(
1404
+ 'actionDeleteSecret',
1405
+ 'DELETE',
1406
+ R + '/actions/settings/secrets/{secret}',
1407
+ 'admin',
1408
+ ok,
1409
+ empty,
1410
+ 'no-store',
1411
+ false,
1412
+ ),
1413
+
1414
+ route(
1415
+ 'openapi',
1416
+ 'GET',
1417
+ '/openapi.json',
1418
+ null,
1419
+ z
1420
+ .object({
1421
+ openapi: text,
1422
+ info: z.object({ title: text, version: text }),
1423
+ paths: z.record(text, z.unknown()),
1424
+ })
1425
+ .passthrough(),
1426
+ empty,
1427
+ 'static',
1428
+ false,
1429
+ ),
1430
+ route(
1431
+ 'repoVisibility',
1432
+ 'GET',
1433
+ R + '/visibility',
1434
+ 'repo:read',
1435
+ z.object({ visibility: z.enum(['public', 'private']) }),
1436
+ empty,
1437
+ 'no-store',
1438
+ false,
1439
+ empty,
1440
+ 200,
1441
+ 'D',
1442
+ ),
1443
+ route(
1444
+ 'setRepoVisibility',
1445
+ 'PATCH',
1446
+ R + '/visibility',
1447
+ 'admin',
1448
+ z.object({ visibility: z.enum(['public', 'private']) }),
1449
+ z
1450
+ .object({
1451
+ visibility: z.enum(['public', 'private']),
1452
+ confirm: text.optional(),
1453
+ })
1454
+ .strict(),
1455
+ 'no-store',
1456
+ false,
1457
+ empty,
1458
+ 200,
1459
+ 'D',
1460
+ ),
1461
+ route(
1462
+ 'collaborators',
1463
+ 'GET',
1464
+ R + '/collaborators',
1465
+ 'repo:read',
1466
+ z.object({
1467
+ collaborators: z.array(
1468
+ z.object({ login: text, permission: z.enum(['read', 'write']) }),
1469
+ ),
1470
+ invitations: z.array(
1471
+ z.object({
1472
+ id: text,
1473
+ repo: text,
1474
+ invitee: text,
1475
+ permission: z.enum(['read', 'write']),
1476
+ inviter: text,
1477
+ created_at: text,
1478
+ }),
1479
+ ),
1480
+ }),
1481
+ empty,
1482
+ 'no-store',
1483
+ true,
1484
+ empty,
1485
+ 200,
1486
+ 'D',
1487
+ ),
1488
+ route(
1489
+ 'addCollaborator',
1490
+ 'PUT',
1491
+ R + '/collaborators/{username}',
1492
+ 'admin',
1493
+ ok,
1494
+ z
1495
+ .object({ permission: z.enum(['read', 'write']).default('read') })
1496
+ .strict(),
1497
+ 'no-store',
1498
+ true,
1499
+ empty,
1500
+ 200,
1501
+ 'D',
1502
+ ),
1503
+ route(
1504
+ 'removeCollaborator',
1505
+ 'DELETE',
1506
+ R + '/collaborators/{username}',
1507
+ 'admin',
1508
+ ok,
1509
+ empty,
1510
+ 'no-store',
1511
+ true,
1512
+ empty,
1513
+ 200,
1514
+ 'D',
1515
+ ),
1516
+ route(
1517
+ 'repositoryInvitations',
1518
+ 'GET',
1519
+ '/user/repository_invitations',
1520
+ 'repo:read',
1521
+ z.array(z.object({ id: text, permission: z.enum(['read', 'write']) })),
1522
+ empty,
1523
+ 'no-store',
1524
+ true,
1525
+ empty,
1526
+ 200,
1527
+ 'D',
1528
+ ),
1529
+ route(
1530
+ 'acceptRepositoryInvitation',
1531
+ 'PATCH',
1532
+ '/user/repository_invitations/{id}',
1533
+ // Accepting can grant write, so a read-only token may not accept.
1534
+ 'repo:write',
1535
+ ok,
1536
+ empty,
1537
+ 'no-store',
1538
+ true,
1539
+ empty,
1540
+ 200,
1541
+ 'D',
1542
+ ),
1543
+ route(
1544
+ 'declineRepositoryInvitation',
1545
+ 'DELETE',
1546
+ '/user/repository_invitations/{id}',
1547
+ 'repo:read',
1548
+ ok,
1549
+ empty,
1550
+ 'no-store',
1551
+ true,
1552
+ empty,
1553
+ 200,
1554
+ 'D',
1555
+ ),
1556
+ route(
1557
+ 'repos',
1558
+ 'GET',
1559
+ '/user/repos',
1560
+ 'repo:read',
1561
+ z.array(repository),
1562
+ empty,
1563
+ 'index',
1564
+ true,
1565
+ pagination,
1566
+ ),
1567
+ route(
1568
+ 'createRepository',
1569
+ 'POST',
1570
+ '/user/repos',
1571
+ 'repo:write',
1572
+ repository,
1573
+ z.object({
1574
+ name: text.min(1),
1575
+ description: text.max(1000).optional(),
1576
+ private: z.boolean().optional(),
1577
+ }),
1578
+ 'no-store',
1579
+ true,
1580
+ empty,
1581
+ 201,
1582
+ ),
1583
+ route(
1584
+ 'createOrgRepository',
1585
+ 'POST',
1586
+ '/orgs/{org}/repos',
1587
+ 'repo:write',
1588
+ repository,
1589
+ z.object({
1590
+ name: text.min(1),
1591
+ description: text.max(1000).optional(),
1592
+ private: z.boolean().optional(),
1593
+ }),
1594
+ 'no-store',
1595
+ true,
1596
+ empty,
1597
+ 201,
1598
+ ),
1599
+ route(
1600
+ 'orgs',
1601
+ 'GET',
1602
+ '/orgs',
1603
+ 'repo:read',
1604
+ z.array(
1605
+ z.object({
1606
+ name: text,
1607
+ description: text.nullable(),
1608
+ createdBy: text,
1609
+ createdAt: text,
1610
+ role: z.enum(['owner', 'admin', 'member']),
1611
+ }),
1612
+ ),
1613
+ empty,
1614
+ 'no-store',
1615
+ false,
1616
+ ),
1617
+ route(
1618
+ 'createOrg',
1619
+ 'POST',
1620
+ '/orgs',
1621
+ 'admin',
1622
+ z.object({
1623
+ name: text,
1624
+ description: text.nullable(),
1625
+ createdBy: text,
1626
+ createdAt: text,
1627
+ }),
1628
+ z.object({
1629
+ name: text.min(1),
1630
+ description: text.max(1000).optional(),
1631
+ private: z.boolean().optional(),
1632
+ }),
1633
+ 'no-store',
1634
+ false,
1635
+ empty,
1636
+ 201,
1637
+ ),
1638
+ route(
1639
+ 'addOrgMember',
1640
+ 'POST',
1641
+ '/orgs/{org}/members',
1642
+ 'admin',
1643
+ z.object({
1644
+ ok: z.literal(true),
1645
+ org: text,
1646
+ member: text,
1647
+ role: z.enum(['owner', 'admin', 'member']),
1648
+ }),
1649
+ z.object({
1650
+ member: text,
1651
+ role: z.enum(['owner', 'admin', 'member']).default('member'),
1652
+ }),
1653
+ 'no-store',
1654
+ false,
1655
+ empty,
1656
+ 201,
1657
+ ),
1658
+ route(
1659
+ 'ownerRepos',
1660
+ 'GET',
1661
+ '/users/{owner}/repos',
1662
+ 'repo:read',
1663
+ z.array(repository),
1664
+ empty,
1665
+ 'index',
1666
+ true,
1667
+ pagination,
1668
+ ),
1669
+ route(
1670
+ 'orgRepos',
1671
+ 'GET',
1672
+ '/orgs/{owner}/repos',
1673
+ 'repo:read',
1674
+ z.array(repository),
1675
+ empty,
1676
+ 'index',
1677
+ true,
1678
+ pagination,
1679
+ ),
1680
+ route('repo', 'GET', R, 'repo:read', repository, empty, 'index'),
1681
+ route(
1682
+ 'branches',
1683
+ 'GET',
1684
+ R + '/branches',
1685
+ 'repo:read',
1686
+ z.array(branch),
1687
+ empty,
1688
+ 'index',
1689
+ true,
1690
+ pagination,
1691
+ ),
1692
+ route(
1693
+ 'refs',
1694
+ 'GET',
1695
+ R + '/git/refs',
1696
+ 'repo:read',
1697
+ z.array(ref),
1698
+ empty,
1699
+ 'index',
1700
+ true,
1701
+ pagination,
1702
+ ),
1703
+ route('ref', 'GET', R + '/git/ref/{ref}', 'repo:read', ref, empty, 'index'),
1704
+ route(
1705
+ 'commits',
1706
+ 'GET',
1707
+ R + '/commits',
1708
+ 'repo:read',
1709
+ z.array(commit),
1710
+ empty,
1711
+ 'resolved-hash',
1712
+ true,
1713
+ pagination.extend({ sha: text.optional() }),
1714
+ ),
1715
+ route(
1716
+ 'commit',
1717
+ 'GET',
1718
+ R + '/commits/{sha}',
1719
+ 'repo:read',
1720
+ commit.extend({
1721
+ files: z.array(fileDiff),
1722
+ stats: z.object({
1723
+ additions: integer,
1724
+ deletions: integer,
1725
+ total: integer,
1726
+ }),
1727
+ }),
1728
+ empty,
1729
+ 'resolved-hash',
1730
+ ),
1731
+ route(
1732
+ 'compare',
1733
+ 'GET',
1734
+ R + '/compare/{base}...{head}',
1735
+ 'repo:read',
1736
+ z.object({
1737
+ url,
1738
+ html_url: url,
1739
+ status: z.enum(['ahead', 'behind', 'diverged', 'identical']),
1740
+ ahead_by: integer,
1741
+ behind_by: integer,
1742
+ total_commits: integer,
1743
+ base_commit: commit,
1744
+ merge_base_commit: commit,
1745
+ commits: z.array(commit),
1746
+ files: z.array(fileDiff),
1747
+ }),
1748
+ empty,
1749
+ 'resolved-hash',
1750
+ true,
1751
+ pagination,
1752
+ ),
1753
+ route(
1754
+ 'contentsRoot',
1755
+ 'GET',
1756
+ R + '/contents',
1757
+ 'repo:read',
1758
+ z.union([content, z.array(content)]),
1759
+ empty,
1760
+ 'resolved-hash',
1761
+ true,
1762
+ reference,
1763
+ ),
1764
+ route(
1765
+ 'contents',
1766
+ 'GET',
1767
+ R + '/contents/{path}',
1768
+ 'repo:read',
1769
+ z.union([content, z.array(content)]),
1770
+ empty,
1771
+ 'resolved-hash',
1772
+ true,
1773
+ reference,
1774
+ ),
1775
+ route(
1776
+ 'tree',
1777
+ 'GET',
1778
+ R + '/git/trees/{sha}',
1779
+ 'repo:read',
1780
+ z.object({ sha, url, tree: z.array(treeEntry), truncated: z.boolean() }),
1781
+ empty,
1782
+ 'resolved-hash',
1783
+ true,
1784
+ z.object({ recursive: text.optional() }),
1785
+ ),
1786
+ route(
1787
+ 'blob',
1788
+ 'GET',
1789
+ R + '/git/blobs/{sha}',
1790
+ 'repo:read',
1791
+ z.object({
1792
+ sha,
1793
+ url,
1794
+ size: integer,
1795
+ encoding: z.literal('base64'),
1796
+ content: text,
1797
+ }),
1798
+ empty,
1799
+ 'immutable',
1800
+ ),
1801
+ route(
1802
+ 'issues',
1803
+ 'GET',
1804
+ R + '/issues',
1805
+ 'repo:read',
1806
+ z.array(issue),
1807
+ empty,
1808
+ 'index',
1809
+ true,
1810
+ listing,
1811
+ ),
1812
+ route(
1813
+ 'issue',
1814
+ 'GET',
1815
+ R + '/issues/{number}',
1816
+ 'repo:read',
1817
+ issue,
1818
+ empty,
1819
+ 'index',
1820
+ ),
1821
+ route(
1822
+ 'createIssue',
1823
+ 'POST',
1824
+ R + '/issues',
1825
+ 'issues:write',
1826
+ issue,
1827
+ z.object({ title, body: body.default(''), labels: labels.default([]) }),
1828
+ 'no-store',
1829
+ true,
1830
+ empty,
1831
+ 201,
1832
+ ),
1833
+ route(
1834
+ 'updateIssue',
1835
+ 'PATCH',
1836
+ R + '/issues/{number}',
1837
+ 'issues:write',
1838
+ issue,
1839
+ z.object({
1840
+ title: title.optional(),
1841
+ body: body.optional(),
1842
+ state: z.enum(['open', 'closed']).optional(),
1843
+ labels: labels.optional(),
1844
+ }),
1845
+ 'no-store',
1846
+ ),
1847
+ route(
1848
+ 'issueComments',
1849
+ 'GET',
1850
+ R + '/issues/{number}/comments',
1851
+ 'repo:read',
1852
+ z.array(comment),
1853
+ empty,
1854
+ 'index',
1855
+ true,
1856
+ pagination,
1857
+ ),
1858
+ route(
1859
+ 'createIssueComment',
1860
+ 'POST',
1861
+ R + '/issues/{number}/comments',
1862
+ 'issues:write',
1863
+ comment,
1864
+ z.object({ body: body.min(1) }),
1865
+ 'no-store',
1866
+ true,
1867
+ empty,
1868
+ 201,
1869
+ ),
1870
+ route(
1871
+ 'labels',
1872
+ 'GET',
1873
+ R + '/labels',
1874
+ 'repo:read',
1875
+ z.array(label),
1876
+ empty,
1877
+ 'index',
1878
+ true,
1879
+ pagination,
1880
+ ),
1881
+ route(
1882
+ 'pulls',
1883
+ 'GET',
1884
+ R + '/pulls',
1885
+ 'repo:read',
1886
+ z.array(pull),
1887
+ empty,
1888
+ 'index',
1889
+ true,
1890
+ listing,
1891
+ ),
1892
+ route(
1893
+ 'pull',
1894
+ 'GET',
1895
+ R + '/pulls/{number}',
1896
+ 'repo:read',
1897
+ pull,
1898
+ empty,
1899
+ 'index',
1900
+ ),
1901
+ route(
1902
+ 'createPull',
1903
+ 'POST',
1904
+ R + '/pulls',
1905
+ 'pulls:write',
1906
+ pull,
1907
+ z.object({
1908
+ title,
1909
+ body: body.default(''),
1910
+ head: text.min(1),
1911
+ base: text.min(1),
1912
+ }),
1913
+ 'no-store',
1914
+ true,
1915
+ empty,
1916
+ 201,
1917
+ ),
1918
+ route(
1919
+ 'updatePull',
1920
+ 'PATCH',
1921
+ R + '/pulls/{number}',
1922
+ 'pulls:write',
1923
+ pull,
1924
+ z.object({
1925
+ title: title.optional(),
1926
+ body: body.optional(),
1927
+ state: z.enum(['open', 'closed']).optional(),
1928
+ base: text.optional(),
1929
+ }),
1930
+ 'no-store',
1931
+ ),
1932
+ route(
1933
+ 'pullFiles',
1934
+ 'GET',
1935
+ R + '/pulls/{number}/files',
1936
+ 'repo:read',
1937
+ z.array(fileDiff),
1938
+ empty,
1939
+ 'resolved-hash',
1940
+ true,
1941
+ pagination,
1942
+ ),
1943
+ route(
1944
+ 'pullReviews',
1945
+ 'GET',
1946
+ R + '/pulls/{number}/reviews',
1947
+ 'repo:read',
1948
+ z.array(review),
1949
+ empty,
1950
+ 'index',
1951
+ true,
1952
+ pagination,
1953
+ ),
1954
+ route(
1955
+ 'createReview',
1956
+ 'POST',
1957
+ R + '/pulls/{number}/reviews',
1958
+ 'pulls:write',
1959
+ review,
1960
+ z.object({
1961
+ body: body.default(''),
1962
+ event: z.enum(['APPROVE', 'REQUEST_CHANGES', 'COMMENT']),
1963
+ }),
1964
+ 'no-store',
1965
+ true,
1966
+ empty,
1967
+ 201,
1968
+ ),
1969
+ route(
1970
+ 'pullComments',
1971
+ 'GET',
1972
+ R + '/pulls/{number}/comments',
1973
+ 'repo:read',
1974
+ z.array(
1975
+ comment.extend({
1976
+ path: text,
1977
+ line: integer,
1978
+ side: z.enum(['LEFT', 'RIGHT']),
1979
+ commit_id: sha,
1980
+ }),
1981
+ ),
1982
+ empty,
1983
+ 'index',
1984
+ true,
1985
+ pagination,
1986
+ ),
1987
+ route(
1988
+ 'createPullComment',
1989
+ 'POST',
1990
+ R + '/pulls/{number}/comments',
1991
+ 'pulls:write',
1992
+ comment.extend({
1993
+ path: text,
1994
+ line: integer,
1995
+ side: z.enum(['LEFT', 'RIGHT']),
1996
+ commit_id: sha,
1997
+ }),
1998
+ z.object({
1999
+ body: body.min(1),
2000
+ path: text.min(1),
2001
+ line: integer.positive(),
2002
+ side: z.enum(['LEFT', 'RIGHT']).default('RIGHT'),
2003
+ commit_id: sha,
2004
+ }),
2005
+ 'no-store',
2006
+ true,
2007
+ empty,
2008
+ 201,
2009
+ ),
2010
+ route(
2011
+ 'mergePull',
2012
+ 'PUT',
2013
+ R + '/pulls/{number}/merge',
2014
+ 'pulls:write',
2015
+ z.object({
2016
+ sha: sha.nullable(),
2017
+ merged: z.literal(false),
2018
+ message: text,
2019
+ queued: z.literal(true),
2020
+ }),
2021
+ z.object({
2022
+ sha: sha.optional(),
2023
+ merge_method: z.literal('merge').optional(),
2024
+ commit_title: text.optional(),
2025
+ commit_message: text.optional(),
2026
+ }),
2027
+ 'no-store',
2028
+ false,
2029
+ empty,
2030
+ 202,
2031
+ ),
2032
+ route(
2033
+ 'mergeQueue',
2034
+ 'GET',
2035
+ R + '/merge-queue',
2036
+ 'repo:read',
2037
+ z.object({ queue: z.array(integer) }),
2038
+ empty,
2039
+ 'index',
2040
+ false,
2041
+ ),
2042
+ route(
2043
+ 'commitChanges',
2044
+ 'GET',
2045
+ R + '/changes/{sha}',
2046
+ 'repo:read',
2047
+ change,
2048
+ empty,
2049
+ 'resolved-hash',
2050
+ false,
2051
+ ),
2052
+ route(
2053
+ 'pullChanges',
2054
+ 'GET',
2055
+ R + '/pulls/{number}/changes',
2056
+ 'repo:read',
2057
+ change,
2058
+ empty,
2059
+ 'resolved-hash',
2060
+ false,
2061
+ ),
2062
+ route(
2063
+ 'health',
2064
+ 'GET',
2065
+ R + '/health',
2066
+ 'repo:read',
2067
+ health,
2068
+ empty,
2069
+ 'resolved-hash',
2070
+ false,
2071
+ reference,
2072
+ ),
2073
+ route(
2074
+ 'healthAt',
2075
+ 'GET',
2076
+ R + '/health/{sha}',
2077
+ 'repo:read',
2078
+ health,
2079
+ empty,
2080
+ 'immutable',
2081
+ false,
2082
+ ),
2083
+ route(
2084
+ 'searchCode',
2085
+ 'GET',
2086
+ '/search/code',
2087
+ 'repo:read',
2088
+ z.object({
2089
+ total_count: integer,
2090
+ incomplete_results: z.boolean(),
2091
+ items: z.array(
2092
+ z.object({
2093
+ name: text,
2094
+ path: text,
2095
+ sha,
2096
+ text_matches: z.array(
2097
+ z.object({
2098
+ fragment: text,
2099
+ matches: z.array(
2100
+ z.object({ indices: z.tuple([integer, integer]), text }),
2101
+ ),
2102
+ }),
2103
+ ),
2104
+ repository,
2105
+ url,
2106
+ html_url: url,
2107
+ }),
2108
+ ),
2109
+ }),
2110
+ empty,
2111
+ 'index',
2112
+ false,
2113
+ pagination.extend({ q: text.min(1).max(2000) }),
2114
+ ),
2115
+ route(
2116
+ 'tokens',
2117
+ 'GET',
2118
+ '/user/tokens',
2119
+ 'admin',
2120
+ z.array(token),
2121
+ empty,
2122
+ 'no-store',
2123
+ false,
2124
+ ),
2125
+ route(
2126
+ 'createToken',
2127
+ 'POST',
2128
+ '/user/tokens',
2129
+ 'admin',
2130
+ token.extend({ token: text }),
2131
+ z.object({
2132
+ label: text.max(100).default(''),
2133
+ scopes: z.array(z.enum(SCOPES)),
2134
+ repos: z.array(text.regex(/^[a-z0-9-]+\/[a-z0-9._-]+$/i)).optional(),
2135
+ }),
2136
+ 'no-store',
2137
+ false,
2138
+ empty,
2139
+ 201,
2140
+ ),
2141
+ route(
2142
+ 'deleteToken',
2143
+ 'DELETE',
2144
+ '/user/tokens/{id}',
2145
+ 'admin',
2146
+ ok,
2147
+ empty,
2148
+ 'no-store',
2149
+ false,
2150
+ ),
2151
+ route(
2152
+ 'agents',
2153
+ 'GET',
2154
+ '/agents',
2155
+ 'agents',
2156
+ z.array(agent),
2157
+ empty,
2158
+ 'no-store',
2159
+ false,
2160
+ ),
2161
+ route(
2162
+ 'deleteAgent',
2163
+ 'DELETE',
2164
+ '/agents/{label}',
2165
+ 'agents',
2166
+ ok,
2167
+ empty,
2168
+ 'no-store',
2169
+ false,
2170
+ ),
2171
+ route(
2172
+ 'agentRequests',
2173
+ 'GET',
2174
+ '/agents/requests',
2175
+ 'agents',
2176
+ z.array(join),
2177
+ empty,
2178
+ 'no-store',
2179
+ false,
2180
+ ),
2181
+ route(
2182
+ 'createAgentRequest',
2183
+ 'POST',
2184
+ '/agents/requests',
2185
+ 'agents',
2186
+ join,
2187
+ z.object({
2188
+ sponsor: text,
2189
+ label: text,
2190
+ publicKey: text,
2191
+ repo: text.optional(),
2192
+ grants: z.array(text).default([]),
2193
+ note: text.optional(),
2194
+ }),
2195
+ 'no-store',
2196
+ false,
2197
+ empty,
2198
+ 201,
2199
+ ),
2200
+ route(
2201
+ 'decideAgentRequest',
2202
+ 'PATCH',
2203
+ '/agents/requests/{id}',
2204
+ 'agents',
2205
+ z.object({
2206
+ status: z.enum(['approved', 'denied']),
2207
+ agent: text.optional(),
2208
+ grants: z.array(text).optional(),
2209
+ }),
2210
+ z.object({
2211
+ decision: z.enum(['approve', 'deny']),
2212
+ grants: z.array(text).default([]),
2213
+ }),
2214
+ 'no-store',
2215
+ false,
2216
+ ),
2217
+ route(
2218
+ 'actionRuns',
2219
+ 'GET',
2220
+ R + '/actions/runs',
2221
+ 'repo:read',
2222
+ z.object({ total_count: integer, workflow_runs: z.array(actionRun) }),
2223
+ empty,
2224
+ 'index',
2225
+ true,
2226
+ pagination,
2227
+ ),
2228
+ route(
2229
+ 'actionRun',
2230
+ 'GET',
2231
+ R + '/actions/runs/{run}',
2232
+ 'repo:read',
2233
+ actionRun,
2234
+ empty,
2235
+ 'index',
2236
+ ),
2237
+ route(
2238
+ 'actionJobs',
2239
+ 'GET',
2240
+ R + '/actions/runs/{run}/jobs',
2241
+ 'repo:read',
2242
+ z.object({ total_count: integer, jobs: z.array(actionJob) }),
2243
+ empty,
2244
+ 'index',
2245
+ true,
2246
+ pagination,
2247
+ ),
2248
+ route(
2249
+ 'actionJob',
2250
+ 'GET',
2251
+ R + '/actions/jobs/{job}',
2252
+ 'repo:read',
2253
+ actionJob,
2254
+ empty,
2255
+ 'index',
2256
+ ),
2257
+ route(
2258
+ 'actionLogs',
2259
+ 'GET',
2260
+ R + '/actions/runs/{run}/logs',
2261
+ 'repo:read',
2262
+ z.object({
2263
+ logs: z.array(
2264
+ z.object({ job: integer, step: integer, seq: integer, text }),
2265
+ ),
2266
+ }),
2267
+ empty,
2268
+ 'index',
2269
+ false,
2270
+ z.object({
2271
+ job: z.coerce.number().int().positive().optional(),
2272
+ step: z.coerce.number().int().min(0).optional(),
2273
+ after: z.coerce.number().int().min(-1).default(-1),
2274
+ }).refine(q => (q.job === undefined) === (q.step === undefined), 'Use job and step together'),
2275
+ ),
2276
+ route(
2277
+ 'actionRerun',
2278
+ 'POST',
2279
+ R + '/actions/runs/{run}/rerun',
2280
+ 'actions',
2281
+ z.object({ id: integer }),
2282
+ empty,
2283
+ 'no-store',
2284
+ false,
2285
+ empty,
2286
+ 201,
2287
+ ),
2288
+ route(
2289
+ 'actionCancel',
2290
+ 'POST',
2291
+ R + '/actions/runs/{run}/cancel',
2292
+ 'actions',
2293
+ ok,
2294
+ empty,
2295
+ 'no-store',
2296
+ ),
2297
+ route(
2298
+ 'actionRunners',
2299
+ 'GET',
2300
+ R + '/actions/runners',
2301
+ 'actions',
2302
+ z.object({ total_count: integer, runners: z.array(runner) }),
2303
+ empty,
2304
+ 'no-store',
2305
+ true,
2306
+ pagination,
2307
+ ),
2308
+ route(
2309
+ 'actionRegister',
2310
+ 'POST',
2311
+ R + '/actions/runners',
2312
+ 'actions',
2313
+ z.object({ id: text, token: text }),
2314
+ runnerRegistration
2315
+ .omit({ group: true })
2316
+ .extend({ registration_token: text.optional() }),
2317
+ 'no-store',
2318
+ false,
2319
+ empty,
2320
+ 201,
2321
+ ),
2322
+ route(
2323
+ 'actionPatch',
2324
+ 'PATCH',
2325
+ R + '/actions/runners/{runner}',
2326
+ 'actions',
2327
+ ok,
2328
+ z.object({ labels: z.array(text.regex(/^[\w.-]{1,64}$/)).max(32) }),
2329
+ 'no-store',
2330
+ ),
2331
+ route(
2332
+ 'actionRemove',
2333
+ 'DELETE',
2334
+ R + '/actions/runners/{runner}',
2335
+ 'actions',
2336
+ ok,
2337
+ empty,
2338
+ 'no-store',
2339
+ false,
2340
+ ),
2341
+ route(
2342
+ 'actionDispatch',
2343
+ 'POST',
2344
+ R + '/actions/workflows/{workflow}/dispatches',
2345
+ 'actions',
2346
+ z.object({ id: integer }),
2347
+ z.object({ ref: text.min(1) }),
2348
+ 'no-store',
2349
+ false,
2350
+ empty,
2351
+ 201,
2352
+ ),
2353
+ route(
2354
+ 'runnerPoll',
2355
+ 'POST',
2356
+ R + '/actions/runners/poll',
2357
+ 'actions',
2358
+ z.object({ job: assignment.nullable() }),
2359
+ z.object({ wait: z.number().min(0).max(20000).default(20000) }),
2360
+ 'no-store',
2361
+ false,
2362
+ ),
2363
+ route(
2364
+ 'runnerHeartbeat',
2365
+ 'POST',
2366
+ R + '/actions/runners/heartbeat',
2367
+ 'actions',
2368
+ z.object({ cancel: z.boolean() }),
2369
+ z.object({ job: integer.nullable(), lease: text.nullable() }),
2370
+ 'no-store',
2371
+ false,
2372
+ ),
2373
+ route(
2374
+ 'runnerLogs',
2375
+ 'POST',
2376
+ R + '/actions/runners/logs',
2377
+ 'actions',
2378
+ ok,
2379
+ z
2380
+ .object({
2381
+ job: integer,
2382
+ lease: text,
2383
+ step: integer,
2384
+ batch: integer,
2385
+ lines: z.array(text),
2386
+ })
2387
+ .passthrough(),
2388
+ 'no-store',
2389
+ false,
2390
+ ),
2391
+ route(
2392
+ 'runnerStep',
2393
+ 'POST',
2394
+ R + '/actions/runners/step',
2395
+ 'actions',
2396
+ ok,
2397
+ z
2398
+ .object({
2399
+ job: integer,
2400
+ lease: text,
2401
+ step: integer,
2402
+ status: z.enum([
2403
+ 'running',
2404
+ 'success',
2405
+ 'failure',
2406
+ 'cancelled',
2407
+ 'skipped',
2408
+ ]),
2409
+ exit: integer.nullable(),
2410
+ })
2411
+ .passthrough(),
2412
+ 'no-store',
2413
+ false,
2414
+ ),
2415
+ route(
2416
+ 'runnerFinish',
2417
+ 'POST',
2418
+ R + '/actions/runners/finish',
2419
+ 'actions',
2420
+ ok,
2421
+ z
2422
+ .object({
2423
+ job: integer,
2424
+ lease: text,
2425
+ status: z.enum(['success', 'failure', 'cancelled']),
2426
+ reason: text.nullable(),
2427
+ })
2428
+ .passthrough(),
2429
+ 'no-store',
2430
+ false,
2431
+ ),
2432
+ ] as const
2433
+ export type Route = (typeof routes)[number]
2434
+ export type Operation = Route['id']
2435
+ export type Input<I extends Operation> = z.input<
2436
+ Extract<Route, { id: I }>['input']
2437
+ >
2438
+ export type Output<I extends Operation> = z.output<
2439
+ Extract<Route, { id: I }>['output']
2440
+ >
2441
+ export type Query<I extends Operation> = z.input<
2442
+ Extract<Route, { id: I }>['query']
2443
+ >
2444
+ export const schemas = {
2445
+ repository,
2446
+ comment,
2447
+ issue,
2448
+ pull,
2449
+ review,
2450
+ commit,
2451
+ change,
2452
+ health,
2453
+ ok,
2454
+ }