@defrex/autobuild 0.8.0 → 0.10.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 (182) hide show
  1. package/README.md +1 -1
  2. package/SPEC.md +323 -26
  3. package/bin/ab-build-runner.ts +8 -2
  4. package/docs/architecture.md +166 -14
  5. package/docs/assets/headline-wide.png +0 -0
  6. package/docs/configuration.md +175 -28
  7. package/docs/hosted-dispatcher.md +69 -13
  8. package/docs/operator-api.md +2 -2
  9. package/docs/remote-store-protocol.md +204 -16
  10. package/docs/remote-ticket-protocol.md +1 -1
  11. package/docs/setup.md +12 -9
  12. package/docs/website.md +14 -0
  13. package/package.json +45 -23
  14. package/packages/core/src/cli/artifact.ts +130 -6
  15. package/packages/core/src/cli/binary.ts +9 -1
  16. package/packages/core/src/cli/build-control.ts +110 -13
  17. package/packages/core/src/cli/context.ts +46 -0
  18. package/packages/core/src/cli/dashboard/facts.ts +215 -0
  19. package/packages/core/src/cli/dashboard/frame-parse.ts +223 -0
  20. package/packages/core/src/cli/dashboard/model.ts +141 -153
  21. package/packages/core/src/cli/dashboard/poll.ts +76 -12
  22. package/packages/core/src/cli/dashboard/render.ts +34 -5
  23. package/packages/core/src/cli/dispatch-frontend.ts +54 -5
  24. package/packages/core/src/cli/dispatch-process.ts +1 -13
  25. package/packages/core/src/cli/dispatch.ts +392 -75
  26. package/packages/core/src/cli/harvest.ts +122 -8
  27. package/packages/core/src/cli/help.ts +62 -9
  28. package/packages/core/src/cli/init-readiness-remote.ts +110 -0
  29. package/packages/core/src/cli/init-readiness-shared.ts +72 -0
  30. package/packages/core/src/cli/init-validation.ts +266 -222
  31. package/packages/core/src/cli/installation.ts +50 -8
  32. package/packages/core/src/cli/main.ts +70 -11
  33. package/packages/core/src/cli/mcp.ts +23 -1
  34. package/packages/core/src/cli/plugin.ts +7 -4
  35. package/packages/core/src/cli/remote-poll.ts +277 -0
  36. package/packages/core/src/cli/repo-state.ts +22 -0
  37. package/packages/core/src/cli/repository-status.ts +39 -1
  38. package/packages/core/src/cli/self-update.ts +77 -2
  39. package/packages/core/src/cli/status.ts +150 -28
  40. package/packages/core/src/cli/terminals.ts +2 -1
  41. package/packages/core/src/cli/ticket-assets.ts +247 -0
  42. package/packages/core/src/cli/ticket.ts +453 -8
  43. package/packages/core/src/cli/wait.ts +157 -41
  44. package/packages/core/src/cli/watch.ts +138 -168
  45. package/packages/core/src/config/live.ts +23 -0
  46. package/packages/core/src/config/pipeline-source.ts +388 -0
  47. package/packages/core/src/config/schema.ts +251 -19
  48. package/packages/core/src/events/catalog.ts +1 -0
  49. package/packages/core/src/events/globs.ts +47 -0
  50. package/packages/core/src/events/payloads.ts +52 -2
  51. package/packages/core/src/events/repository.ts +52 -1
  52. package/packages/core/src/events/sessions.ts +69 -10
  53. package/packages/core/src/events/workspace-remote.ts +12 -0
  54. package/packages/core/src/integration/harness.ts +115 -2
  55. package/packages/core/src/kernel/__snapshots__/reducer-registry.test.ts.snap +1369 -0
  56. package/packages/core/src/kernel/auto-merge-default.ts +157 -0
  57. package/packages/core/src/kernel/auto-merge.ts +99 -22
  58. package/packages/core/src/kernel/dispatch-settings.ts +42 -17
  59. package/packages/core/src/kernel/dispatch-status.ts +23 -0
  60. package/packages/core/src/kernel/engine.ts +9 -438
  61. package/packages/core/src/kernel/generators/build-log.ts +259 -0
  62. package/packages/core/src/kernel/generators/repository-journals.ts +206 -0
  63. package/packages/core/src/kernel/generators/session-log.ts +72 -0
  64. package/packages/core/src/kernel/harvest.ts +62 -18
  65. package/packages/core/src/kernel/incremental-contract.ts +75 -0
  66. package/packages/core/src/kernel/incremental-fixtures.ts +211 -0
  67. package/packages/core/src/kernel/incremental.ts +53 -0
  68. package/packages/core/src/kernel/log-index.ts +620 -0
  69. package/packages/core/src/kernel/phases.ts +16 -2
  70. package/packages/core/src/kernel/pr-attachments.ts +164 -46
  71. package/packages/core/src/kernel/reducer-registry.ts +164 -0
  72. package/packages/core/src/kernel/reducer.ts +254 -73
  73. package/packages/core/src/operator/annotations.ts +6 -0
  74. package/packages/core/src/operator/control.ts +19 -5
  75. package/packages/core/src/operator/index.ts +71 -6
  76. package/packages/core/src/operator/query.ts +253 -24
  77. package/packages/core/src/operator/read-view.ts +98 -0
  78. package/packages/core/src/operator/registry.ts +55 -10
  79. package/packages/core/src/operator/requests.ts +9 -6
  80. package/packages/core/src/operator/sandbox-host.ts +140 -0
  81. package/packages/core/src/operator/sandbox.ts +247 -14
  82. package/packages/core/src/operator/ticket-source-backend.ts +47 -0
  83. package/packages/core/src/orchestrator/approvals.ts +115 -0
  84. package/packages/core/src/orchestrator/conversation.ts +167 -0
  85. package/packages/core/src/orchestrator/model.ts +86 -0
  86. package/packages/core/src/orchestrator/prompt.ts +61 -0
  87. package/packages/core/src/orchestrator/tools.ts +117 -0
  88. package/packages/core/src/orchestrator/turn-runner.ts +457 -0
  89. package/packages/core/src/plugin-sdk/index.ts +51 -1
  90. package/packages/core/src/plugins/load.ts +135 -7
  91. package/packages/core/src/plugins/manifest.ts +183 -10
  92. package/packages/core/src/plugins/registry.ts +73 -4
  93. package/packages/core/src/ports/forge/create.ts +1 -1
  94. package/packages/core/src/ports/forge/fake.ts +31 -0
  95. package/packages/core/src/ports/forge/github-transport.ts +13 -2
  96. package/packages/core/src/ports/forge/github.ts +13 -2
  97. package/packages/core/src/ports/forge/local-git.ts +31 -1
  98. package/packages/core/src/ports/runner/claude.ts +2 -2
  99. package/packages/core/src/ports/runner/codex.ts +6 -2
  100. package/packages/core/src/ports/runner/fake.ts +7 -1
  101. package/packages/core/src/ports/runner/pi.ts +8 -6
  102. package/packages/core/src/ports/runner/provider-error.ts +13 -3
  103. package/packages/core/src/ports/tickets/fake.ts +5 -1
  104. package/packages/core/src/ports/tickets/file.ts +169 -48
  105. package/packages/core/src/ports/tickets/{remote-index.ts → hosted-index.ts} +3 -2
  106. package/packages/core/src/ports/tickets/linear.ts +33 -1
  107. package/packages/core/src/ports/tickets/operations.ts +1 -1
  108. package/packages/core/src/ports/tickets/remote.ts +8 -1
  109. package/packages/core/src/ports/types.ts +49 -3
  110. package/packages/core/src/ports/workspace/builtin-capabilities.ts +114 -0
  111. package/packages/core/src/ports/workspace/create.ts +74 -39
  112. package/packages/core/src/ports/workspace/distribution-archive.ts +171 -12
  113. package/packages/core/src/ports/workspace/fake.ts +169 -4
  114. package/packages/core/src/ports/workspace/git-worktree.ts +246 -26
  115. package/packages/core/src/ports/workspace/github-origin.ts +36 -0
  116. package/packages/core/src/ports/workspace/operator-sandbox.ts +7 -1
  117. package/packages/core/src/ports/workspace/provider-capabilities.ts +171 -0
  118. package/packages/core/src/ports/workspace/vercel-capabilities.ts +110 -0
  119. package/packages/core/src/ports/workspace/vercel-sandbox.ts +142 -114
  120. package/packages/core/src/processes/build-child.ts +17 -2
  121. package/packages/core/src/processes/build-execution-state.ts +68 -15
  122. package/packages/core/src/processes/build-runner.ts +238 -93
  123. package/packages/core/src/processes/dispatcher-selectors.ts +123 -0
  124. package/packages/core/src/processes/dispatcher.ts +501 -201
  125. package/packages/core/src/processes/execution-settlement.ts +72 -39
  126. package/packages/core/src/processes/harvest-child.ts +5 -0
  127. package/packages/core/src/processes/harvest-execution-state.ts +41 -29
  128. package/packages/core/src/processes/harvest-runner.ts +66 -19
  129. package/packages/core/src/processes/harvest.ts +196 -24
  130. package/packages/core/src/processes/infrastructure-failure-budget.ts +31 -18
  131. package/packages/core/src/processes/orchestrator-tick.ts +360 -0
  132. package/packages/core/src/processes/publication-state.ts +164 -52
  133. package/packages/core/src/processes/repo-view.ts +1436 -0
  134. package/packages/core/src/processes/sandbox-state.ts +36 -2
  135. package/packages/core/src/processes/tick-state.ts +33 -0
  136. package/packages/core/src/store/adapter.ts +41 -0
  137. package/packages/core/src/store/build-scope.ts +90 -0
  138. package/packages/core/src/store/contract.ts +1205 -0
  139. package/packages/core/src/store/digest.ts +102 -0
  140. package/packages/core/src/store/local/schema.ts +46 -2
  141. package/packages/core/src/store/local/store.ts +445 -4
  142. package/packages/core/src/store/memory.ts +246 -0
  143. package/packages/core/src/store/new-build.ts +17 -0
  144. package/packages/core/src/store/phase-session.ts +94 -0
  145. package/packages/core/src/store/remote/client.ts +310 -2
  146. package/packages/core/src/store/remote/index.ts +14 -2
  147. package/packages/core/src/store/remote/protocol.ts +115 -12
  148. package/packages/core/src/store/remote/version.ts +6 -2
  149. package/packages/core/src/store/repo-state-events.ts +205 -0
  150. package/packages/core/src/store/retention.ts +7 -0
  151. package/packages/core/src/store/session-handle.ts +94 -0
  152. package/packages/core/src/{sessions/reducer.ts → store/session-reducer.ts} +79 -19
  153. package/packages/core/src/store/snapshots.ts +88 -0
  154. package/packages/core/src/store/streams/session-writer.ts +42 -2
  155. package/packages/core/src/store/streams/wait.ts +4 -5
  156. package/packages/core/src/store/ticket-assets.ts +458 -0
  157. package/packages/core/src/store/types.ts +160 -1
  158. package/packages/core/src/testing/index.ts +59 -0
  159. package/skills/code-review/SKILL.md +5 -1
  160. package/skills/guide/SKILL.md +152 -40
  161. package/skills/guide/references/operator-api.md +2 -2
  162. package/skills/guide/references/plugin-authoring.md +17 -0
  163. package/skills/guide/references/remote-store-protocol.md +204 -16
  164. package/skills/guide/references/remote-ticket-protocol.md +1 -1
  165. package/skills/guide/references/setup.md +12 -9
  166. package/skills/implement/SKILL.md +3 -0
  167. package/skills/operate/SKILL.md +126 -0
  168. package/skills/plan/SKILL.md +4 -0
  169. package/skills/plan-review/SKILL.md +5 -1
  170. package/skills/spec/SKILL.md +46 -3
  171. package/skills/tickets/SKILL.md +57 -5
  172. package/packages/core/src/cli/dashboard/frame-image.ts +0 -373
  173. package/packages/core/src/cli/store-opening.contract.ts +0 -289
  174. package/packages/core/src/cli/testkit.ts +0 -194
  175. package/packages/core/src/markdown.ts +0 -67
  176. package/packages/core/src/operator/client.ts +0 -311
  177. package/packages/core/src/operator/server.ts +0 -616
  178. package/packages/core/src/operator/sessions.ts +0 -223
  179. package/packages/core/src/ports/runner/live-contract-fixture.ts +0 -176
  180. package/packages/core/src/ports/tickets/remote-server.ts +0 -185
  181. package/packages/core/src/store/remote/server.ts +0 -923
  182. package/packages/core/src/testing/store-failures.ts +0 -32
@@ -1,311 +0,0 @@
1
- import type { BuildControlResult } from '../cli/build-control'
2
- import type { BulkControlSummary } from '../cli/bulk-control'
3
- import type { HarvestStatusView } from '../cli/harvest'
4
- import type { RepositoryStatus } from '../cli/repository-status'
5
- import type { BuildSummary } from '../cli/status'
6
- import {
7
- AUTOBUILD_VERSION,
8
- AUTOBUILD_VERSION_HEADER,
9
- REMOTE_STORE_PROTOCOL_VERSION,
10
- REMOTE_STORE_PROTOCOL_VERSION_HEADER,
11
- } from '../store/remote/version'
12
- import {
13
- operatorErrorSchema,
14
- type OperatorAnswerRequest,
15
- type OperatorBuildControlRequest,
16
- type OperatorTicketBlockerRequest,
17
- type OperatorTicketCreateRequest,
18
- type OperatorTicketMoveRequest,
19
- type OperatorTicketUpdateRequest,
20
- } from './protocol'
21
- import type { OperatorBuildView, OperatorDashboardSnapshot } from './query'
22
- import type { OperatorTicketDetail, OperatorTicketQueue } from './tickets'
23
- import type { OperatorSessionView } from './sessions'
24
- import type { SessionRecord } from '../store/types'
25
- import type { StreamRead } from '../store/streams/types'
26
- import type {
27
- OperatorSessionApprovalRequest,
28
- OperatorSessionCreateRequest,
29
- OperatorSessionMessageRequest,
30
- OperatorSessionWakeRequest,
31
- } from './protocol'
32
-
33
- export class OperatorApiError extends Error {
34
- constructor(
35
- readonly status: number,
36
- readonly kind: string,
37
- readonly code?: string,
38
- readonly progress?: unknown,
39
- ) {
40
- super(kind)
41
- this.name = 'OperatorApiError'
42
- }
43
- }
44
-
45
- export interface OperatorApiClientOptions {
46
- url: string
47
- token: string
48
- fetchFn?: typeof fetch
49
- }
50
-
51
- export interface DownloadedArtifact {
52
- content: Uint8Array
53
- kind: string
54
- revision: number
55
- blobRef: string
56
- disposition?: string
57
- }
58
-
59
- export class OperatorApiClient {
60
- private readonly base: string
61
- private readonly fetchFn: typeof fetch
62
- constructor(private readonly options: OperatorApiClientOptions) {
63
- this.base = options.url.replace(/\/+$/, '')
64
- this.fetchFn = options.fetchFn ?? fetch
65
- }
66
-
67
- private repoPath(repo: string, suffix: string): string {
68
- return `/operator/v1/repos/${encodeURIComponent(repo)}/${suffix}`
69
- }
70
-
71
- private async request<T>(repo: string, suffix: string, init: RequestInit = {}): Promise<T> {
72
- const headers = new Headers(init.headers)
73
- headers.set(AUTOBUILD_VERSION_HEADER, AUTOBUILD_VERSION)
74
- headers.set(REMOTE_STORE_PROTOCOL_VERSION_HEADER, REMOTE_STORE_PROTOCOL_VERSION)
75
- headers.set('authorization', `Bearer ${this.options.token}`)
76
- if (init.body !== undefined) headers.set('content-type', 'application/json')
77
- const response = await this.fetchFn(`${this.base}${this.repoPath(repo, suffix)}`, {
78
- ...init,
79
- headers,
80
- })
81
- if (!response.ok) {
82
- const parsed = operatorErrorSchema.safeParse(await response.json().catch(() => null))
83
- if (!parsed.success) throw new Error(`operator API returned HTTP ${response.status}`)
84
- const error = new OperatorApiError(
85
- response.status,
86
- parsed.data.kind,
87
- parsed.data.code,
88
- parsed.data.progress,
89
- )
90
- error.message = parsed.data.error
91
- throw error
92
- }
93
- return (await response.json()) as T
94
- }
95
-
96
- listBuilds(repo: string, scope: 'active' | 'queued' | 'all' = 'active'): Promise<BuildSummary[]> {
97
- return this.request(repo, `builds?scope=${scope}`)
98
- }
99
- getBuild(repo: string, slug: string): Promise<OperatorBuildView> {
100
- return this.request(repo, `builds/${encodeURIComponent(slug)}`)
101
- }
102
- dashboard(repo: string): Promise<OperatorDashboardSnapshot> {
103
- return this.request(repo, 'dashboard')
104
- }
105
- repositoryStatus(repo: string): Promise<RepositoryStatus> {
106
- return this.request(repo, 'status')
107
- }
108
- harvestStatus(repo: string): Promise<HarvestStatusView> {
109
- return this.request(repo, 'harvest/status')
110
- }
111
- listTickets(
112
- repo: string,
113
- filters: { state?: string; labels?: string[] } = {},
114
- ): Promise<OperatorTicketQueue> {
115
- const query = new URLSearchParams()
116
- if (filters.state !== undefined) query.set('state', filters.state)
117
- for (const label of filters.labels ?? []) query.append('label', label)
118
- const suffix = query.size > 0 ? `tickets?${query}` : 'tickets'
119
- return this.request(repo, suffix)
120
- }
121
- getTicket(repo: string, id: string): Promise<OperatorTicketDetail> {
122
- return this.request(repo, `tickets/${encodeURIComponent(id)}`)
123
- }
124
- createTicket(repo: string, request: OperatorTicketCreateRequest): Promise<OperatorTicketDetail> {
125
- return this.request(repo, 'tickets', { method: 'POST', body: JSON.stringify(request) })
126
- }
127
- updateTicket(
128
- repo: string,
129
- id: string,
130
- request: OperatorTicketUpdateRequest,
131
- ): Promise<OperatorTicketDetail> {
132
- return this.request(repo, `tickets/${encodeURIComponent(id)}`, {
133
- method: 'PATCH',
134
- body: JSON.stringify(request),
135
- })
136
- }
137
- moveTicket(
138
- repo: string,
139
- id: string,
140
- request: OperatorTicketMoveRequest,
141
- ): Promise<OperatorTicketDetail> {
142
- return this.request(repo, `tickets/${encodeURIComponent(id)}/move`, {
143
- method: 'POST',
144
- body: JSON.stringify(request),
145
- })
146
- }
147
- blockTicket(
148
- repo: string,
149
- id: string,
150
- request: OperatorTicketBlockerRequest,
151
- ): Promise<OperatorTicketDetail> {
152
- return this.request(repo, `tickets/${encodeURIComponent(id)}/block`, {
153
- method: 'POST',
154
- body: JSON.stringify(request),
155
- })
156
- }
157
- unblockTicket(
158
- repo: string,
159
- id: string,
160
- request: OperatorTicketBlockerRequest,
161
- ): Promise<OperatorTicketDetail> {
162
- return this.request(repo, `tickets/${encodeURIComponent(id)}/unblock`, {
163
- method: 'POST',
164
- body: JSON.stringify(request),
165
- })
166
- }
167
- listSessions(repo: string): Promise<SessionRecord[]> {
168
- return this.request(repo, 'sessions')
169
- }
170
- createSession(repo: string, request: OperatorSessionCreateRequest): Promise<SessionRecord> {
171
- return this.request(repo, 'sessions', { method: 'POST', body: JSON.stringify(request) })
172
- }
173
- getSession(repo: string, sid: string): Promise<OperatorSessionView> {
174
- return this.request(repo, `sessions/${encodeURIComponent(sid)}`)
175
- }
176
- postSessionMessage(
177
- repo: string,
178
- sid: string,
179
- request: OperatorSessionMessageRequest,
180
- ): Promise<{ ok: boolean }> {
181
- return this.request(repo, `sessions/${encodeURIComponent(sid)}/messages`, {
182
- method: 'POST',
183
- body: JSON.stringify(request),
184
- })
185
- }
186
- setSessionWake(
187
- repo: string,
188
- sid: string,
189
- request: OperatorSessionWakeRequest,
190
- ): Promise<{ ok: boolean }> {
191
- return this.request(repo, `sessions/${encodeURIComponent(sid)}/wake`, {
192
- method: 'PUT',
193
- body: JSON.stringify(request),
194
- })
195
- }
196
- answerSessionApproval(
197
- repo: string,
198
- sid: string,
199
- request: OperatorSessionApprovalRequest,
200
- ): Promise<{ ok: boolean }> {
201
- return this.request(repo, `sessions/${encodeURIComponent(sid)}/approvals`, {
202
- method: 'POST',
203
- body: JSON.stringify(request),
204
- })
205
- }
206
- archiveSession(repo: string, sid: string): Promise<{ ok: boolean }> {
207
- return this.request(repo, `sessions/${encodeURIComponent(sid)}/archive`, {
208
- method: 'POST',
209
- })
210
- }
211
- readSessionTurnStream(
212
- repo: string,
213
- sid: string,
214
- turn: string,
215
- opts: { since?: number; waitSeconds?: number } = {},
216
- ): Promise<StreamRead> {
217
- const query = new URLSearchParams({ since: String(opts?.since ?? 0) })
218
- if (opts?.waitSeconds !== undefined) query.set('wait', String(opts.waitSeconds))
219
- return this.request(
220
- repo,
221
- `sessions/${encodeURIComponent(sid)}/turns/${encodeURIComponent(turn)}/stream?${query}`,
222
- )
223
- }
224
- controlBuild(
225
- repo: string,
226
- slug: string,
227
- request: OperatorBuildControlRequest,
228
- ): Promise<BuildControlResult> {
229
- return this.request(repo, `builds/${encodeURIComponent(slug)}/control`, {
230
- method: 'POST',
231
- body: JSON.stringify(request),
232
- })
233
- }
234
- /** The registry's generic protocol face: execute any tool from the closed
235
- * table by name. The body is the tool's input (repo included); failures
236
- * parse into OperatorApiError exactly like the typed routes. */
237
- callTool(repo: string, tool: string, input: unknown): Promise<unknown> {
238
- return this.request(repo, `tools/${encodeURIComponent(tool)}`, {
239
- method: 'POST',
240
- body: JSON.stringify(input),
241
- })
242
- }
243
- answer(repo: string, slug: string, request: OperatorAnswerRequest): Promise<BuildControlResult> {
244
- return this.request(repo, `builds/${encodeURIComponent(slug)}/answer`, {
245
- method: 'POST',
246
- body: JSON.stringify(request),
247
- })
248
- }
249
- setIntake(repo: string, enabled: boolean): Promise<unknown> {
250
- return this.request(repo, 'settings/intake', {
251
- method: 'PUT',
252
- body: JSON.stringify({ enabled }),
253
- })
254
- }
255
- toggleIntake(repo: string): Promise<unknown> {
256
- return this.request(repo, 'settings/intake/toggle', { method: 'POST' })
257
- }
258
- setAutoMergeDefault(repo: string, enabled: boolean): Promise<unknown> {
259
- return this.request(repo, 'settings/auto-merge-default', {
260
- method: 'PUT',
261
- body: JSON.stringify({ enabled }),
262
- })
263
- }
264
- toggleAutoMergeDefault(repo: string): Promise<unknown> {
265
- return this.request(repo, 'settings/auto-merge-default/toggle', { method: 'POST' })
266
- }
267
- bulkControl(repo: string, action: 'pause' | 'resume'): Promise<BulkControlSummary> {
268
- return this.request(repo, 'bulk-control', { method: 'POST', body: JSON.stringify({ action }) })
269
- }
270
- toggleHarvest(repo: string): Promise<unknown> {
271
- return this.request(repo, 'harvest/control', {
272
- method: 'POST',
273
- body: JSON.stringify({ action: 'toggle-gate' }),
274
- })
275
- }
276
- controlHarvestRun(repo: string, run: string): Promise<unknown> {
277
- return this.request(repo, 'harvest/control', {
278
- method: 'POST',
279
- body: JSON.stringify({ action: 'run', run }),
280
- })
281
- }
282
- async downloadArtifact(
283
- repo: string,
284
- slug: string,
285
- kind: string,
286
- rev?: number,
287
- ): Promise<DownloadedArtifact> {
288
- const suffix = `builds/${encodeURIComponent(slug)}/artifacts/${encodeURIComponent(kind)}${rev === undefined ? '' : `?rev=${rev}`}`
289
- const headers = new Headers({
290
- [AUTOBUILD_VERSION_HEADER]: AUTOBUILD_VERSION,
291
- [REMOTE_STORE_PROTOCOL_VERSION_HEADER]: REMOTE_STORE_PROTOCOL_VERSION,
292
- authorization: `Bearer ${this.options.token}`,
293
- })
294
- const response = await this.fetchFn(`${this.base}${this.repoPath(repo, suffix)}`, { headers })
295
- if (!response.ok) {
296
- const parsed = operatorErrorSchema.parse(await response.json())
297
- const error = new OperatorApiError(response.status, parsed.kind, parsed.code, parsed.progress)
298
- error.message = parsed.error
299
- throw error
300
- }
301
- return {
302
- content: new Uint8Array(await response.arrayBuffer()),
303
- kind: response.headers.get('x-autobuild-artifact-kind') ?? kind,
304
- revision: Number(response.headers.get('x-autobuild-artifact-revision')),
305
- blobRef: response.headers.get('x-autobuild-artifact-blob-ref') ?? '',
306
- ...(response.headers.get('content-disposition') !== null
307
- ? { disposition: response.headers.get('content-disposition')! }
308
- : {}),
309
- }
310
- }
311
- }