@ref0/sdk 0.0.0-stage → 0.6.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.
@@ -0,0 +1,341 @@
1
+ import { B as GateOwn, Ct as SandboxPushAnswer, Ht as VersionFile, Jt as WorkflowAskClosed, Kt as WorkflowAnswerer, On as WorkflowRequestRefusal, at as PasskeyFrom$1, h as ChangeAuthor, jn as WorkflowText, mt as Ref0Owned, ot as PasskeyRefusal, qt as WorkflowAsk, wt as SandboxSize } from "./index-CJGX88qF.mjs";
2
+ import { $ as StartActor, A as ForkOptions, B as WorkflowContext, C as Comment, D as EventWorkflow, E as EventOf, F as StepConfig, G as CalledWorkflow, H as text, I as StepContext, J as TreeEntry, K as JsonValue, L as ThreadStart, M as PullRequestAnswer, N as PullRequestOptions, O as EventWorkflowSpec, P as Ref0Actions, Q as Refusal, R as WaitType, S as CheckRunEnded, T as Duration, U as workflow, V as WorkflowStep, W as CalledRunFailed, X as Allow, Y as TreeRead, Z as CalledRun, _ as ActionAnswer, a as CheckRunOptions, at as allow, b as CalledContext, c as CheckRunResult, ct as Need, d as OneOfValues, et as StartContext, f as OutputResult, g as oneOf, h as check, i as CheckResult, it as StartRun, j as NeedAddOptions, k as ForkAnswer, l as CheckSpec, m as Step, n as Check, nt as StartOutput, o as CheckRunReference, ot as refuse, p as OutputSchema, q as Tree, r as CheckContext, rt as StartRule, s as CheckRunRefused, st as CheckNeed, t as Browser, tt as StartItem, u as DurationText, v as CallAnswer, w as ConnectionsOf, x as CalledWorkflowSpec, y as CallEnded, z as WaitedEvent } from "./browse-DHgV6DTF.mjs";
3
+ //#region src/ask.d.ts
4
+ /**
5
+ * `ask`, ref0's leaf that asks someone a question and waits in the run for the answer, as a
6
+ * repo's `.ref0/workflows/` code imports it from `@ref0/sdk`. It has only `.run`: `await
7
+ * ask.run(step, { … })`. The workflow's `permissions.ask` names whom it may ask, and each ask
8
+ * spends from its `asks` budget.
9
+ */
10
+ type Text = (typeof WorkflowText)['Encoded'];
11
+ /** One answer an ask offers: its key, which the run reads, and its title and detail, which the decider reads. */
12
+ interface AskAnswerOption<K extends string = string> {
13
+ readonly key: K;
14
+ readonly title: Text;
15
+ readonly detail: Text;
16
+ }
17
+ /**
18
+ * What `ask.run` asks: whom, the accountable person or the agent of a session in the run's
19
+ * `sessions`, by its index; its key, which names the ask in its run, so a run asks with each key
20
+ * once; the question; two to five answers; the lean, one of them, which the deadline answers; and
21
+ * the deadline, from a minute to a day. ref0 brings the deadline in to what the run has left.
22
+ */
23
+ interface AskOptions<K extends string> {
24
+ readonly to: (typeof WorkflowAsk)['Encoded']['to'];
25
+ readonly key: string;
26
+ readonly question: Text;
27
+ readonly answers: ReadonlyArray<AskAnswerOption<K>>;
28
+ readonly lean: NoInfer<K>;
29
+ readonly deadline: DurationText;
30
+ }
31
+ /** Who answered an ask: the accountable person, or an agent by its handle. */
32
+ type Answerer = (typeof WorkflowAnswerer)['Encoded'];
33
+ type Answered = Extract<(typeof WorkflowAskClosed)['Encoded'], {
34
+ readonly kind: 'answered';
35
+ }>;
36
+ /**
37
+ * An ask's answer: its key, one of the ask's answers'; who answered, `via: 'decider'`, or at the
38
+ * deadline, the lean, with no `by` and `via: 'deadline'`; and when, in ISO 8601.
39
+ */
40
+ type AskAnswer<K extends string = string> = Answered extends (infer Each) ? Each extends Answered ? Omit<Each, 'kind' | 'key'> & {
41
+ readonly key: K;
42
+ } : never : never;
43
+ /**
44
+ * ref0 refused an ask, as it refuses an action, and never opened it; `duplicate` when the same
45
+ * words went to the same decider within the hour; or `withdrawn`, opened, then closed with no
46
+ * answer when its thread closed. A refusal is kept as its step's result, so a replay throws it
47
+ * again and asks nothing.
48
+ */
49
+ export declare class AskRefused extends Error {
50
+ readonly why: WorkflowRequestRefusal | 'duplicate' | 'withdrawn';
51
+ constructor(key: string, why: AskRefused['why']);
52
+ }
53
+ /**
54
+ * Asks once, in a step of its own, then waits in the run for the ask's close, `ask-<key>`. The
55
+ * ask's step name carries its key and a digest of what it asks, since Workflows tells steps of
56
+ * one name apart only by the order they're reached in: a replay finds the same ask, and two asks
57
+ * with one key never take each other's answers, as ref0 opens only the first.
58
+ */
59
+ declare const run$1: <const K extends string>(step: WorkflowStep, options: AskOptions<K>) => Promise<AskAnswer<K>>;
60
+ /**
61
+ * ref0's ask: `ask.run(step, { to, key, question, answers, lean, deadline })` asks, then waits
62
+ * in the run for `{ key, by, via, at }`, the answer, or the lean at the deadline.
63
+ */
64
+ export declare const ask: {
65
+ readonly run: typeof run$1;
66
+ };
67
+ //#endregion
68
+ //#region src/gate.d.ts
69
+ /** What the gate returns: needs, with `false`, `null` and `undefined` skipped and lists flattened. */
70
+ type Needs = ReadonlyArray<Need | Needs | false | null | undefined>;
71
+ /** One changed file, from Git, never as the agent reports it. */
72
+ type ChangedFile = (typeof VersionFile)['Encoded'];
73
+ /** What the change does, as ref0 worked it out from Git. */
74
+ interface Change {
75
+ /** Every changed file, unless `complete` is false. */
76
+ readonly files: ReadonlyArray<ChangedFile>;
77
+ /** Whether `files` holds every changed file: false past 5,000 files or 1 MB. */
78
+ readonly complete: boolean;
79
+ /** The built-in permissions its paths touch, whose approval ref0's floor asks for anyway. */
80
+ readonly permissions: ReadonlyArray<string>;
81
+ /** Lines added and removed, over every changed file. */
82
+ readonly lines: {
83
+ readonly added: number;
84
+ readonly removed: number;
85
+ };
86
+ /**
87
+ * Whether any changed file, either end of a rename, matches a pattern: `src/billing/**`,
88
+ * `**\/*.sql`. In a segment `*` is any run of characters and `?` any one; a whole segment `**`
89
+ * is any number of segments.
90
+ */
91
+ readonly touches: (...patterns: ReadonlyArray<string>) => boolean;
92
+ /** Whether every changed file matches a pattern, as for a docs-only change. */
93
+ readonly only: (...patterns: ReadonlyArray<string>) => boolean;
94
+ /** Who wrote it: a member of the owner or a contributor, an agent or a person. */
95
+ readonly author: (typeof ChangeAuthor)['Encoded'];
96
+ /**
97
+ * The tree the change is made on, its base's, as a check reads its own. A decision reads at
98
+ * most 200 objects of both trees, each folder on a read's way among them, each at most 1 MiB
99
+ * and 8 MiB in all; past any, the decision fails, as a gate that throws does. ref0 keeps each
100
+ * read with the version, so `ref0 gate` shows what the gate read.
101
+ */
102
+ readonly before: Tree;
103
+ /** The tree the change makes, the version's expected tree, read as `before` is. */
104
+ readonly after: Tree;
105
+ }
106
+ /** What the gate is given about the change it decides for. */
107
+ interface GateContext {
108
+ readonly change: Change;
109
+ /** The thread's accepted plan, by its version, or `null`. */
110
+ readonly plan: {
111
+ readonly version: number;
112
+ } | null;
113
+ }
114
+ /**
115
+ * The gate, as `.ref0/gate.ts`'s default export, with what ref0 calls on it in its isolate, as
116
+ * `GateOwn` in `@ref0/contracts` says.
117
+ */
118
+ interface Gate extends Ref0Owned<GateOwn> {
119
+ readonly decide: (context: GateContext) => Needs | Promise<Needs>;
120
+ }
121
+ /** The gate: given a change, what it needs. Export it as `.ref0/gate.ts`'s default. */
122
+ export declare const gate: (decide: Gate['decide']) => Gate;
123
+ /**
124
+ * An approval from someone holding that repo permission: `approval('billing')`. Admins hold every
125
+ * permission.
126
+ */
127
+ export declare const approval: (permission: string) => Need;
128
+ /** A whole review covering the change, with no blocking finding open. ref0's floor has one. */
129
+ export declare const review: () => Need;
130
+ /**
131
+ * A check's need that a local run meets too: `local(unit())`. A run of the same check-run
132
+ * identity, the check's code, its params and the version's expected tree, run with `ref0 run
133
+ * --local` on an attached machine of the thread's and reported, meets each of its parts, and ref0
134
+ * runs none of them on the change, unless another need for the part doesn't take local. ref0's
135
+ * failure of a part still stands, the merge queue's tip still runs the check as ref0's own, and
136
+ * when ref0's runs of a local success's identity fail twice, its machine stops answering the
137
+ * check until an admin restores it. It takes a check's need, never a check or another need.
138
+ */
139
+ export declare const local: (need: CheckNeed) => CheckNeed;
140
+ //#endregion
141
+ //#region src/passkey.d.ts
142
+ /**
143
+ * `passkey`, as code imports it from `@ref0/sdk`. In a workflow, `passkey.run` asks a person for
144
+ * their yes to one statement, given with their passkey in their approving browser, and waits for
145
+ * it: `await passkey.run(step, { from: 'accountable', statement: text`Deploy ${sha}`, deadline:
146
+ * '1 hour' })`. In a gate, `passkey.check(e2e())` is a check's need whose result counts only once
147
+ * a person said yes to it the same way. Only that browser answers, never an agent, a session's
148
+ * token or the CLI, and a yes to one statement stands for no other.
149
+ */
150
+ /**
151
+ * Who a request asks, as `PasskeyFrom` in `@ref0/contracts` says: the run's accountable person; a
152
+ * person by their name; or anyone holding one of the repo's permissions, the first of whom to
153
+ * answer decides. The workflow's `permissions.ask` names each kind it asks. An ask's `by` passes
154
+ * as it is: `'accountable'`, or an agent, which is refused `agent`, since an agent has no passkey.
155
+ */
156
+ type PasskeyFrom = (typeof PasskeyFrom$1)['Encoded'] | {
157
+ readonly agent: string;
158
+ };
159
+ /** What `passkey.run` asks. */
160
+ interface PasskeyRunOptions {
161
+ readonly from: PasskeyFrom;
162
+ /** The statement, written with `text`, so its words are the code's own and its values quoted. */
163
+ readonly statement: (typeof WorkflowText)['Encoded'];
164
+ /**
165
+ * From a minute to a day: it ends there, or a minute before the run's day does, whichever is
166
+ * first, with a no.
167
+ */
168
+ readonly deadline: DurationText;
169
+ }
170
+ /**
171
+ * How a request ended: yes or no, who answered, by their name, and when, as an ISO time. A
172
+ * deadline answers no, with nobody's name.
173
+ */
174
+ interface PasskeyAnswer {
175
+ readonly approved: boolean;
176
+ readonly by?: string;
177
+ readonly at: string;
178
+ }
179
+ /**
180
+ * ref0 asked nobody, and why, as `PasskeyRefusal` in `@ref0/contracts` says. A refusal is
181
+ * kept as its step's result, so a replay throws it again and asks nobody; `agent` is refused
182
+ * before any step.
183
+ */
184
+ export declare class PasskeyRequestRefused extends Error {
185
+ readonly why: (typeof PasskeyRefusal)['Encoded'];
186
+ constructor(why: (typeof PasskeyRefusal)['Encoded']);
187
+ }
188
+ /**
189
+ * Asks for a passkey's yes to `statement`, then waits for the answer. The request is one step,
190
+ * named `ref0: passkey` and told from the run's others by its count, so it's reached in the order
191
+ * the code asks: a replay waits on the same request, and one that asks something else there
192
+ * throws `changed`. Then each round reads the request in a step and waits for its end, until its
193
+ * deadline or an hour, whichever is first, and a wait that times out reads again.
194
+ */
195
+ declare const run: (step: WorkflowStep, options: PasskeyRunOptions) => Promise<PasskeyAnswer>;
196
+ /** What `passkey.check` asks beside its need. */
197
+ interface PasskeyCheckOptions {
198
+ /**
199
+ * Who says yes: by default the person behind the run that meets the need, a local run's
200
+ * signer's person, or the version's accountable person for a run of ref0's own.
201
+ */
202
+ readonly from?: (typeof PasskeyFrom$1)['Encoded'];
203
+ }
204
+ /**
205
+ * A check's need whose result counts only once a person said yes to it with their passkey:
206
+ * `passkey.check(local(e2e()))`, or `passkey.check(e2e(), { from: { permission: 'qa' } })` to ask
207
+ * someone else. For each part, ref0 asks for a yes to a statement that names the run that meets it,
208
+ * its check-run identity, its conclusion and its outputs' hash, and the part waits for that yes. A
209
+ * newer run that counts asks again. A no or the request's day ending waits for a newer local run;
210
+ * on a run of ref0's, or from a person who can't be asked, the check needs an admin's override.
211
+ * When ref0's runs of an identity someone said yes over fail twice, their yes stops answering the
212
+ * check until an admin restores them. It takes a check's need, never a check or another need, and wraps it
213
+ * once, before or after `local`.
214
+ */
215
+ declare const check$1: (need: CheckNeed, options?: PasskeyCheckOptions) => CheckNeed;
216
+ export declare const passkey: {
217
+ run: typeof run;
218
+ check: typeof check$1;
219
+ };
220
+ //#endregion
221
+ //#region src/sandbox.d.ts
222
+ /**
223
+ * `sandbox()`, as a repo's `.ref0/sandboxes/` files write one, and what an import of one is. A
224
+ * sandbox's file is a declaration: ref0 reads every key from its literals and never runs it, and
225
+ * ref0's bundler swaps an import of it for a handle by its name, `sandboxHandle('node')`. A
226
+ * handle's `run` opens it in a step of a check run, through the opener ref0 gives the step's
227
+ * attempt, or in a workflow's step. Either way, a sandbox with `setup` opens from its snapshot,
228
+ * and one without from its image.
229
+ */
230
+ /** A command, as `exec` takes one: a string, run by `sh -c`, or an argv, run with no shell. */
231
+ type SandboxCommand = string | ReadonlyArray<string>;
232
+ /** What `sandbox()` takes, every key written out as a literal. */
233
+ interface SandboxSpec {
234
+ /** An image from ref0's catalog, by its name: `'node-24'`. */
235
+ readonly image: string;
236
+ /** `'standard-1'` unless it says. */
237
+ readonly size?: SandboxSize;
238
+ /** The paths from the repo's root its snapshot is keyed by. */
239
+ readonly cache?: {
240
+ readonly inputs: ReadonlyArray<string>;
241
+ };
242
+ /** Commands run in order when its snapshot is made, at most 16. */
243
+ readonly setup?: ReadonlyArray<string>;
244
+ /** The hosts setup may reach, and only setup: code judging a tree has no network. */
245
+ readonly egress?: {
246
+ readonly setup: ReadonlyArray<string>;
247
+ };
248
+ }
249
+ /**
250
+ * What a command run in a sandbox answers: a failing command isn't an error. Each stream keeps
251
+ * its last 256 KB. It's JSON, so a step may return it.
252
+ */
253
+ interface Exec {
254
+ readonly exitCode: number;
255
+ readonly stdout: string;
256
+ readonly stderr: string;
257
+ /** When it started, as an ISO 8601 time in UTC. */
258
+ readonly startedAt: string;
259
+ readonly durationMs: number;
260
+ }
261
+ /**
262
+ * What a push answers: the commit now on the fork's branch; `nothing`, when nothing changed; or
263
+ * why ref0 refused it. It's JSON, so a step may return it.
264
+ */
265
+ type PushAnswer = (typeof SandboxPushAnswer)['Encoded'];
266
+ /**
267
+ * A serve's port, ready: `url` is the plain `http://` URL a browser of the same step reaches it
268
+ * at. The URL confers nothing: only the session's own browser is routed to it.
269
+ */
270
+ interface Served {
271
+ readonly port: number;
272
+ readonly url: string;
273
+ }
274
+ /** A sandbox, open for as long as the function given it runs. */
275
+ interface SandboxSession {
276
+ readonly exec: (command: SandboxCommand, options?: {
277
+ readonly cwd?: string;
278
+ readonly env?: Readonly<Record<string, string>>;
279
+ readonly timeout?: DurationText;
280
+ }) => Promise<Exec>;
281
+ /**
282
+ * In a workflow's sandbox on a fork: commits what changed against the tree, as the workflow,
283
+ * and has ref0 push it to the fork, replacing its branch with a commit on `main`. A change
284
+ * under `.ref0/` is refused. Each call counts once against the run's `pushes`, and a step's
285
+ * retry pushes again from its new sandbox without counting again.
286
+ */
287
+ readonly push: (options: {
288
+ readonly message: string;
289
+ }) => Promise<PushAnswer>;
290
+ /**
291
+ * Starts a command in the background, left running on `port` until the sandbox closes, and
292
+ * answers once the port answers HTTP while the command holds it, within `ready`, 30 seconds
293
+ * unless it says. At most 4 a sandbox, each on a port of its own from 1024 up. One that exits
294
+ * or isn't ready in time throws, with the end of what it said, and closes the sandbox.
295
+ */
296
+ readonly serve: (command: SandboxCommand, options: {
297
+ readonly port: number;
298
+ readonly cwd?: string;
299
+ readonly env?: Readonly<Record<string, string>>;
300
+ readonly ready?: DurationText;
301
+ }) => Promise<Served>;
302
+ /**
303
+ * Lends `fn` a browser, a fresh Browser Run session that reaches only this sandbox's serves
304
+ * that are ready now, and closes it when `fn` ends: `fn`'s value. Only a check that imports
305
+ * `@ref0/sdk/browser` browses, one browser at a time.
306
+ */
307
+ readonly browse: <T>(fn: (browser: Browser) => Promise<T>) => Promise<T>;
308
+ }
309
+ /**
310
+ * What opening a sandbox takes: in a check run, the paths of its run's tree the sandbox sees, all
311
+ * of it unless given, since a check run's tree is always its own; a size at least its own; and
312
+ * its step's `timeout` and `retries`, 10 minutes and 2 unless given. A retry waits 10 seconds,
313
+ * then 20. In a workflow, `tree` is `'main'` or a fork `forks.create` answered, and both hold
314
+ * `main`'s tree at the commit the run read, as a one-commit Git history in `/src`; it takes no
315
+ * `paths`, and the step's `timeout` cuts its deadline, which is otherwise the run's
316
+ * `sandboxMinutes` left.
317
+ */
318
+ interface SandboxRunOptions {
319
+ /** A workflow's alone, and it must give one. */
320
+ readonly tree?: string | ForkAnswer;
321
+ readonly paths?: ReadonlyArray<string>;
322
+ readonly size?: SandboxSize;
323
+ readonly timeout?: DurationText;
324
+ readonly retries?: number;
325
+ }
326
+ /** A sandbox, as code that imports its file sees it: `import node from '../sandboxes/node'`. */
327
+ interface Sandbox {
328
+ /**
329
+ * Opens it for one step, puts the tree's paths in it, and stops it when `work` ends. The step's
330
+ * result is `work`'s, kept as any step's is.
331
+ */
332
+ readonly run: <T>(step: Step, name: string, options: SandboxRunOptions, work: (sandbox: SandboxSession) => Promise<T>) => Promise<T>;
333
+ }
334
+ /**
335
+ * A sandbox: its image, size, cached setup, and the hosts setup may reach. Export it as its
336
+ * file's default, `.ref0/sandboxes/<name>.ts`, named by its file.
337
+ */
338
+ export declare const sandbox: (_spec: SandboxSpec) => Sandbox;
339
+ //#endregion
340
+ export { type ActionAnswer, type Allow, type Answerer, type AskAnswer, type AskAnswerOption, type AskOptions, type CallAnswer, type CallEnded, type CalledContext, type CalledRun, CalledRunFailed, type CalledWorkflow, type CalledWorkflowSpec, type Change, type ChangedFile, type Check, type CheckContext, type CheckNeed, type CheckResult, type CheckRunEnded, type CheckRunOptions, type CheckRunReference, CheckRunRefused, type CheckRunResult, type CheckSpec, type Comment, type ConnectionsOf, type Duration, type DurationText, type EventOf, type EventWorkflow, type EventWorkflowSpec, type Exec, type ForkAnswer, type ForkOptions, type Gate, type GateContext, type JsonValue, type Need, type NeedAddOptions, type Needs, type OneOfValues, type OutputResult, type OutputSchema, type PasskeyAnswer, type PasskeyCheckOptions, type PasskeyFrom, type PasskeyRunOptions, type PullRequestAnswer, type PullRequestOptions, type PushAnswer, type Ref0Actions, type Refusal, type Sandbox, type SandboxCommand, type SandboxRunOptions, type SandboxSession, type SandboxSpec, type Served, type StartActor, type StartContext, type StartItem, type StartOutput, type StartRule, type StartRun, type Step, type StepConfig, type StepContext, type ThreadStart, type Tree, type TreeEntry, type TreeRead, type WaitType, type WaitedEvent, type WorkflowContext, type WorkflowStep, allow, check, oneOf, refuse, text, workflow };
341
+ //# sourceMappingURL=index.d.mts.map