unfazed 0.6.0 → 0.8.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.
- package/CHANGELOG.md +88 -0
- package/README.md +299 -78
- package/REFERENCE.md +284 -0
- package/dist/cli/login.d.ts +129 -0
- package/dist/cli/login.js +596 -0
- package/dist/cli/login.js.map +1 -0
- package/dist/cli/workflow.d.ts +31 -0
- package/dist/cli/workflow.js +157 -0
- package/dist/cli/workflow.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +173 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +26 -5
- package/dist/client.js +93 -48
- package/dist/client.js.map +1 -1
- package/dist/credentials.d.ts +123 -0
- package/dist/credentials.js +317 -0
- package/dist/credentials.js.map +1 -0
- package/dist/errors.d.ts +64 -0
- package/dist/errors.js +95 -0
- package/dist/errors.js.map +1 -1
- package/dist/generated/gql.d.ts +78 -2
- package/dist/generated/gql.js +21 -2
- package/dist/generated/gql.js.map +1 -1
- package/dist/generated/graphql.d.ts +505 -6
- package/dist/generated/graphql.js +439 -2
- package/dist/generated/graphql.js.map +1 -1
- package/dist/index.d.ts +25 -6
- package/dist/index.js +23 -5
- package/dist/index.js.map +1 -1
- package/dist/operations.d.ts +116 -5
- package/dist/operations.js +379 -7
- package/dist/operations.js.map +1 -1
- package/dist/reference.d.ts +18 -0
- package/dist/reference.generated.d.ts +2 -0
- package/dist/reference.generated.js +5 -0
- package/dist/reference.generated.js.map +1 -0
- package/dist/reference.js +38 -0
- package/dist/reference.js.map +1 -0
- package/dist/remote/app.js +2 -1
- package/dist/remote/app.js.map +1 -1
- package/dist/remote/world.d.ts +2 -2
- package/dist/remote/world.js +32 -16
- package/dist/remote/world.js.map +1 -1
- package/dist/unfazed.d.ts +545 -68
- package/dist/unfazed.js +688 -64
- package/dist/unfazed.js.map +1 -1
- package/dist/wait.d.ts +7 -0
- package/dist/wait.js.map +1 -1
- package/dist/workflow/nitro.js +5 -3
- package/dist/workflow/nitro.js.map +1 -1
- package/package.json +22 -6
- package/schema/SOURCE.json +4 -4
- package/schema/schema.graphqls +1628 -30
package/schema/schema.graphqls
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
"Incremental fragment delivery over multipart/mixed (deferSpec=20220824)."
|
|
2
|
+
directive @defer(if: Boolean = true, label: String) on FRAGMENT_SPREAD | INLINE_FRAGMENT
|
|
3
|
+
|
|
1
4
|
scalar File
|
|
2
5
|
scalar JSON
|
|
3
6
|
|
|
4
7
|
type Function {
|
|
5
8
|
id: ID!
|
|
9
|
+
"The owning identity. A listing also includes the functions of agents the caller claimed (and, for the operator, every tenant's), so a client that must act only on its own functions keeps those whose ownerId equals whoami.userID. Returned only with a function the caller can already see."
|
|
10
|
+
ownerId: ID!
|
|
6
11
|
name: String!
|
|
7
12
|
filename: String!
|
|
8
13
|
sizeBytes: Int!
|
|
@@ -11,6 +16,25 @@ type Function {
|
|
|
11
16
|
bundled: Boolean!
|
|
12
17
|
}
|
|
13
18
|
|
|
19
|
+
"Durable registration metadata. A published resource can still be awaiting job cleanup; settled distinguishes that case. No worker credentials or source paths are exposed."
|
|
20
|
+
type FunctionRegistration {
|
|
21
|
+
id: ID!
|
|
22
|
+
name: String!
|
|
23
|
+
createdAt: String!
|
|
24
|
+
"pending, published, failed, cancelled, rejected or unavailable."
|
|
25
|
+
state: String!
|
|
26
|
+
phase: String!
|
|
27
|
+
code: String
|
|
28
|
+
settled: Boolean!
|
|
29
|
+
canResume: Boolean!
|
|
30
|
+
cancelRequested: Boolean!
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
type FunctionRegistrationPage {
|
|
34
|
+
items: [FunctionRegistration!]!
|
|
35
|
+
nextCursor: ID
|
|
36
|
+
}
|
|
37
|
+
|
|
14
38
|
enum DeploymentKind {
|
|
15
39
|
STATIC
|
|
16
40
|
SERVICE
|
|
@@ -58,6 +82,7 @@ enum DeploymentEventType {
|
|
|
58
82
|
SERVICE_VM_STARTED
|
|
59
83
|
SERVICE_VM_STOPPED
|
|
60
84
|
SERVICE_CRON_TRIGGERED
|
|
85
|
+
SERVICE_VM_CRASHED
|
|
61
86
|
}
|
|
62
87
|
|
|
63
88
|
enum DeploymentEventSeverity {
|
|
@@ -67,23 +92,84 @@ enum DeploymentEventSeverity {
|
|
|
67
92
|
}
|
|
68
93
|
|
|
69
94
|
type Workspace {
|
|
95
|
+
"Write-only secrets are returned with null values, as in workspaceEnv."
|
|
96
|
+
environment: [WorkspaceEnvVar!]
|
|
97
|
+
"Value-free connections shared with this workspace's project."
|
|
98
|
+
sharedConnections: [IntegrationConnection!]
|
|
70
99
|
id: ID!
|
|
71
100
|
name: String!
|
|
72
101
|
"Who owns this source. The listing includes the sources of agents the caller claimed, so this is how a client tells its own from an agent's: it matches one of whoami.linkedAgents[].agentID for the latter. Operations that require a DIRECTLY owned source — alias adoption targets — must filter on it."
|
|
73
102
|
ownerId: ID!
|
|
74
103
|
"The owner-defined project this app is grouped under (dashboard organization only); null when ungrouped."
|
|
75
104
|
projectId: ID
|
|
105
|
+
"The containing project, when visible to the caller; null when ungrouped."
|
|
106
|
+
project: Project
|
|
76
107
|
gitSource: GitSource
|
|
108
|
+
"Platform git for this app; null where the installation runs no platform git."
|
|
109
|
+
platformGit: WorkspacePlatformGit
|
|
110
|
+
"Every environment of this workspace's git repo — the main app first — including this workspace. Empty when the workspace is not git-linked."
|
|
111
|
+
repoEnvironments: [RepoEnvironment!]!
|
|
112
|
+
"The apps this workspace serves right now, by alias: everything deleteWorkspace withDeployments would take offline, and the exact list its confirmAliases must name. Domains are listed for the app's owner only."
|
|
113
|
+
liveApps: [LiveApp!]!
|
|
114
|
+
"Apps deleted with deleteApp while the workspace is git-linked. Pushes and syncs skip them while unfazed.json apps[] still declares them; removing them from apps[] clears this, and syncRepo restoreApps brings one back."
|
|
115
|
+
deletedApps: [DeletedApp!]!
|
|
77
116
|
createdAt: String!
|
|
78
117
|
updatedAt: String!
|
|
79
118
|
}
|
|
80
119
|
|
|
120
|
+
"An app (alias) a workspace or an API client serves right now, with the custom domains routing to it."
|
|
121
|
+
type LiveApp {
|
|
122
|
+
alias: String!
|
|
123
|
+
"The deployment serving the alias."
|
|
124
|
+
deploymentID: ID!
|
|
125
|
+
"Custom domains that stop serving with the app; empty for a caller who does not own it."
|
|
126
|
+
domains: [String!]!
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
"An app deleted with deleteApp from a git-linked workspace (Workspace.deletedApps)."
|
|
130
|
+
type DeletedApp {
|
|
131
|
+
alias: String!
|
|
132
|
+
deletedAt: String!
|
|
133
|
+
"The newest commit whose import skipped the app because unfazed.json apps[] still declared it; null until one did."
|
|
134
|
+
skippedCommit: String
|
|
135
|
+
skippedAt: String
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
"An app's platform git, as the caller sees it."
|
|
139
|
+
type WorkspacePlatformGit {
|
|
140
|
+
"The git server, e.g. https://git.unfz.to. A person signs git in to it once with <url>/install.sh."
|
|
141
|
+
url: String!
|
|
142
|
+
"The app's repository by alias, e.g. https://git.unfz.to/<alias>.git, while the app deploys from it; null otherwise."
|
|
143
|
+
cloneURL: String
|
|
144
|
+
"Whether the caller may turn it on (enablePlatformGit): the app's owner and the platform operator. Team members may not, though they clone and push once it is on."
|
|
145
|
+
canEnable: Boolean!
|
|
146
|
+
"Whether apps without a repository get platform git by themselves at their next change (a file write or a deploy) once they serve."
|
|
147
|
+
byDefault: Boolean!
|
|
148
|
+
"Why this app does not get platform git by itself (its owner turned it off, or what enablePlatformGit would refuse); null when it will, or has it."
|
|
149
|
+
offReason: String
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
"One environment of a git-linked repo: the main app, or a sibling workspace that deploys another branch to its own aliases."
|
|
153
|
+
type RepoEnvironment {
|
|
154
|
+
workspace: Workspace!
|
|
155
|
+
"The environment name, e.g. staging; null for the main app."
|
|
156
|
+
name: String
|
|
157
|
+
branch: String!
|
|
158
|
+
lastImportStatus: String!
|
|
159
|
+
"Where the environment is opened: its serving app, else its latest deployment attempt; null before the first one exists."
|
|
160
|
+
deployment: Deployment
|
|
161
|
+
}
|
|
162
|
+
|
|
81
163
|
"A project groups an owner's apps under a human-chosen name. Purely a dashboard organization layer: it does not affect app URLs or aliases, and is never exposed to agents."
|
|
82
164
|
type Project {
|
|
83
165
|
id: ID!
|
|
84
166
|
name: String!
|
|
85
|
-
"The owning identity
|
|
167
|
+
"The owning identity. Visibility through a team does not grant ownership."
|
|
86
168
|
owner: String!
|
|
169
|
+
"Display name of the owning human account, resolving a linked agent to its claimer. Unclaimed agents display as Unclaimed account."
|
|
170
|
+
ownerName: String!
|
|
171
|
+
"Whether the caller may rename, delete or share this project."
|
|
172
|
+
canManage: Boolean!
|
|
87
173
|
createdAt: String!
|
|
88
174
|
updatedAt: String!
|
|
89
175
|
}
|
|
@@ -136,13 +222,14 @@ type TeamSharedProject {
|
|
|
136
222
|
|
|
137
223
|
type TeamMember {
|
|
138
224
|
userID: String!
|
|
139
|
-
"
|
|
225
|
+
"The member's handle (a GitHub login, a display name, or the words Google account), never an email address (docs/access-control.md)."
|
|
140
226
|
name: String!
|
|
141
227
|
role: String!
|
|
142
228
|
addedAt: String!
|
|
143
229
|
}
|
|
144
230
|
|
|
145
231
|
type TeamInvite {
|
|
232
|
+
"Stable opaque recipient key for cancellation. An email invitation key is not an account ID, even after sign-in."
|
|
146
233
|
userID: String!
|
|
147
234
|
name: String!
|
|
148
235
|
invitedBy: String!
|
|
@@ -154,7 +241,7 @@ type TeamEvent {
|
|
|
154
241
|
at: String!
|
|
155
242
|
actor: String!
|
|
156
243
|
actorName: String!
|
|
157
|
-
"created | renamed | invited | invite_cancelled | invite_declined | joined | member_removed | member_left"
|
|
244
|
+
"created | renamed | invited | invite_bound | invite_cancelled | invite_declined | joined | member_removed | member_left"
|
|
158
245
|
action: String!
|
|
159
246
|
subject: String
|
|
160
247
|
subjectName: String
|
|
@@ -184,12 +271,13 @@ input TeamIDInput {
|
|
|
184
271
|
|
|
185
272
|
input TeamInviteInput {
|
|
186
273
|
teamID: ID!
|
|
187
|
-
"GitHub login
|
|
274
|
+
"GitHub login (optional leading @) or Gmail/Google Workspace email. Google invitations appear after the recipient signs in with that verified address; no email is sent."
|
|
188
275
|
login: String!
|
|
189
276
|
}
|
|
190
277
|
|
|
191
278
|
input TeamMemberInput {
|
|
192
279
|
teamID: ID!
|
|
280
|
+
"Account ID for member operations; use TeamInvite.userID unchanged when cancelling an invitation."
|
|
193
281
|
userID: String!
|
|
194
282
|
}
|
|
195
283
|
|
|
@@ -202,13 +290,125 @@ type TeamPayload {
|
|
|
202
290
|
team: Team!
|
|
203
291
|
}
|
|
204
292
|
|
|
205
|
-
"A BYO custom domain attached to an app's alias. The edge issues its TLS cert
|
|
293
|
+
"A BYO custom domain attached to an app's alias. The edge issues its TLS cert once active; requests to the domain serve the app."
|
|
206
294
|
type CustomDomain {
|
|
207
295
|
domain: String!
|
|
208
296
|
alias: String!
|
|
209
297
|
"True once the platform allows the edge to issue a cert and route the domain."
|
|
210
298
|
active: Boolean!
|
|
211
299
|
createdAt: String!
|
|
300
|
+
"The DNS records to create for this domain: where to point it, plus any verification record the edge still asks for. A record with recommended=false is an alternative to a recommended one, not an addition."
|
|
301
|
+
dnsRecords: [DNSRecord!]!
|
|
302
|
+
"The domain's hostname at the edge (Cloudflare for SaaS) as of the platform's last check; null while the platform does not manage one."
|
|
303
|
+
status: CustomDomainStatus
|
|
304
|
+
"How far the domain is from serving, in one word and one sentence, as of the platform's last check."
|
|
305
|
+
activation: CustomDomainActivation!
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
"A custom domain's activation state."
|
|
309
|
+
enum CustomDomainState {
|
|
310
|
+
"Cloudflare is verifying the domain or issuing its certificate: usually 1–5 minutes, during which it answers the domain with \"error code: 1014\". Nothing to do unless it lasts longer than 15 minutes."
|
|
311
|
+
ACTIVATING
|
|
312
|
+
"Cloudflare has not seen the domain point at the platform for longer than activation takes, or it stopped pointing there: create or fix its CNAME."
|
|
313
|
+
DNS_MISSING
|
|
314
|
+
"Served over HTTPS."
|
|
315
|
+
ACTIVE
|
|
316
|
+
"Refused, timed out, or still not active long after activation should have finished; the message says why."
|
|
317
|
+
FAILED
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
"How far a custom domain is from serving."
|
|
321
|
+
type CustomDomainActivation {
|
|
322
|
+
state: CustomDomainState!
|
|
323
|
+
"One sentence for a person or an agent: what is happening, and what to do if anything."
|
|
324
|
+
message: String!
|
|
325
|
+
"When the current activation step started (RFC 3339); null once active or when unknown."
|
|
326
|
+
since: String
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
"How far a custom domain is from serving over HTTPS at the edge."
|
|
330
|
+
type CustomDomainStatus {
|
|
331
|
+
"The edge's hostname status, e.g. pending, active, blocked; \"registering\" before the hostname exists."
|
|
332
|
+
status: String!
|
|
333
|
+
"The certificate's status, e.g. initializing, pending_validation, pending_issuance, active; empty before the hostname exists."
|
|
334
|
+
sslStatus: String!
|
|
335
|
+
"True once the hostname and its certificate are both active."
|
|
336
|
+
live: Boolean!
|
|
337
|
+
"Why the domain is not live yet: verification and certificate validation errors from the edge, and the platform's own when it could not register the domain."
|
|
338
|
+
errors: [String!]!
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
"""
|
|
342
|
+
A hostname of the caller's that serves an app besides its own <alias> URL:
|
|
343
|
+
a custom domain attached to the app's alias, or the domain of a site an
|
|
344
|
+
integration publishes the app to.
|
|
345
|
+
"""
|
|
346
|
+
type AppDomain {
|
|
347
|
+
"The hostname, e.g. app.example.com."
|
|
348
|
+
domain: String!
|
|
349
|
+
"Serves the app over HTTPS now."
|
|
350
|
+
live: Boolean!
|
|
351
|
+
"How far the domain is from serving (a published site's domain is ACTIVE)."
|
|
352
|
+
state: CustomDomainState!
|
|
353
|
+
"What a domain that is not live yet waits for; null once it is live."
|
|
354
|
+
pending: AppDomainPending @deprecated(reason: "Use state.")
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
enum AppDomainPending {
|
|
358
|
+
"Its DNS: the records its owner creates at their DNS provider (Configuration → Domains lists them)."
|
|
359
|
+
DNS
|
|
360
|
+
"Its certificate, being issued now that the DNS resolves."
|
|
361
|
+
CERTIFICATE
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
"A DNS record a custom domain's owner creates at their DNS provider."
|
|
365
|
+
type DNSRecord {
|
|
366
|
+
"Record type: CNAME, A, or TXT."
|
|
367
|
+
type: String!
|
|
368
|
+
"The record's hostname: the custom domain itself, or a verification name under it."
|
|
369
|
+
name: String!
|
|
370
|
+
"What the record points at, or the TXT value."
|
|
371
|
+
content: String!
|
|
372
|
+
"True when the record must be proxied by Cloudflare; false when it need not be (the note says whether it must be DNS only)."
|
|
373
|
+
proxied: Boolean!
|
|
374
|
+
"True for a record to create; false for an alternative to it."
|
|
375
|
+
recommended: Boolean!
|
|
376
|
+
"When this record applies."
|
|
377
|
+
note: String!
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
"""
|
|
381
|
+
A provider a person can sign in with, as their account settings show it. The
|
|
382
|
+
dashboard renders the list as given; it knows no provider by name. Linking
|
|
383
|
+
and unlinking are same-origin form posts to linkURL and unlinkURL.
|
|
384
|
+
"""
|
|
385
|
+
type SignInMethod {
|
|
386
|
+
provider: String!
|
|
387
|
+
label: String!
|
|
388
|
+
iconURL: String!
|
|
389
|
+
"Whether a sign-in from this provider reaches the account."
|
|
390
|
+
linked: Boolean!
|
|
391
|
+
"The linked login or address, as the provider last reported it."
|
|
392
|
+
handle: String
|
|
393
|
+
"Whether unlinking is offered: never for the account's only sign-in."
|
|
394
|
+
canUnlink: Boolean!
|
|
395
|
+
linkURL: String!
|
|
396
|
+
unlinkURL: String!
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
"""
|
|
400
|
+
A computer whose git is signed in to platform git with this account
|
|
401
|
+
(git-credential-unfazed, approved in the browser). Signing it out is a
|
|
402
|
+
same-origin form post to signOutURL.
|
|
403
|
+
"""
|
|
404
|
+
type GitSignIn {
|
|
405
|
+
id: ID!
|
|
406
|
+
"What the computer called itself when it asked; not verified."
|
|
407
|
+
name: String!
|
|
408
|
+
createdAt: String!
|
|
409
|
+
"When it last renewed its git token (about hourly while git is used)."
|
|
410
|
+
lastUsedAt: String!
|
|
411
|
+
signOutURL: String!
|
|
212
412
|
}
|
|
213
413
|
|
|
214
414
|
"A public key that may authenticate to the box SSH gateway. Public keys are not secrets, so the fingerprint and type are shown in full."
|
|
@@ -244,6 +444,19 @@ input RemoveCustomDomainInput {
|
|
|
244
444
|
domain: String!
|
|
245
445
|
}
|
|
246
446
|
|
|
447
|
+
input MoveCustomDomainInput {
|
|
448
|
+
domain: String!
|
|
449
|
+
"The alias of the app the domain serves from now on."
|
|
450
|
+
alias: String!
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
"An app a custom domain may move to (moveCustomDomain)."
|
|
454
|
+
type CustomDomainMoveTarget {
|
|
455
|
+
alias: String!
|
|
456
|
+
"The app's name."
|
|
457
|
+
name: String!
|
|
458
|
+
}
|
|
459
|
+
|
|
247
460
|
type GitSource {
|
|
248
461
|
provider: String!
|
|
249
462
|
repo: String!
|
|
@@ -259,8 +472,10 @@ type GitSource {
|
|
|
259
472
|
lastImportError: String
|
|
260
473
|
webhookURL: String
|
|
261
474
|
webhookSecret: String
|
|
262
|
-
"When set, the auto-deploy webhook has been registered on the
|
|
475
|
+
"When set, the auto-deploy webhook has been registered on the source repo (RFC3339)."
|
|
263
476
|
webhookInstalledAt: String
|
|
477
|
+
"The environment this link deploys (e.g. staging); null for the repo's main app."
|
|
478
|
+
environment: String
|
|
264
479
|
}
|
|
265
480
|
|
|
266
481
|
type GitHubTokenStatus {
|
|
@@ -339,6 +554,22 @@ type AppEnvScope {
|
|
|
339
554
|
}
|
|
340
555
|
|
|
341
556
|
type Deployment {
|
|
557
|
+
"Whether the caller may create a guest feedback link for this app."
|
|
558
|
+
canShareReview: Boolean!
|
|
559
|
+
"Whether the app keeps its own platform git history (appCommits); false while platform git is off and for apps linked to another repository."
|
|
560
|
+
gitHistory: Boolean!
|
|
561
|
+
"The caller's custom hostnames serving this app (AppDomain), custom domains oldest first, then published sites'. Empty for a release that does not hold its alias. Custom domains are the app owner's: team members see none of them."
|
|
562
|
+
domains: [AppDomain!]!
|
|
563
|
+
workspace: Workspace
|
|
564
|
+
"Runs visible to the caller in this deployment's workspace."
|
|
565
|
+
runs(limit: Int = 20, offset: Int = 0): RunPage
|
|
566
|
+
"Effective environment for this app alias; secret values stay write-only."
|
|
567
|
+
environment: [WorkspaceEnvVar!]
|
|
568
|
+
releases: [DeploymentRelease!]
|
|
569
|
+
events(limit: Int = 20, offset: Int = 0): DeploymentEventPage
|
|
570
|
+
"Null for deployments that are not services. Errors stay within this field."
|
|
571
|
+
runtimeStatus: ServiceRuntimeStatus
|
|
572
|
+
runtimeLogs(tailBytes: Int = 16384): ServiceRuntimeLogs
|
|
342
573
|
id: ID!
|
|
343
574
|
workspaceID: ID!
|
|
344
575
|
kind: DeploymentKind!
|
|
@@ -375,6 +606,20 @@ type Deployment {
|
|
|
375
606
|
worker: DeploymentWorker
|
|
376
607
|
}
|
|
377
608
|
|
|
609
|
+
"A release summary. History cannot recursively expand the same history."
|
|
610
|
+
type DeploymentRelease {
|
|
611
|
+
id: ID!
|
|
612
|
+
aliasHeld: Boolean!
|
|
613
|
+
aliasRevision: String!
|
|
614
|
+
status: DeploymentStatus!
|
|
615
|
+
error: String
|
|
616
|
+
serviceMode: ServiceMode!
|
|
617
|
+
previewUrl: String!
|
|
618
|
+
gitCommit: String
|
|
619
|
+
size: String!
|
|
620
|
+
createdAt: String!
|
|
621
|
+
}
|
|
622
|
+
|
|
378
623
|
"The authoritative runtime target assigned to a current deployment."
|
|
379
624
|
type DeploymentWorker {
|
|
380
625
|
id: String!
|
|
@@ -412,6 +657,42 @@ type ServiceRuntimeStatus {
|
|
|
412
657
|
lastStoppedAt: String
|
|
413
658
|
restartCount: Int!
|
|
414
659
|
lastError: String
|
|
660
|
+
"""
|
|
661
|
+
The app's recent crashes on its server: its VM stopped without being asked
|
|
662
|
+
to. Null when it has had none since that server's runtime last started.
|
|
663
|
+
"""
|
|
664
|
+
crashes: ServiceCrashes
|
|
665
|
+
"True when the app's server tracks its crashes, so a null crashes means none; false for a server runtime that predates crash tracking, and for boxes."
|
|
666
|
+
crashesTracked: Boolean!
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
"Recent crashes of a service on the server that runs it."
|
|
670
|
+
type ServiceCrashes {
|
|
671
|
+
"At least 3 crashes within the last hour."
|
|
672
|
+
looping: Boolean!
|
|
673
|
+
lastHour: Int!
|
|
674
|
+
last24h: Int!
|
|
675
|
+
"Crashes since the server's runtime last started."
|
|
676
|
+
total: Int!
|
|
677
|
+
"Newest first, at most 5; only the newest carries logTail."
|
|
678
|
+
recent: [ServiceCrash!]!
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
"One unexpected stop of a service's VM."
|
|
682
|
+
type ServiceCrash {
|
|
683
|
+
at: String!
|
|
684
|
+
vmID: String
|
|
685
|
+
"running (the VM was serving) or starting (the app failed before it was ready)."
|
|
686
|
+
phase: String!
|
|
687
|
+
"app_exit, app_signal, out_of_memory, kernel_panic, guest_stopped, unknown, health_check, host_killed or vm_error."
|
|
688
|
+
cause: String!
|
|
689
|
+
"The app process's exit status (128+signal when a signal ended it), when its VM reported it."
|
|
690
|
+
exitCode: Int
|
|
691
|
+
signal: String
|
|
692
|
+
"One line saying what happened."
|
|
693
|
+
message: String!
|
|
694
|
+
"The last lines of the VM's console before it stopped (the app's output, secrets redacted)."
|
|
695
|
+
logTail: String
|
|
415
696
|
}
|
|
416
697
|
|
|
417
698
|
type ServiceRuntimeLogs {
|
|
@@ -445,6 +726,8 @@ type IntegrationKind {
|
|
|
445
726
|
kind: String!
|
|
446
727
|
label: String!
|
|
447
728
|
iconURL: String
|
|
729
|
+
"Lowercase catalog grouping labels: ai, database, observability, …"
|
|
730
|
+
tags: [String!]!
|
|
448
731
|
# who supplies the backend: "platform" (unfazed runs it) or "user" (BYO)
|
|
449
732
|
provenance: String!
|
|
450
733
|
# how the owner connects: "none" (no connection), "fields" (a form), "link" (an auth flow)
|
|
@@ -458,7 +741,55 @@ type IntegrationKind {
|
|
|
458
741
|
"Safe isolation mode selected when bindIntegration omits mode; null for providers without app runtime."
|
|
459
742
|
defaultMode: String
|
|
460
743
|
runtime: IntegrationRuntime!
|
|
744
|
+
"Tools and skills this provider contributes to a bound app's bot tasks. No credentials or server endpoints."
|
|
745
|
+
agent: IntegrationAgent!
|
|
461
746
|
surfaces: [IntegrationSurface!]!
|
|
747
|
+
"True when the provider can read what one scoped binding's per-app resource consumed (integrationBindingUsage)."
|
|
748
|
+
reportsUsage: Boolean!
|
|
749
|
+
"Choices the owner makes when binding this kind to an app (bindIntegration options), e.g. what a git environment's database starts with. Empty for most kinds."
|
|
750
|
+
bindOptions: [IntegrationBindOption!]!
|
|
751
|
+
}
|
|
752
|
+
"A provider-declared choice made once, at bind time, about how the app's resource is created. A resource that already exists is kept whatever the choice."
|
|
753
|
+
type IntegrationBindOption {
|
|
754
|
+
name: String!
|
|
755
|
+
label: String!
|
|
756
|
+
description: String!
|
|
757
|
+
"Which apps the option exists for: app (every app) or environment (only a git environment of another app). Elsewhere bindIntegration refuses it."
|
|
758
|
+
appliesTo: String!
|
|
759
|
+
"The value recorded when bindIntegration omits the option."
|
|
760
|
+
default: String!
|
|
761
|
+
choices: [IntegrationBindChoice!]!
|
|
762
|
+
}
|
|
763
|
+
type IntegrationBindChoice {
|
|
764
|
+
value: String!
|
|
765
|
+
label: String!
|
|
766
|
+
description: String!
|
|
767
|
+
"What the owner must know before choosing this value (e.g. that it copies production data); null when nothing."
|
|
768
|
+
warning: String
|
|
769
|
+
}
|
|
770
|
+
"One bind option value of a binding."
|
|
771
|
+
type IntegrationBindOptionValue {
|
|
772
|
+
name: String!
|
|
773
|
+
value: String!
|
|
774
|
+
"True when the binding predates the option: nothing was chosen or recorded, and value is what such bindings were created with."
|
|
775
|
+
legacy: Boolean!
|
|
776
|
+
}
|
|
777
|
+
input IntegrationBindOptionInput {
|
|
778
|
+
name: String!
|
|
779
|
+
value: String!
|
|
780
|
+
}
|
|
781
|
+
type IntegrationAgent {
|
|
782
|
+
revision: String!
|
|
783
|
+
servers: [IntegrationAgentServer!]!
|
|
784
|
+
skills: [String!]!
|
|
785
|
+
}
|
|
786
|
+
type IntegrationAgentServer {
|
|
787
|
+
name: String!
|
|
788
|
+
description: String!
|
|
789
|
+
transport: String!
|
|
790
|
+
auth: String!
|
|
791
|
+
readTools: [String!]!
|
|
792
|
+
writeTools: [String!]!
|
|
462
793
|
}
|
|
463
794
|
type IntegrationSurface {
|
|
464
795
|
id: String!
|
|
@@ -501,6 +832,18 @@ type IntegrationConnection {
|
|
|
501
832
|
grantedProjectIDs: [ID!]!
|
|
502
833
|
createdAt: String!
|
|
503
834
|
updatedAt: String!
|
|
835
|
+
"OAuth state of the kind's MCP server (null for kinds without one): runs get the server only while it is active."
|
|
836
|
+
authorization: IntegrationConnectionAuthorization
|
|
837
|
+
}
|
|
838
|
+
"The owner's OAuth grant for a connection's MCP server. The platform is the OAuth client; tokens stay on the control plane."
|
|
839
|
+
type IntegrationConnectionAuthorization {
|
|
840
|
+
"required (no usable grant), active, or failed (the server refused a refresh; authorize again)"
|
|
841
|
+
status: String!
|
|
842
|
+
"The protected resource: the MCP endpoint the grant is for."
|
|
843
|
+
resource: String!
|
|
844
|
+
scopes: [String!]!
|
|
845
|
+
authorizedAt: String
|
|
846
|
+
error: String
|
|
504
847
|
}
|
|
505
848
|
type IntegrationFieldValue {
|
|
506
849
|
name: String!
|
|
@@ -524,17 +867,59 @@ type IntegrationBinding {
|
|
|
524
867
|
status: String!
|
|
525
868
|
"Set when the binding rides a GRANTED connection: the lender's identity. The lender can always see and sever such bindings."
|
|
526
869
|
connectionOwner: String
|
|
870
|
+
"True when integrationBindingUsage can answer for this binding: an active scoped binding of a usage-reporting kind. Passthrough bindings never report usage — a shared credential's spend belongs to no one app."
|
|
871
|
+
reportsUsage: Boolean!
|
|
872
|
+
"The binding's bind options: chosen or defaulted at bind time, or, for a binding recorded before an option existed, the value such bindings were created with (legacy). Empty for most kinds."
|
|
873
|
+
options: [IntegrationBindOptionValue!]!
|
|
874
|
+
"Warnings of the recorded options, e.g. that the environment's database is a copy of production data with every setting stored in it. Empty for most bindings."
|
|
875
|
+
warnings: [String!]!
|
|
876
|
+
"True when the signed-in caller can mint this binding's one-time .env reveal now (revealIntegrationEnv): the binding is active and carries credentials, the caller owns the app, and no reveal was ever issued for it (bindings older than 30 days never qualify)."
|
|
877
|
+
revealAvailable: Boolean!
|
|
878
|
+
}
|
|
879
|
+
"What one binding's per-app resource consumed, read from the provider's own accounting and cached for about a minute. Figures, labels and units are the provider's and are shown as-is."
|
|
880
|
+
type IntegrationUsage {
|
|
881
|
+
bindingID: ID!
|
|
882
|
+
kind: String!
|
|
883
|
+
"Start of the window the figures cover (RFC3339); null means since the resource was created."
|
|
884
|
+
periodStart: String
|
|
885
|
+
"End of the window (RFC3339); null means now."
|
|
886
|
+
periodEnd: String
|
|
887
|
+
metrics: [IntegrationUsageMetric!]!
|
|
888
|
+
"Optional https link to this app's resource in the provider's console."
|
|
889
|
+
consoleURL: String
|
|
890
|
+
"When unfazed read these figures from the provider (RFC3339)."
|
|
891
|
+
fetchedAt: String!
|
|
892
|
+
"Why the figures are unavailable (the provider failed, timed out or reported malformed data); null on success. Never carries credential values."
|
|
893
|
+
error: String
|
|
894
|
+
}
|
|
895
|
+
type IntegrationUsageMetric {
|
|
896
|
+
"Stable machine name, e.g. compute_hours."
|
|
897
|
+
name: String!
|
|
898
|
+
label: String!
|
|
899
|
+
value: Float!
|
|
900
|
+
"Display unit; may be empty for plain counts."
|
|
901
|
+
unit: String!
|
|
902
|
+
"Optional cap configured for this app, in the same unit."
|
|
903
|
+
limit: Float
|
|
527
904
|
}
|
|
528
905
|
type IntegrationConnectionPayload {
|
|
529
906
|
connection: IntegrationConnection!
|
|
530
907
|
}
|
|
531
908
|
type IntegrationBindingPayload {
|
|
532
909
|
binding: IntegrationBinding!
|
|
533
|
-
"One-time command (curl) that prints THIS binding's
|
|
910
|
+
"One-time command (curl) that prints THIS binding's credentials as .env lines, exactly once. Present in the bind response for an active credential-carrying binding whose single reveal was not issued yet; a binding that becomes active later gets it once from revealIntegrationEnv. Never issued twice — only its hash is stored."
|
|
534
911
|
revealCommand: String
|
|
535
912
|
"RFC3339 time the unused reveal stops working."
|
|
536
913
|
revealExpiresAt: String
|
|
537
914
|
}
|
|
915
|
+
"The single one-time .env reveal of one binding, minted by revealIntegrationEnv."
|
|
916
|
+
type IntegrationEnvReveal {
|
|
917
|
+
binding: IntegrationBinding!
|
|
918
|
+
"One-time command (curl) that prints THIS binding's credentials as .env lines. Whoever runs it consumes it; it is never issued again for this binding."
|
|
919
|
+
revealCommand: String!
|
|
920
|
+
"RFC3339 time the unused reveal stops working."
|
|
921
|
+
revealExpiresAt: String!
|
|
922
|
+
}
|
|
538
923
|
"Account-level non-secret event routing. Credential/runtime grants never use this type."
|
|
539
924
|
type IntegrationSubscription {
|
|
540
925
|
id: ID!
|
|
@@ -609,6 +994,142 @@ input BindIntegrationInput {
|
|
|
609
994
|
alias: String!
|
|
610
995
|
"Optional provider-supported isolation mode. Omit to use the provider's safe default (scoped for Postgres)."
|
|
611
996
|
mode: String
|
|
997
|
+
"Choices for the kind's bindOptions, by name. Omitted options take their default; an option the app does not take (e.g. an environment-only option on a main app) is refused."
|
|
998
|
+
options: [IntegrationBindOptionInput!]
|
|
999
|
+
}
|
|
1000
|
+
"The account's chosen model-provider connection for one harness (docs/run-design.md phase 12 step 2). connectionName and kind are omitted when the referenced connection was since deleted."
|
|
1001
|
+
type RunHarnessSetting {
|
|
1002
|
+
harness: String!
|
|
1003
|
+
connectionID: ID!
|
|
1004
|
+
connectionName: String
|
|
1005
|
+
kind: String
|
|
1006
|
+
model: String
|
|
1007
|
+
updatedAt: String!
|
|
1008
|
+
}
|
|
1009
|
+
type RunHarnessSettingPayload {
|
|
1010
|
+
setting: RunHarnessSetting!
|
|
1011
|
+
}
|
|
1012
|
+
"A named run bundle (docs/run-design.md phase 12 step 3): base harness, optional provider connection + model, extra env. A preset picks a CONNECTION, never carries a key; an env value may reference a workspace name as \"$NAME\", resolved when a run is created."
|
|
1013
|
+
type RunPreset {
|
|
1014
|
+
name: String!
|
|
1015
|
+
description: String!
|
|
1016
|
+
harness: String!
|
|
1017
|
+
connectionID: ID
|
|
1018
|
+
"Set when the referenced connection still exists: its display name and kind."
|
|
1019
|
+
connectionName: String
|
|
1020
|
+
kind: String
|
|
1021
|
+
model: String
|
|
1022
|
+
env: [RunPresetEnv!]!
|
|
1023
|
+
createdAt: String!
|
|
1024
|
+
updatedAt: String!
|
|
1025
|
+
}
|
|
1026
|
+
type RunPresetEnv {
|
|
1027
|
+
name: String!
|
|
1028
|
+
value: String!
|
|
1029
|
+
}
|
|
1030
|
+
type RunPresetPayload {
|
|
1031
|
+
preset: RunPreset!
|
|
1032
|
+
}
|
|
1033
|
+
input RunPresetEnvInput {
|
|
1034
|
+
name: String!
|
|
1035
|
+
value: String!
|
|
1036
|
+
}
|
|
1037
|
+
input SaveRunPresetInput {
|
|
1038
|
+
name: String!
|
|
1039
|
+
description: String
|
|
1040
|
+
harness: String!
|
|
1041
|
+
connectionID: ID
|
|
1042
|
+
model: String
|
|
1043
|
+
env: [RunPresetEnvInput!]
|
|
1044
|
+
}
|
|
1045
|
+
input DeleteRunPresetInput {
|
|
1046
|
+
name: String!
|
|
1047
|
+
}
|
|
1048
|
+
"An account-level run trigger (docs/run-design.md phase 13): an inbound webhook event becomes an agent run. The secret authenticates deliveries; it is returned only by runTriggerSecret."
|
|
1049
|
+
type RunTrigger {
|
|
1050
|
+
id: ID!
|
|
1051
|
+
name: String!
|
|
1052
|
+
enabled: Boolean!
|
|
1053
|
+
"\"webhook\" (generic HMAC/bearer) or \"github\" (X-Hub-Signature-256)."
|
|
1054
|
+
source: String!
|
|
1055
|
+
"Event names that fire (github: X-GitHub-Event); empty fires on every event."
|
|
1056
|
+
filter: [String!]!
|
|
1057
|
+
template: RunTriggerTemplate!
|
|
1058
|
+
cooldownSeconds: Int!
|
|
1059
|
+
"Allow parallel firings; off = one at a time, later firings queue (owner decision D3)."
|
|
1060
|
+
allowParallel: Boolean!
|
|
1061
|
+
"The POST endpoint to configure at the sender: /hooks/runs/{id}."
|
|
1062
|
+
hookPath: String!
|
|
1063
|
+
"Recent firings, newest first."
|
|
1064
|
+
firings: [RunTriggerFiring!]!
|
|
1065
|
+
"Firings waiting for a slot (cooldown or a still-running previous firing)."
|
|
1066
|
+
queued: Int!
|
|
1067
|
+
createdAt: String!
|
|
1068
|
+
updatedAt: String!
|
|
1069
|
+
}
|
|
1070
|
+
type RunTriggerTemplate {
|
|
1071
|
+
workspaceID: ID!
|
|
1072
|
+
alias: String
|
|
1073
|
+
harness: String
|
|
1074
|
+
preset: String
|
|
1075
|
+
"May hold {{event.<dotted.path>}} placeholders, interpolated from the JSON payload."
|
|
1076
|
+
prompt: String!
|
|
1077
|
+
access: String
|
|
1078
|
+
maxSeconds: Int
|
|
1079
|
+
metadata: JSON
|
|
1080
|
+
}
|
|
1081
|
+
type RunTriggerFiring {
|
|
1082
|
+
id: ID!
|
|
1083
|
+
at: String!
|
|
1084
|
+
"started | queued | skipped | failed | expired"
|
|
1085
|
+
status: String!
|
|
1086
|
+
summary: String
|
|
1087
|
+
runID: ID
|
|
1088
|
+
reason: String
|
|
1089
|
+
}
|
|
1090
|
+
type RunTriggerPayload {
|
|
1091
|
+
trigger: RunTrigger!
|
|
1092
|
+
}
|
|
1093
|
+
input RunTriggerTemplateInput {
|
|
1094
|
+
workspaceID: ID!
|
|
1095
|
+
alias: String
|
|
1096
|
+
harness: String
|
|
1097
|
+
preset: String
|
|
1098
|
+
prompt: String!
|
|
1099
|
+
access: String
|
|
1100
|
+
maxSeconds: Int
|
|
1101
|
+
metadata: JSON
|
|
1102
|
+
}
|
|
1103
|
+
input SaveRunTriggerInput {
|
|
1104
|
+
"Empty creates; a set id updates that trigger."
|
|
1105
|
+
id: ID
|
|
1106
|
+
name: String!
|
|
1107
|
+
enabled: Boolean!
|
|
1108
|
+
source: String!
|
|
1109
|
+
"Empty keeps the existing secret (a fresh one is generated on create); set replaces it."
|
|
1110
|
+
secret: String
|
|
1111
|
+
filter: [String!]
|
|
1112
|
+
template: RunTriggerTemplateInput!
|
|
1113
|
+
cooldownSeconds: Int
|
|
1114
|
+
allowParallel: Boolean
|
|
1115
|
+
}
|
|
1116
|
+
input RunTriggerIDInput {
|
|
1117
|
+
id: ID!
|
|
1118
|
+
}
|
|
1119
|
+
input SetRunHarnessProviderInput {
|
|
1120
|
+
harness: String!
|
|
1121
|
+
connectionID: ID!
|
|
1122
|
+
model: String
|
|
1123
|
+
}
|
|
1124
|
+
input ClearRunHarnessProviderInput {
|
|
1125
|
+
harness: String!
|
|
1126
|
+
}
|
|
1127
|
+
"One of the caller's own connections eligible to back a harness: its kind implements harness credentials and actually serves this one."
|
|
1128
|
+
type RunHarnessProviderChoice {
|
|
1129
|
+
harness: String!
|
|
1130
|
+
connectionID: ID!
|
|
1131
|
+
name: String!
|
|
1132
|
+
kind: String!
|
|
612
1133
|
}
|
|
613
1134
|
input IntegrationIDInput {
|
|
614
1135
|
id: ID!
|
|
@@ -681,6 +1202,8 @@ type DeploymentEventPage {
|
|
|
681
1202
|
type Invocation {
|
|
682
1203
|
id: ID!
|
|
683
1204
|
functionID: ID!
|
|
1205
|
+
"True while the original invocation is unfinished. Query functionInvocation with this ID; do not start a new invocation to check its outcome."
|
|
1206
|
+
pending: Boolean!
|
|
684
1207
|
ok: Boolean!
|
|
685
1208
|
result: JSON
|
|
686
1209
|
stdout: String!
|
|
@@ -696,7 +1219,7 @@ enum CurrentActorKind {
|
|
|
696
1219
|
OWNER
|
|
697
1220
|
"An automated caller using a self-registered bearer token. Subject to free-tier usage/resource limits; a user can claim it to link it to their account."
|
|
698
1221
|
AGENT
|
|
699
|
-
"A human signed in via
|
|
1222
|
+
"A human signed in via an enabled identity provider, who manages their linked agents and apps."
|
|
700
1223
|
USER
|
|
701
1224
|
}
|
|
702
1225
|
|
|
@@ -714,20 +1237,115 @@ type CurrentActorResources {
|
|
|
714
1237
|
}
|
|
715
1238
|
|
|
716
1239
|
"""
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
callers) and agents, unlike `usage`/`resources` above, which are agent-only.
|
|
1240
|
+
Recorded compute for the caller's raw owner ID in the current UTC calendar
|
|
1241
|
+
month. Linked API identities retain separate ownership and are not included.
|
|
1242
|
+
This is metering, not an invoice: no prices or charges are calculated. Running
|
|
1243
|
+
VMs may await an hourly checkpoint; builds, storage, network and provider API
|
|
1244
|
+
usage are not included. Null means the ledger could not be read.
|
|
723
1245
|
"""
|
|
724
1246
|
type CurrentActorCompute {
|
|
725
1247
|
seconds: Float!
|
|
726
1248
|
mibSeconds: Float!
|
|
727
1249
|
since: String!
|
|
728
1250
|
until: String!
|
|
1251
|
+
"When this ledger snapshot was read, in UTC."
|
|
1252
|
+
generatedAt: String!
|
|
1253
|
+
"Latest recorded activity in the period, not a completeness watermark."
|
|
1254
|
+
lastRecordedAt: String
|
|
1255
|
+
"Corrupt, conflicting, or memory-less records make this report incomplete."
|
|
1256
|
+
incomplete: Boolean!
|
|
1257
|
+
byMode: [ComputeModeUsage!]!
|
|
729
1258
|
}
|
|
730
1259
|
|
|
1260
|
+
type ComputeModeUsage {
|
|
1261
|
+
mode: String!
|
|
1262
|
+
seconds: Float!
|
|
1263
|
+
mibSeconds: Float!
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
"An agent (docs/agents-design.md): a long-lived worker with a name and a job whose setup a run inherits. It owns a hidden workspace with its computer, a BOX deployment, in it."
|
|
1267
|
+
type Agent {
|
|
1268
|
+
id: ID!
|
|
1269
|
+
ownerId: ID!
|
|
1270
|
+
name: String!
|
|
1271
|
+
"The one-line role under the name."
|
|
1272
|
+
job: String!
|
|
1273
|
+
"Standing rules the harness is given on every run; never sent as a task."
|
|
1274
|
+
description: String!
|
|
1275
|
+
"The agent's own workspace (hidden from the apps lists): its env and secrets, the home of its computer."
|
|
1276
|
+
workspaceID: ID!
|
|
1277
|
+
"The alias of the agent's computer (its SSH user name); null until it exists."
|
|
1278
|
+
boxAlias: String
|
|
1279
|
+
"The agent's computer: the newest BOX deployment in its workspace (BUILDING while it starts, FAILED when its build failed)."
|
|
1280
|
+
computer: Deployment
|
|
1281
|
+
"The harness a run of this agent uses; null means the node's first catalogue entry."
|
|
1282
|
+
harness: String
|
|
1283
|
+
"The provider connection backing its runs; null means the account's per-harness setting."
|
|
1284
|
+
connectionID: ID
|
|
1285
|
+
"Set when the referenced connection still exists: its display name and kind."
|
|
1286
|
+
connectionName: String
|
|
1287
|
+
kind: String
|
|
1288
|
+
model: String
|
|
1289
|
+
"read-only or read-write: what a run of this agent may do."
|
|
1290
|
+
access: String!
|
|
1291
|
+
"\"human\" routes the harness's guarded actions to a person; empty keeps the harness's defaults."
|
|
1292
|
+
approval: String!
|
|
1293
|
+
"The workspaces the agent works on; the first supplies a run's files and env until runs execute on the agent's computer."
|
|
1294
|
+
scopeWorkspaceIDs: [ID!]!
|
|
1295
|
+
"Remembered \"always\" answers to permission questions of this agent's runs: a tool name, a whole MCP server (mcp__postgres), or a tool with an input prefix (Bash(git push:*))."
|
|
1296
|
+
allowedTools: [String!]!
|
|
1297
|
+
"Derived on the server from the newest run and the computer, so every surface agrees."
|
|
1298
|
+
state: AgentState!
|
|
1299
|
+
"One line about the state: the current task, the pending question, or what failed."
|
|
1300
|
+
stateDetail: String!
|
|
1301
|
+
"The agent's newest run, whoever messaged it."
|
|
1302
|
+
lastRun: Run
|
|
1303
|
+
createdAt: String!
|
|
1304
|
+
updatedAt: String!
|
|
1305
|
+
}
|
|
1306
|
+
"What an agent is doing: STARTING (computer being made), IDLE, WORKING (a run in flight), NEEDS_YOU (a run waits for an answer), ASLEEP (computer stopped), FAILED (the computer or the last run)."
|
|
1307
|
+
enum AgentState {
|
|
1308
|
+
STARTING
|
|
1309
|
+
IDLE
|
|
1310
|
+
WORKING
|
|
1311
|
+
NEEDS_YOU
|
|
1312
|
+
ASLEEP
|
|
1313
|
+
FAILED
|
|
1314
|
+
}
|
|
1315
|
+
type AgentPayload {
|
|
1316
|
+
agent: Agent!
|
|
1317
|
+
}
|
|
1318
|
+
input CreateAgentInput {
|
|
1319
|
+
name: String!
|
|
1320
|
+
job: String
|
|
1321
|
+
description: String
|
|
1322
|
+
harness: String
|
|
1323
|
+
connectionID: ID
|
|
1324
|
+
model: String
|
|
1325
|
+
access: String
|
|
1326
|
+
approval: String
|
|
1327
|
+
scopeWorkspaceIDs: [ID!]
|
|
1328
|
+
"The computer's size; omitted uses the platform defaults."
|
|
1329
|
+
boxResources: BoxResourcesInput
|
|
1330
|
+
}
|
|
1331
|
+
input UpdateAgentInput {
|
|
1332
|
+
id: ID!
|
|
1333
|
+
name: String
|
|
1334
|
+
job: String
|
|
1335
|
+
description: String
|
|
1336
|
+
harness: String
|
|
1337
|
+
connectionID: ID
|
|
1338
|
+
model: String
|
|
1339
|
+
access: String
|
|
1340
|
+
approval: String
|
|
1341
|
+
"Replaces the scope when given; an empty list clears it."
|
|
1342
|
+
scopeWorkspaceIDs: [ID!]
|
|
1343
|
+
"Replaces the remembered permission rules when given; an empty list forgets them all."
|
|
1344
|
+
allowedTools: [String!]
|
|
1345
|
+
}
|
|
1346
|
+
input DeleteAgentInput {
|
|
1347
|
+
id: ID!
|
|
1348
|
+
}
|
|
731
1349
|
enum RunStatus {
|
|
732
1350
|
QUEUED
|
|
733
1351
|
RUNNING
|
|
@@ -753,13 +1371,22 @@ that executed one task and was destroyed when it exited. Deployments answer
|
|
|
753
1371
|
"what is running"; runs answer "what happened".
|
|
754
1372
|
"""
|
|
755
1373
|
type Run {
|
|
1374
|
+
"Source workspace and its current alias holders, when still visible."
|
|
1375
|
+
source: RunSource
|
|
1376
|
+
events(limit: Int = 100): [RunEvent!]
|
|
1377
|
+
console(tailBytes: Int = 16384): RunConsole
|
|
1378
|
+
transcript(tailBytes: Int = 16384): RunTranscript
|
|
756
1379
|
id: ID!
|
|
757
1380
|
workspaceID: ID!
|
|
1381
|
+
"The agent this run is a task of (docs/agents-design.md); null for a plain app run."
|
|
1382
|
+
agentID: ID
|
|
758
1383
|
ownerId: ID!
|
|
759
1384
|
status: RunStatus!
|
|
760
1385
|
rawStatus: String!
|
|
761
1386
|
command: String
|
|
762
1387
|
harness: String
|
|
1388
|
+
"The preset this run was created from (display-only; resolved at creation)."
|
|
1389
|
+
preset: String
|
|
763
1390
|
prompt: String
|
|
764
1391
|
setup: [String!]!
|
|
765
1392
|
skills: [String!]!
|
|
@@ -800,6 +1427,19 @@ type Run {
|
|
|
800
1427
|
settledAt: String
|
|
801
1428
|
}
|
|
802
1429
|
|
|
1430
|
+
"A terminal source summary: run navigation cannot recursively expand runs."
|
|
1431
|
+
type RunSource {
|
|
1432
|
+
id: ID!
|
|
1433
|
+
name: String!
|
|
1434
|
+
deployments: [RunSourceDeployment!]!
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
type RunSourceDeployment {
|
|
1438
|
+
id: ID!
|
|
1439
|
+
alias: String
|
|
1440
|
+
createdAt: String!
|
|
1441
|
+
}
|
|
1442
|
+
|
|
803
1443
|
"One bound integration's contribution to a run. env is the credential set injected: empty (none), read-only or read-write."
|
|
804
1444
|
type RunIntegration {
|
|
805
1445
|
kind: String!
|
|
@@ -892,6 +1532,8 @@ type CurrentActorAgent {
|
|
|
892
1532
|
claimedAt: String
|
|
893
1533
|
"Deployments owned by this linked agent. Resolved lazily — only fetched when selected."
|
|
894
1534
|
deployments: [Deployment!]!
|
|
1535
|
+
"Every app this agent serves right now, across its workspaces: what deleteLinkedAgent takes offline, and the exact list its confirmAliases must name."
|
|
1536
|
+
liveApps: [LiveApp!]!
|
|
895
1537
|
}
|
|
896
1538
|
|
|
897
1539
|
type CurrentActor {
|
|
@@ -914,11 +1556,160 @@ type CurrentActor {
|
|
|
914
1556
|
linkedAgents: [CurrentActorAgent!]!
|
|
915
1557
|
}
|
|
916
1558
|
|
|
1559
|
+
"The authenticated account. Nested fields can be delivered independently with @defer."
|
|
1560
|
+
type Viewer {
|
|
1561
|
+
availableIntegrations: [IntegrationKind!]
|
|
1562
|
+
integrationConnections: [IntegrationConnection!]
|
|
1563
|
+
integrationSubscriptions: [IntegrationSubscription!]
|
|
1564
|
+
integrationBindings: [IntegrationBinding!]
|
|
1565
|
+
customDomains: [CustomDomain!]
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
|
|
1569
|
+
"Current app placement without assessing destinations or granting placement authority."
|
|
1570
|
+
type PlacementDisplay {
|
|
1571
|
+
current: PlacementCurrent
|
|
1572
|
+
target: PlacementServer
|
|
1573
|
+
blockers: [PlacementBlocker!]!
|
|
1574
|
+
}
|
|
1575
|
+
"Public metadata for the exact server currently assigned to the app."
|
|
1576
|
+
type PlacementServer {
|
|
1577
|
+
id: ID!
|
|
1578
|
+
"CONTROL_PLANE or WORKER."
|
|
1579
|
+
kind: String!
|
|
1580
|
+
name: String!
|
|
1581
|
+
"Empty when the server has no configured region."
|
|
1582
|
+
region: String!
|
|
1583
|
+
incarnation: String!
|
|
1584
|
+
}
|
|
1585
|
+
|
|
1586
|
+
"Read-only placement metadata. Blockers are observations, never permission to move data."
|
|
1587
|
+
type PlacementCatalog {
|
|
1588
|
+
current: PlacementCurrent
|
|
1589
|
+
targets: [PlacementTarget!]!
|
|
1590
|
+
"Regions advertised by the caller's targets, before the optional region filter."
|
|
1591
|
+
regions: [String!]!
|
|
1592
|
+
blockers: [PlacementBlocker!]!
|
|
1593
|
+
"Where a new app would land. Set only when no current app is selected."
|
|
1594
|
+
newApps: PlacementDecision
|
|
1595
|
+
}
|
|
1596
|
+
"Where a new app lands. The first release starts on the control plane; a WORKER choice then moves the app there with its App State through the ordinary placement move. Existing apps keep their server."
|
|
1597
|
+
type PlacementDecision {
|
|
1598
|
+
serverID: String!
|
|
1599
|
+
serverName: String!
|
|
1600
|
+
"CONTROL_PLANE or WORKER."
|
|
1601
|
+
kind: String!
|
|
1602
|
+
region: String!
|
|
1603
|
+
"request, account_default, default or platform."
|
|
1604
|
+
source: String!
|
|
1605
|
+
"The server that was asked for when the app cannot use it; empty otherwise."
|
|
1606
|
+
requested: String!
|
|
1607
|
+
"Why the app stays on the control plane, e.g. worker_disconnected or static_on_control_plane; empty when it lands as chosen."
|
|
1608
|
+
code: String!
|
|
1609
|
+
message: String!
|
|
1610
|
+
}
|
|
1611
|
+
type PlacementTarget {
|
|
1612
|
+
id: ID!
|
|
1613
|
+
"CONTROL_PLANE or WORKER."
|
|
1614
|
+
kind: String!
|
|
1615
|
+
name: String!
|
|
1616
|
+
"Empty when the server has no configured region."
|
|
1617
|
+
region: String!
|
|
1618
|
+
"Exact installation identity; empty when it is unknown for the default server."
|
|
1619
|
+
incarnation: String!
|
|
1620
|
+
status: String!
|
|
1621
|
+
connected: Boolean!
|
|
1622
|
+
"An authenticated session on a settled runtime release; not a data-admission grant."
|
|
1623
|
+
ready: Boolean!
|
|
1624
|
+
deployBlockers: [PlacementBlocker!]!
|
|
1625
|
+
moveBlockers: [PlacementBlocker!]!
|
|
1626
|
+
}
|
|
1627
|
+
type PlacementBlocker { code: String!, message: String! }
|
|
1628
|
+
type PlacementCurrent {
|
|
1629
|
+
deploymentID: ID!
|
|
1630
|
+
alias: String!
|
|
1631
|
+
aliasRevision: String!
|
|
1632
|
+
"Empty if the exact current placement is unknown."
|
|
1633
|
+
targetID: String!
|
|
1634
|
+
incarnation: String!
|
|
1635
|
+
state: String!
|
|
1636
|
+
blockers: [PlacementBlocker!]!
|
|
1637
|
+
}
|
|
1638
|
+
input PlacementTargetsInput {
|
|
1639
|
+
workspaceID: ID
|
|
1640
|
+
alias: String
|
|
1641
|
+
deploymentID: ID
|
|
1642
|
+
"Filter exact servers by region; this does not select a regional scheduler."
|
|
1643
|
+
region: String
|
|
1644
|
+
}
|
|
1645
|
+
|
|
1646
|
+
type PlacementMoveApp { deploymentID: ID!, workspaceID: ID!, alias: String! }
|
|
1647
|
+
type PlacementMovePlan {
|
|
1648
|
+
deploymentID: ID!
|
|
1649
|
+
"Public retry key; empty for an older operator-created move."
|
|
1650
|
+
idempotencyKey: String!
|
|
1651
|
+
planDigest: String!
|
|
1652
|
+
targetID: String!
|
|
1653
|
+
targetIncarnation: String!
|
|
1654
|
+
affectedApps: [PlacementMoveApp!]!
|
|
1655
|
+
resourceCount: Int!
|
|
1656
|
+
}
|
|
1657
|
+
type PlacementMove {
|
|
1658
|
+
id: ID!
|
|
1659
|
+
phase: String!
|
|
1660
|
+
complete: Boolean!
|
|
1661
|
+
running: Boolean!
|
|
1662
|
+
resumable: Boolean!
|
|
1663
|
+
plan: PlacementMovePlan!
|
|
1664
|
+
}
|
|
1665
|
+
input PlacementMovePlanInput {
|
|
1666
|
+
deploymentID: ID!
|
|
1667
|
+
targetID: String!
|
|
1668
|
+
targetIncarnation: String!
|
|
1669
|
+
idempotencyKey: String!
|
|
1670
|
+
}
|
|
1671
|
+
input BeginPlacementMoveInput {
|
|
1672
|
+
deploymentID: ID!
|
|
1673
|
+
targetID: String!
|
|
1674
|
+
targetIncarnation: String!
|
|
1675
|
+
idempotencyKey: String!
|
|
1676
|
+
planDigest: String!
|
|
1677
|
+
}
|
|
1678
|
+
input PlacementMoveStatusInput {
|
|
1679
|
+
deploymentID: ID!
|
|
1680
|
+
idempotencyKey: String
|
|
1681
|
+
moveID: ID
|
|
1682
|
+
}
|
|
1683
|
+
input RunPlacementMoveInput {
|
|
1684
|
+
deploymentID: ID!
|
|
1685
|
+
idempotencyKey: String
|
|
1686
|
+
moveID: ID!
|
|
1687
|
+
}
|
|
1688
|
+
|
|
917
1689
|
type Query {
|
|
1690
|
+
"Read-only exact server-move plan for a current app. Ordinary apps need no operator enrollment: App State follows compute and external connections stay unchanged. Existing managed-data pilots retain their shared-data group. Does not reserve or start a move."
|
|
1691
|
+
placementMovePlan(input: PlacementMovePlanInput!): PlacementMovePlan!
|
|
1692
|
+
"Saved move by key/ID; with neither selector, the app's incomplete move. Null is absence, never evidence that a timed-out operation rolled back."
|
|
1693
|
+
placementMove(input: PlacementMoveStatusInput!): PlacementMove
|
|
1694
|
+
|
|
1695
|
+
"Authoritative current server for a visible app, without assessing destination eligibility."
|
|
1696
|
+
deploymentPlacement(deploymentID: ID!): PlacementDisplay
|
|
1697
|
+
"Servers for the caller or an owned app/workspace. Shared-project access alone does not expose another owner's servers. Historical releases have no current placement."
|
|
1698
|
+
placementTargets(input: PlacementTargetsInput): PlacementCatalog!
|
|
1699
|
+
"Where a new app would land for the caller, or for the owner of an owned workspace. Read-only."
|
|
1700
|
+
newAppPlacement(workspaceID: ID): PlacementDecision!
|
|
1701
|
+
|
|
1702
|
+
viewer: Viewer
|
|
918
1703
|
whoami: CurrentActor!
|
|
919
1704
|
functions: [Function!]!
|
|
920
1705
|
functionsPage(input: PageInput): FunctionPage!
|
|
921
1706
|
function(id: ID!): Function
|
|
1707
|
+
"Read the caller's saved invocation without executing it again. Requires deploy scope, as invoking does."
|
|
1708
|
+
functionInvocation(id: ID!): Invocation!
|
|
1709
|
+
"Read one visible registration without contacting a worker or starting work."
|
|
1710
|
+
functionRegistration(id: ID!): FunctionRegistration!
|
|
1711
|
+
"Discover saved registrations, including a lost initial response. Ordered by immutable ID; limit 1–100."
|
|
1712
|
+
functionRegistrations(after: ID, limit: Int = 20): FunctionRegistrationPage!
|
|
922
1713
|
"Sources visible to the current account: directly owned plus those of linked claimed agents for a user; own for an agent; all for the operator. The same scope as deployments, so an agent's apps can be grouped into the caller's projects."
|
|
923
1714
|
workspaces: [Workspace!]!
|
|
924
1715
|
"Paginated sources visible to the current account, with the same ownership scope as workspaces."
|
|
@@ -932,8 +1723,14 @@ type Query {
|
|
|
932
1723
|
myTeamInvites: [TeamInviteForMe!]!
|
|
933
1724
|
"The signed-in owner's BYO custom domains, oldest first."
|
|
934
1725
|
customDomains: [CustomDomain!]!
|
|
1726
|
+
"The apps a custom domain of yours may move to (moveCustomDomain), by alias."
|
|
1727
|
+
customDomainMoveTargets(domain: String!): [CustomDomainMoveTarget!]!
|
|
935
1728
|
"The signed-in account's SSH public keys — the keys that may open its boxes."
|
|
936
1729
|
sshKeys: [SSHKey!]!
|
|
1730
|
+
"The sign-in providers the platform offers, and which of them are linked to the signed-in account."
|
|
1731
|
+
signInMethods: [SignInMethod!]!
|
|
1732
|
+
"Computers whose git is signed in to platform git with the signed-in account, newest first."
|
|
1733
|
+
gitSignIns: [GitSignIn!]!
|
|
937
1734
|
"Integration types available to connect (postgres, redis, …)."
|
|
938
1735
|
availableIntegrations: [IntegrationKind!]!
|
|
939
1736
|
"The signed-in owner's connected backends."
|
|
@@ -942,6 +1739,8 @@ type Query {
|
|
|
942
1739
|
projectSharedConnections(projectID: ID!): [IntegrationConnection!]!
|
|
943
1740
|
"The signed-in owner's app bindings (which app uses which backend)."
|
|
944
1741
|
integrationBindings: [IntegrationBinding!]!
|
|
1742
|
+
"Usage of one binding's per-app resource, read live from its provider (bounded, cached ~60s). Fails for a binding that does not report usage (see IntegrationBinding.reportsUsage); a provider failure is returned in error, not as a GraphQL error."
|
|
1743
|
+
integrationBindingUsage(id: ID!): IntegrationUsage!
|
|
945
1744
|
"Account-level event subscriptions, including disabled state."
|
|
946
1745
|
integrationSubscriptions: [IntegrationSubscription!]!
|
|
947
1746
|
"Secret-free configuration effective for this app's next deploy or lifecycle event."
|
|
@@ -950,6 +1749,10 @@ type Query {
|
|
|
950
1749
|
publishDomainProbe(bindingID: ID!): PublishDomainProbe!
|
|
951
1750
|
workspaceFiles(workspaceID: ID!): [WorkspaceFile!]!
|
|
952
1751
|
workspaceFilesPage(input: ListWorkspaceFilesInput!): WorkspaceFilePage!
|
|
1752
|
+
"History of an app with platform git: its branch's commits, newest first (limit default 20, max 100); before continues from a page's nextBefore."
|
|
1753
|
+
appCommits(workspaceID: ID!, limit: Int, before: String): AppCommitPage!
|
|
1754
|
+
"One commit of an app with platform git with its diff against its first parent."
|
|
1755
|
+
appCommit(workspaceID: ID!, sha: String!): AppCommitDiff!
|
|
953
1756
|
readWorkspaceFile(input: ReadWorkspaceFileInput!): WorkspaceFileContent
|
|
954
1757
|
workspaceEnv(workspaceID: ID!): [WorkspaceEnvVar!]!
|
|
955
1758
|
workspaceEnvPage(input: ListWorkspaceEnvInput!): WorkspaceEnvPage!
|
|
@@ -974,10 +1777,25 @@ type Query {
|
|
|
974
1777
|
deploymentEventsPage(input: ListDeploymentEventsInput!): DeploymentEventPage!
|
|
975
1778
|
"The harness presets a run may name: what each is and which workspace secrets it needs. Empty when this node's box image carries no catalogue."
|
|
976
1779
|
runHarnesses: [RunHarness!]!
|
|
1780
|
+
"The caller's chosen model-provider connection per harness. A run of that harness receives its env unless the workspace sets the same name."
|
|
1781
|
+
runHarnessSettings: [RunHarnessSetting!]!
|
|
1782
|
+
"The caller's named run presets, sorted by name."
|
|
1783
|
+
runPresets: [RunPreset!]!
|
|
1784
|
+
"The caller's run triggers, sorted by name."
|
|
1785
|
+
runTriggers: [RunTrigger!]!
|
|
1786
|
+
"One trigger's shared secret — shown to its owner to configure the sending side."
|
|
1787
|
+
runTriggerSecret(input: RunTriggerIDInput!): String!
|
|
1788
|
+
"The caller's own connections eligible to back each harness in the catalogue, computed server-side (kind implements harness credentials and actually serves that harness)."
|
|
1789
|
+
runHarnessProviderChoices: [RunHarnessProviderChoice!]!
|
|
1790
|
+
"The models a connection's provider offers for a harness, fetched live from the provider (e.g. GET /v1/models); empty when the kind cannot list models (no remote catalogue, or an oauth-only credential with no API access) — the caller falls back to free text."
|
|
1791
|
+
runHarnessProviderModels(harness: String!, connectionID: ID!): [String!]!
|
|
977
1792
|
"One agent run visible to the caller; not-found otherwise."
|
|
978
1793
|
run(id: ID!): Run!
|
|
979
1794
|
"The caller's agent runs, newest first."
|
|
980
1795
|
runs(input: ListRunsInput): RunPage!
|
|
1796
|
+
"Agents the caller may see (docs/agents-design.md): its own and those of identities it claimed; a claimed identity sees only its own, never its claimer's. Oldest first."
|
|
1797
|
+
agents: [Agent!]!
|
|
1798
|
+
agent(id: ID!): Agent!
|
|
981
1799
|
"A run's own history, oldest first (at most limit, default 100)."
|
|
982
1800
|
runEvents(runID: ID!, limit: Int): [RunEvent!]!
|
|
983
1801
|
"The live console tail of a RUNNING run (tailBytes, default 16384)."
|
|
@@ -994,8 +1812,19 @@ type Query {
|
|
|
994
1812
|
}
|
|
995
1813
|
|
|
996
1814
|
type Mutation {
|
|
1815
|
+
"Persist the exact previewed move before execution. Retry with the same key/digest after a lost response."
|
|
1816
|
+
beginPlacementMove(input: BeginPlacementMoveInput!): PlacementMove!
|
|
1817
|
+
"Execute or resume the saved move. On interruption, read status and retry this same ID; cancellation does not undo it."
|
|
1818
|
+
runPlacementMove(input: RunPlacementMoveInput!): PlacementMove!
|
|
1819
|
+
|
|
997
1820
|
"Start an agent run; returns once its VM has started (RUNNING) or FAILED with error."
|
|
998
1821
|
createRun(input: CreateRunInput!): Run!
|
|
1822
|
+
"Create an agent: the record, its own hidden workspace, and its computer (a BOX deployment, sized like any box). A name is enough; the rest defaults. Requires a claimed account, like a box."
|
|
1823
|
+
createAgent(input: CreateAgentInput!): AgentPayload!
|
|
1824
|
+
"Change an agent's setup; omitted fields stay as they are. Owner only."
|
|
1825
|
+
updateAgent(input: UpdateAgentInput!): AgentPayload!
|
|
1826
|
+
"Delete an agent: its active runs are cancelled, its computer and disk deleted, its workspace removed. The agent itself cannot be restored; its computer's files and disk are kept by the platform for 30 days for investigation, then erased. Owner only."
|
|
1827
|
+
deleteAgent(input: DeleteAgentInput!): DeleteResultPayload!
|
|
999
1828
|
"Stop an agent run (idempotent on an already-cancelled run)."
|
|
1000
1829
|
cancelRun(id: ID!): Run!
|
|
1001
1830
|
"Answer a BLOCKED run's pending question; the run resumes."
|
|
@@ -1003,7 +1832,11 @@ type Mutation {
|
|
|
1003
1832
|
"Continue a finished run: a new run in the same workspace with the parent's context prepended to the prompt."
|
|
1004
1833
|
followUpRun(input: FollowUpRunInput!): Run!
|
|
1005
1834
|
registerFunction(input: RegisterFunctionInput!): Function!
|
|
1835
|
+
"Reconcile the original registration, preserving its source and worker identity. May finalize an interrupted preparation as failed; never retries a completed failed execution. Requires deploy scope."
|
|
1836
|
+
resumeFunctionRegistration(id: ID!): FunctionRegistration!
|
|
1006
1837
|
invokeFunction(input: InvokeFunctionInput!): Invocation!
|
|
1838
|
+
"Permanently delete a published function: it stops being invocable and its stored source and bundle are removed. Saved invocation results are not affected. Unpublished registrations are not deleted. Requires deploy scope. Not idempotent: once deleted, the ID reports function was not found like any unknown ID, so a client retrying its own delete may treat that error as already deleted."
|
|
1839
|
+
deleteFunction(input: DeleteFunctionInput!): DeleteResultPayload!
|
|
1007
1840
|
createWorkspace(input: CreateWorkspaceInput!): CreateWorkspacePayload!
|
|
1008
1841
|
"Rename an app (its workspace). Does not change its alias or public URL."
|
|
1009
1842
|
renameWorkspace(input: RenameWorkspaceInput!): Workspace!
|
|
@@ -1041,10 +1874,28 @@ type Mutation {
|
|
|
1041
1874
|
connectIntegration(input: ConnectIntegrationInput!): IntegrationConnectionPayload!
|
|
1042
1875
|
"Start the link flow for a link integration (e.g. Telegram); returns a URL to open."
|
|
1043
1876
|
startIntegrationLink(kind: String!): IntegrationLinkPayload!
|
|
1877
|
+
"Begin the owner's OAuth authorization of a connection's MCP server: open the returned URL in a browser signed in to this account; the callback completes it."
|
|
1878
|
+
startConnectionAuthorization(input: IntegrationIDInput!): IntegrationLinkPayload!
|
|
1879
|
+
"Choose which of the caller's own connections backs a harness; refused when the caller does not own the connection or it does not serve this harness."
|
|
1880
|
+
setRunHarnessProvider(input: SetRunHarnessProviderInput!): RunHarnessSettingPayload!
|
|
1881
|
+
"Create or replace (by name) one of the caller's run presets. A preset naming a connection is refused unless the caller owns it and it serves the preset's harness."
|
|
1882
|
+
saveRunPreset(input: SaveRunPresetInput!): RunPresetPayload!
|
|
1883
|
+
"Forget a preset by name; runs already created from it are untouched."
|
|
1884
|
+
deleteRunPreset(input: DeleteRunPresetInput!): DeleteResultPayload!
|
|
1885
|
+
"Create or update a run trigger. The template's workspace must be visible to the caller; a named preset must exist."
|
|
1886
|
+
saveRunTrigger(input: SaveRunTriggerInput!): RunTriggerPayload!
|
|
1887
|
+
"Forget a trigger and its queued firings."
|
|
1888
|
+
deleteRunTrigger(input: RunTriggerIDInput!): DeleteResultPayload!
|
|
1889
|
+
"Forget the caller's chosen provider for a harness; it falls back to no credential."
|
|
1890
|
+
clearRunHarnessProvider(input: ClearRunHarnessProviderInput!): DeleteResultPayload!
|
|
1891
|
+
"Revoke (best effort, at the server) and forget a connection's OAuth grant; runs stop getting the server."
|
|
1892
|
+
revokeConnectionAuthorization(input: IntegrationIDInput!): DeleteResultPayload!
|
|
1044
1893
|
"Delete a connected backend by id. Active bindings must be unbound first; detached bindings retain it until rollback/provider cleanup completes."
|
|
1045
1894
|
deleteIntegrationConnection(input: IntegrationIDInput!): DeleteResultPayload!
|
|
1046
1895
|
"Bind a backend to ONE app. Scoped providers first create a distinct per-app resource and credential; the app receives only that credential on its next deploy."
|
|
1047
1896
|
bindIntegration(input: BindIntegrationInput!): IntegrationBindingPayload!
|
|
1897
|
+
"Mint the single one-time .env reveal of an ACTIVE credential-carrying binding that never had one — typically a binding whose provider finished provisioning after bindIntegration returned. Only the app's owner may call it; it is refused while the binding is still provisioning and once a reveal was issued for the binding."
|
|
1898
|
+
revealIntegrationEnv(input: IntegrationIDInput!): IntegrationEnvReveal!
|
|
1048
1899
|
"Attach a custom hostname (a zone already in the connected account) to a publish binding's site. Replaces the previously attached hostname, if any."
|
|
1049
1900
|
setPublishDomain(input: PublishDomainInput!): IntegrationBindingPayload!
|
|
1050
1901
|
"Detach the publish binding's custom hostname. The site stays reachable at its provider URL."
|
|
@@ -1076,6 +1927,8 @@ type Mutation {
|
|
|
1076
1927
|
addCustomDomain(input: AddCustomDomainInput!): CustomDomain!
|
|
1077
1928
|
"Detach a custom domain; the app keeps serving on its alias/URL."
|
|
1078
1929
|
removeCustomDomain(input: RemoveCustomDomainInput!): DeleteResultPayload!
|
|
1930
|
+
"Move a custom domain to another of your apps without activating it again: its Cloudflare hostname and certificate are kept and re-pointed, so it never answers \"error code: 1014\". The previous app answers it until Cloudflare has switched, usually within seconds. Only between apps of the domain's own account."
|
|
1931
|
+
moveCustomDomain(input: MoveCustomDomainInput!): CustomDomain!
|
|
1079
1932
|
writeWorkspaceTextFile(input: WriteWorkspaceTextFileInput!): WorkspaceFilePayload!
|
|
1080
1933
|
writeWorkspaceBase64File(input: WriteWorkspaceBase64FileInput!): WorkspaceFilePayload!
|
|
1081
1934
|
uploadWorkspaceFile(input: UploadWorkspaceFileInput!): WorkspaceFilePayload!
|
|
@@ -1098,31 +1951,44 @@ type Mutation {
|
|
|
1098
1951
|
adoptDeploymentAlias(input: AdoptDeploymentAliasInput!): CreateDeploymentPayload!
|
|
1099
1952
|
"Deploy a workspace's CURRENT files, detecting the kind from them (a root server.ts/index.html or an unfazed.json). The recovery path after a failed import: add/fix unfazed.json (or an entry), then deploy — no git re-fetch. Errors with what to add if the files still aren't deployable."
|
|
1100
1953
|
deployWorkspace(input: DeployWorkspaceInput!): CreateDeploymentPayload!
|
|
1101
|
-
"Import and deploy a
|
|
1954
|
+
"Import and deploy a Git repo into a new workspace using the selected provider (GitHub by default). Kind/runtime are detected from the repo root (server.ts/go.mod+main.go -> SERVICE, index.html -> STATIC) unless a root unfazed.json overrides it. For a monorepo, a root unfazed.json `apps` array deploys SEVERAL apps from one push — each {alias, rootDir} builds that subdirectory as its own app (apps[] is repo config, not an input here; the same applies to syncRepo and webhook pushes). Returns immediately with an IMPORTING status; the fetch+build runs in the background."
|
|
1102
1955
|
importRepo(input: ImportRepoInput!): ImportRepoPayload!
|
|
1103
|
-
"Link a
|
|
1956
|
+
"Link a Git repo from the selected provider to an EXISTING workspace (one with no source yet) and import it. The workspace keeps its id, env, and secrets. If unfazed.json apps[] omits the supplied/stored current alias, that alias, its current deployment, and its App State are retired."
|
|
1104
1957
|
connectRepo(input: ConnectRepoInput!): ImportRepoPayload!
|
|
1105
1958
|
syncRepo(input: SyncRepoInput!): ImportRepoPayload!
|
|
1959
|
+
"Give an app with platform git back the files of an earlier commit: one new commit by the caller on its branch, deployed like a push when the app deploys every push. Requires deploy scope."
|
|
1960
|
+
restoreAppVersion(input: RestoreAppVersionInput!): RestoreAppVersionPayload!
|
|
1961
|
+
"Move an app with platform git to a NEW private GitHub repository, created with the caller's own GitHub credential: its whole history (every branch and tag, commits untouched) is pushed there, GitHub's push webhook is installed, and the app deploys from GitHub from then on — nothing redeploys. The platform repository is kept, read-only. Only the app's owner may move it. Idempotent: an app that moved answers with its repository, and a retry finishes a move that failed part-way. Requires deploy scope."
|
|
1962
|
+
moveAppToGitHub(input: MoveAppToGitHubInput!): MoveAppToGitHubPayload!
|
|
1963
|
+
"Give an app with no linked repository its own git repository on the platform now (MCP enable_platform_git; apps get one by themselves at their next change once they serve): its current files become the first commit on main, by the caller, and every later push to main deploys it like a linked repository's. Only the app's owner may turn it on. Refused, with what to fix, when the first push would change what runs: a box, a VM size, schedule or health path set at deploy time instead of in unfazed.json, several aliases without unfazed.json apps[], or files a git import leaves out (.env, .git, node_modules). Idempotent. Requires deploy scope."
|
|
1964
|
+
enablePlatformGit(input: EnablePlatformGitInput!): EnablePlatformGitPayload!
|
|
1106
1965
|
unlinkRepo(input: UnlinkRepoInput!): DeleteResultPayload!
|
|
1107
1966
|
installRepoWebhook(input: InstallRepoWebhookInput!): ImportRepoPayload!
|
|
1108
1967
|
setRepoDeployAlias(input: SetRepoDeployAliasInput!): ImportRepoPayload!
|
|
1968
|
+
"Create an environment (e.g. staging) of a git-linked app: a sibling workspace that deploys another branch of the same repo to its own aliases. Plain env is copied, secrets are not."
|
|
1969
|
+
addRepoEnvironment(input: AddRepoEnvironmentInput!): AddRepoEnvironmentPayload!
|
|
1970
|
+
"Replace the encrypted repository token; empty removes it. Does not deploy. GitHub then uses the account token. Other providers use anonymous access."
|
|
1971
|
+
setRepoToken(workspaceID: ID!, token: String!): ImportRepoPayload!
|
|
1109
1972
|
setGitHubToken(input: SetGitHubTokenInput!): GitHubTokenStatus!
|
|
1110
1973
|
deleteGitHubToken: GitHubTokenStatus!
|
|
1111
1974
|
restartService(input: ServiceControlInput!): ServiceRuntimeStatus!
|
|
1112
1975
|
stopService(input: ServiceControlInput!): ServiceRuntimeStatus!
|
|
1113
|
-
"
|
|
1976
|
+
"Delete ONE app of a workspace and nothing else: every deployment of the alias in that workspace (its VM stopped, its URL and custom domains stop serving), its App State, its app-scoped env and secrets, and its integration bindings. The workspace, its files and defaults, and its other apps keep serving. In a git-linked workspace pushes and syncs skip the alias while unfazed.json apps[] still declares it (Workspace.deletedApps) — remove it from apps[], or bring it back with syncRepo restoreApps. Refused while a git import of the workspace runs. Owner only. The app is kept by the platform for 30 days, so support (the platform operator) can restore it exactly as it was within that time; then it is erased for good. Secret values are never returned."
|
|
1977
|
+
deleteApp(input: DeleteAppInput!): DeleteAppPayload!
|
|
1978
|
+
"Delete a deployment and its files snapshot, stopping a running service VM first. Alias-keyed app state goes with it once no other deployment uses the alias; the alias's app-scoped env and secrets go with it on that condition plus two more — the alias really was deployed once, and no git source redeploys it — so deleting a failed first build keeps the env staged for the retry. What is deleted is kept by the platform for 30 days, so support (the platform operator) can restore it within that time; then it is erased for good. Secret values are never returned by the API."
|
|
1114
1979
|
deleteDeployment(input: DeleteDeploymentInput!): DeleteResultPayload!
|
|
1115
1980
|
"Roll an alias back to a PRIOR release: atomically repoint it to the given deployment and bring that snapshot back (always_on restarts warm; on_demand cold-starts on the next request). Also reverts to that release's env/secrets snapshot. Pass the id and opaque aliasRevision of the aliasHeld release you observed; the rollback fails if either changed since deploymentReleases."
|
|
1116
1981
|
rollbackDeployment(input: RollbackDeploymentInput!): Deployment!
|
|
1982
|
+
"Delete a workspace: its files, env and secrets, and any persistent box disk; with withDeployments, every app it serves too (confirmAliases). Kept by the platform for 30 days, so support (the platform operator) can restore it exactly as it was within that time; then it is erased for good."
|
|
1117
1983
|
deleteWorkspace(input: DeleteWorkspaceInput!): DeleteResultPayload!
|
|
1118
1984
|
setAppState(input: SetAppStateInput!): AppStateValue!
|
|
1119
1985
|
deleteAppState(input: DeleteAppStateInput!): DeleteResultPayload!
|
|
1120
1986
|
"Rename a linked (claimed) agent. Allowed for the agent's claimer or the operator."
|
|
1121
|
-
|
|
1122
|
-
"Delete a linked (claimed) agent: revoke its token AND delete
|
|
1123
|
-
|
|
1987
|
+
renameLinkedAgent(input: RenameLinkedAgentInput!): CurrentActorAgent!
|
|
1988
|
+
"Delete a linked (claimed) agent: revoke its token AND delete everything it owns — its apps and releases (stopping service VMs), its agents and its integration connections. A binding of those connections on another account's app goes too: that app keeps its running release but gets no env from the integration at its next deploy, and the result names it. Allowed for the agent's claimer or the operator, with their own sign-in (not a run, script or job). The agent itself cannot be restored; what its apps held is kept by the platform for 30 days for investigation, then erased."
|
|
1989
|
+
deleteLinkedAgent(input: DeleteLinkedAgentInput!): DeleteLinkedAgentPayload!
|
|
1124
1990
|
"Issue a fresh access token for a linked (claimed) agent, keeping its identity so it can still redeploy the aliases it owns. Self-registration cannot do this: it always mints a NEW agent, and the platform refuses to let a different owner near an existing alias. Every previous token of the agent stops working immediately, so write the returned value wherever the agent reads it. The token is returned once and is never retrievable again. Allowed for the agent's claimer or the operator."
|
|
1125
|
-
|
|
1991
|
+
rotateLinkedAgentToken(input: RotateLinkedAgentTokenInput!): LinkedAgentTokenPayload!
|
|
1126
1992
|
"Issue a one-time code to connect the caller's Telegram to deploy notifications. Returns a t.me deep link to open the bot with the code prefilled; the code expires and is single-use."
|
|
1127
1993
|
createTelegramLinkCode: TelegramLinkPayload!
|
|
1128
1994
|
}
|
|
@@ -1138,21 +2004,40 @@ type TelegramLinkPayload {
|
|
|
1138
2004
|
botUsername: String!
|
|
1139
2005
|
}
|
|
1140
2006
|
|
|
1141
|
-
input
|
|
2007
|
+
input RenameLinkedAgentInput {
|
|
1142
2008
|
agentID: ID!
|
|
1143
2009
|
name: String!
|
|
1144
2010
|
}
|
|
1145
2011
|
|
|
1146
|
-
input
|
|
2012
|
+
input DeleteLinkedAgentInput {
|
|
1147
2013
|
agentID: ID!
|
|
2014
|
+
"Exactly the aliases of the agent's liveApps, in any order: every app this delete takes offline. A missing or extra alias refuses the delete and changes nothing."
|
|
2015
|
+
confirmAliases: [String!]
|
|
2016
|
+
}
|
|
2017
|
+
|
|
2018
|
+
"What deleting a linked agent changed outside the agent's own things. A delete that stopped part-way answers with ok false and the error beside it, and still names the apps it detached; deleting again finishes and names them again."
|
|
2019
|
+
type DeleteLinkedAgentPayload {
|
|
2020
|
+
ok: Boolean!
|
|
2021
|
+
"Apps of other accounts (yours, a teammate's) that had one of the agent's connections bound. Each keeps its running release but gets no env from that integration at its next deploy; the provider resource is released once no retained release uses it."
|
|
2022
|
+
affectedApps: [LinkedAgentAffectedApp!]!
|
|
2023
|
+
"Affected apps you cannot see, counted but not named."
|
|
2024
|
+
hiddenAffectedApps: Int!
|
|
1148
2025
|
}
|
|
1149
2026
|
|
|
1150
|
-
|
|
2027
|
+
"An app that lost a binding of a deleted agent's connection."
|
|
2028
|
+
type LinkedAgentAffectedApp {
|
|
2029
|
+
workspaceID: ID!
|
|
2030
|
+
alias: String!
|
|
2031
|
+
"The integration kind of the binding it lost."
|
|
2032
|
+
kind: String!
|
|
2033
|
+
}
|
|
2034
|
+
|
|
2035
|
+
input RotateLinkedAgentTokenInput {
|
|
1151
2036
|
agentID: ID!
|
|
1152
2037
|
}
|
|
1153
2038
|
|
|
1154
2039
|
"A newly issued agent credential. Shown once: only its hash is stored."
|
|
1155
|
-
type
|
|
2040
|
+
type LinkedAgentTokenPayload {
|
|
1156
2041
|
"The agent this token authenticates as — unchanged by rotation."
|
|
1157
2042
|
agentID: ID!
|
|
1158
2043
|
"The bearer token. Copy it now; it cannot be read again."
|
|
@@ -1171,10 +2056,16 @@ input RegisterFunctionInput {
|
|
|
1171
2056
|
}
|
|
1172
2057
|
|
|
1173
2058
|
input InvokeFunctionInput {
|
|
2059
|
+
"Optional UUID identifying one invocation across retries. A changed function revision or payload conflicts. Servers unable to guarantee replay safety reject this field before execution."
|
|
2060
|
+
invocationID: ID
|
|
1174
2061
|
functionID: ID!
|
|
1175
2062
|
payload: JSON
|
|
1176
2063
|
}
|
|
1177
2064
|
|
|
2065
|
+
input DeleteFunctionInput {
|
|
2066
|
+
functionID: ID!
|
|
2067
|
+
}
|
|
2068
|
+
|
|
1178
2069
|
input PageInput {
|
|
1179
2070
|
limit: Int
|
|
1180
2071
|
offset: Int
|
|
@@ -1198,12 +2089,16 @@ input WriteWorkspaceTextFileInput {
|
|
|
1198
2089
|
workspaceID: ID!
|
|
1199
2090
|
path: String!
|
|
1200
2091
|
text: String!
|
|
2092
|
+
"On an app with platform git: the message of the commit this write makes; default names the file. Ignored on other apps."
|
|
2093
|
+
commitMessage: String
|
|
1201
2094
|
}
|
|
1202
2095
|
|
|
1203
2096
|
input WriteWorkspaceBase64FileInput {
|
|
1204
2097
|
workspaceID: ID!
|
|
1205
2098
|
path: String!
|
|
1206
2099
|
contentBase64: String!
|
|
2100
|
+
"On an app with platform git: the message of the commit this write makes; default names the file. Ignored on other apps."
|
|
2101
|
+
commitMessage: String
|
|
1207
2102
|
}
|
|
1208
2103
|
|
|
1209
2104
|
input UploadWorkspaceFileInput {
|
|
@@ -1214,6 +2109,30 @@ input UploadWorkspaceFileInput {
|
|
|
1214
2109
|
|
|
1215
2110
|
type WorkspaceFilePayload {
|
|
1216
2111
|
file: WorkspaceFile!
|
|
2112
|
+
"The commit the write made on an app with platform git; null on any other app, and for an upload."
|
|
2113
|
+
commit: FileCommit
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
"The commit a file write made on an app with platform git."
|
|
2117
|
+
type FileCommit {
|
|
2118
|
+
"The commit; with committed false, the branch head that already held exactly these files. Null while it waits."
|
|
2119
|
+
sha: String
|
|
2120
|
+
branch: String!
|
|
2121
|
+
message: String!
|
|
2122
|
+
"False when git already held exactly these files: no commit was made."
|
|
2123
|
+
committed: Boolean!
|
|
2124
|
+
"True while the commit waits for the git server: the app's files have the write, and its commit lands in order. Should a push change the same files meanwhile, a git.conflict event says so."
|
|
2125
|
+
waiting: Boolean!
|
|
2126
|
+
"The app's commits waiting, while this one does."
|
|
2127
|
+
waitingCount: Int!
|
|
2128
|
+
"Whether the branch head, this write included, is imported and deployed like a push."
|
|
2129
|
+
deploys: Boolean!
|
|
2130
|
+
"Paths a push changed too since the write was made: the head keeps the pushed version (sha is the merge). Empty otherwise."
|
|
2131
|
+
conflicts: [String!]!
|
|
2132
|
+
"The write as it was made, the merge's second parent, when there are conflicts."
|
|
2133
|
+
writeSHA: String
|
|
2134
|
+
"True while platform git is paused (its commit queue is being recovered): the app's files have the write, and they are committed as they are once it is back. Nothing to retry."
|
|
2135
|
+
paused: Boolean!
|
|
1217
2136
|
}
|
|
1218
2137
|
|
|
1219
2138
|
input ReadWorkspaceFileInput {
|
|
@@ -1350,15 +2269,17 @@ input CreateDeploymentInput {
|
|
|
1350
2269
|
cronPath: String
|
|
1351
2270
|
"BOX only: optional VM size. Omit for the platform defaults."
|
|
1352
2271
|
boxResources: BoxResourcesInput
|
|
2272
|
+
"Server for a NEW app: a server id or name from placementTargets, or control-plane. Omit for the default server. An existing app keeps its server (use a placement move); static sites stay on the control plane."
|
|
2273
|
+
server: String
|
|
1353
2274
|
}
|
|
1354
2275
|
|
|
1355
2276
|
"A box's requested VM size. Omitted fields use the platform default."
|
|
1356
2277
|
input BoxResourcesInput {
|
|
1357
|
-
"RAM in MiB (default
|
|
2278
|
+
"RAM in MiB (default 4096, min 512, max 16384)."
|
|
1358
2279
|
memMiB: Int
|
|
1359
|
-
"vCPU count (default
|
|
2280
|
+
"vCPU count (default 4, max 16)."
|
|
1360
2281
|
vcpus: Int
|
|
1361
|
-
"Persistent disk in GiB (default
|
|
2282
|
+
"Persistent disk in GiB (default 32, max 128). Sets the size when the disk is first created; a later redeploy asking for more grows the existing disk before the box boots (it never shrinks, and the effective size may be lower than requested)."
|
|
1362
2283
|
diskGiB: Int
|
|
1363
2284
|
}
|
|
1364
2285
|
|
|
@@ -1380,6 +2301,8 @@ input DeployWorkspaceInput {
|
|
|
1380
2301
|
serviceMode: ServiceMode
|
|
1381
2302
|
"STATIC only; overrides the detected SPA fallback."
|
|
1382
2303
|
spaMode: Boolean
|
|
2304
|
+
"Server for a NEW app (see CreateDeploymentInput.server); overrides unfazed.json server."
|
|
2305
|
+
server: String
|
|
1383
2306
|
}
|
|
1384
2307
|
|
|
1385
2308
|
type CreateDeploymentPayload {
|
|
@@ -1387,6 +2310,11 @@ type CreateDeploymentPayload {
|
|
|
1387
2310
|
}
|
|
1388
2311
|
|
|
1389
2312
|
input ImportRepoInput {
|
|
2313
|
+
"Git provider, default github. Forgejo accepts any public HTTPS instance."
|
|
2314
|
+
provider: String
|
|
2315
|
+
serverURL: String
|
|
2316
|
+
"Optional repository token, encrypted per workspace; never returned."
|
|
2317
|
+
token: String
|
|
1390
2318
|
repo: String!
|
|
1391
2319
|
ref: String
|
|
1392
2320
|
alias: String
|
|
@@ -1397,6 +2325,9 @@ input ImportRepoInput {
|
|
|
1397
2325
|
}
|
|
1398
2326
|
|
|
1399
2327
|
input ConnectRepoInput {
|
|
2328
|
+
provider: String
|
|
2329
|
+
serverURL: String
|
|
2330
|
+
token: String
|
|
1400
2331
|
workspaceID: ID!
|
|
1401
2332
|
repo: String!
|
|
1402
2333
|
ref: String
|
|
@@ -1409,6 +2340,8 @@ input ConnectRepoInput {
|
|
|
1409
2340
|
input SyncRepoInput {
|
|
1410
2341
|
workspaceID: ID!
|
|
1411
2342
|
force: Boolean
|
|
2343
|
+
"Apps deleted with deleteApp that unfazed.json apps[] still declares (Workspace.deletedApps): their deletion is lifted and this sync, forced, deploys them again. Owner only."
|
|
2344
|
+
restoreApps: [String!]
|
|
1412
2345
|
}
|
|
1413
2346
|
|
|
1414
2347
|
input UnlinkRepoInput {
|
|
@@ -1425,6 +2358,26 @@ input SetRepoDeployAliasInput {
|
|
|
1425
2358
|
alias: String!
|
|
1426
2359
|
}
|
|
1427
2360
|
|
|
2361
|
+
input AddRepoEnvironmentInput {
|
|
2362
|
+
"The main app's git-linked workspace."
|
|
2363
|
+
workspaceID: ID!
|
|
2364
|
+
"Environment name such as staging: 1-20 lowercase letters, digits or dashes. Every alias of the environment ends with -<name>."
|
|
2365
|
+
name: String!
|
|
2366
|
+
"The branch the environment deploys on every push."
|
|
2367
|
+
branch: String!
|
|
2368
|
+
"Single-app alias; defaults to <main alias>-<name>."
|
|
2369
|
+
alias: String
|
|
2370
|
+
}
|
|
2371
|
+
|
|
2372
|
+
type AddRepoEnvironmentPayload {
|
|
2373
|
+
workspace: Workspace!
|
|
2374
|
+
gitSource: GitSource
|
|
2375
|
+
"The main app's secret names that were not copied; set them on the environment."
|
|
2376
|
+
skippedSecrets: [String!]!
|
|
2377
|
+
"Why the environment's push webhook could not be installed automatically."
|
|
2378
|
+
webhookError: String
|
|
2379
|
+
}
|
|
2380
|
+
|
|
1428
2381
|
input SetGitHubTokenInput {
|
|
1429
2382
|
token: String!
|
|
1430
2383
|
}
|
|
@@ -1446,9 +2399,14 @@ input ListDeploymentsInput {
|
|
|
1446
2399
|
}
|
|
1447
2400
|
|
|
1448
2401
|
input CreateRunInput {
|
|
1449
|
-
|
|
2402
|
+
"The workspace whose env, secrets and files the run gets. Optional for an agent's run: the agent's first scoped workspace, else its own."
|
|
2403
|
+
workspaceID: ID
|
|
2404
|
+
"Make this run a task of an agent: it inherits the agent's harness, provider and model, access and approval wherever this input leaves them empty."
|
|
2405
|
+
agentID: ID
|
|
1450
2406
|
prompt: String
|
|
1451
2407
|
harness: String
|
|
2408
|
+
"A run preset name: its harness applies when harness is empty, its connection/model override the account's harness setting, its extra env merges below the workspace's own."
|
|
2409
|
+
preset: String
|
|
1452
2410
|
command: String
|
|
1453
2411
|
"Shell commands run in /work before the harness; the first failure fails the run."
|
|
1454
2412
|
setup: [String!]
|
|
@@ -1483,6 +2441,7 @@ input FollowUpRunInput {
|
|
|
1483
2441
|
|
|
1484
2442
|
input ListRunsInput {
|
|
1485
2443
|
workspaceID: ID
|
|
2444
|
+
agentID: ID
|
|
1486
2445
|
status: RunStatus
|
|
1487
2446
|
limit: Int
|
|
1488
2447
|
offset: Int
|
|
@@ -1515,8 +2474,32 @@ input RollbackDeploymentInput {
|
|
|
1515
2474
|
|
|
1516
2475
|
input DeleteWorkspaceInput {
|
|
1517
2476
|
workspaceID: ID!
|
|
1518
|
-
"Also delete every deployment snapshotted from the workspace (stopping service VMs) instead of refusing while any exist."
|
|
2477
|
+
"Also delete every deployment snapshotted from the workspace (stopping service VMs) instead of refusing while any exist. This takes down EVERY app the workspace serves, so confirmAliases must name exactly those apps (Workspace.liveApps)."
|
|
1519
2478
|
withDeployments: Boolean
|
|
2479
|
+
"With withDeployments: exactly the aliases of Workspace.liveApps, in any order — every app this delete takes offline. A missing or extra alias refuses the delete and deletes nothing; the error lists the live apps. To delete one app, use deleteApp."
|
|
2480
|
+
confirmAliases: [String!]
|
|
2481
|
+
}
|
|
2482
|
+
|
|
2483
|
+
input DeleteAppInput {
|
|
2484
|
+
workspaceID: ID!
|
|
2485
|
+
"The app to delete: an alias of the workspace."
|
|
2486
|
+
alias: String!
|
|
2487
|
+
}
|
|
2488
|
+
|
|
2489
|
+
"What deleteApp removed."
|
|
2490
|
+
type DeleteAppPayload {
|
|
2491
|
+
ok: Boolean!
|
|
2492
|
+
alias: String!
|
|
2493
|
+
"Deployment records deleted: the live release, retained releases and failed or building attempts."
|
|
2494
|
+
deployments: Int!
|
|
2495
|
+
"Custom domains that served the app and stopped. Their records stay with the alias in this workspace, so a restored app serves them again; removeCustomDomain removes one for good."
|
|
2496
|
+
domains: [String!]!
|
|
2497
|
+
"App-scoped env, secret and REMOVE entries removed."
|
|
2498
|
+
envEntries: Int!
|
|
2499
|
+
"Whether pushes and syncs of this git-linked workspace now skip the alias while unfazed.json apps[] declares it."
|
|
2500
|
+
skippedOnSync: Boolean!
|
|
2501
|
+
"The workspace's apps that are still live, untouched."
|
|
2502
|
+
otherApps: [String!]!
|
|
1520
2503
|
}
|
|
1521
2504
|
|
|
1522
2505
|
input SetAppStateInput {
|
|
@@ -1530,3 +2513,618 @@ input DeleteAppStateInput {
|
|
|
1530
2513
|
alias: String!
|
|
1531
2514
|
key: String!
|
|
1532
2515
|
}
|
|
2516
|
+
|
|
2517
|
+
"Application feedback shared by the on-page toolbar, dashboard and agents."
|
|
2518
|
+
type ReviewAttachment {
|
|
2519
|
+
id: ID!
|
|
2520
|
+
filename: String!
|
|
2521
|
+
mimeType: String!
|
|
2522
|
+
size: Int!
|
|
2523
|
+
}
|
|
2524
|
+
type ReviewMessage {
|
|
2525
|
+
id: ID!
|
|
2526
|
+
author: String!
|
|
2527
|
+
"Current authenticated profile picture, empty for guests and accounts without one."
|
|
2528
|
+
avatarURL: String!
|
|
2529
|
+
guest: Boolean!
|
|
2530
|
+
body: String!
|
|
2531
|
+
deleted: Boolean!
|
|
2532
|
+
"Whether the current viewer may delete this message."
|
|
2533
|
+
canDelete: Boolean!
|
|
2534
|
+
createdAt: String!
|
|
2535
|
+
attachments: [ReviewAttachment!]!
|
|
2536
|
+
}
|
|
2537
|
+
type ReviewThread {
|
|
2538
|
+
id: ID!
|
|
2539
|
+
"Permanent discussion number within this app generation, including resolved discussions."
|
|
2540
|
+
number: Int!
|
|
2541
|
+
workspaceID: ID!
|
|
2542
|
+
alias: String!
|
|
2543
|
+
deploymentID: ID!
|
|
2544
|
+
page: String!
|
|
2545
|
+
title: String!
|
|
2546
|
+
selector: String!
|
|
2547
|
+
selectedText: String!
|
|
2548
|
+
x: Float!
|
|
2549
|
+
y: Float!
|
|
2550
|
+
viewportWidth: Int!
|
|
2551
|
+
viewportHeight: Int!
|
|
2552
|
+
userAgent: String!
|
|
2553
|
+
resolved: Boolean!
|
|
2554
|
+
createdAt: String!
|
|
2555
|
+
messages: [ReviewMessage!]!
|
|
2556
|
+
}
|
|
2557
|
+
type ReviewPage { threads: [ReviewThread!]! total: Int! canManage: Boolean! }
|
|
2558
|
+
type ReviewLink { id: ID! url: String createdAt: String! expiresAt: String! revoked: Boolean! }
|
|
2559
|
+
type ReviewFile { filename: String! mimeType: String! contentBase64: String! }
|
|
2560
|
+
type ReviewNotificationConnection { id: ID! name: String! }
|
|
2561
|
+
type ReviewNotificationChannel {
|
|
2562
|
+
kind: String!
|
|
2563
|
+
label: String!
|
|
2564
|
+
iconURL: String!
|
|
2565
|
+
connectMethod: String!
|
|
2566
|
+
connections: [ReviewNotificationConnection!]!
|
|
2567
|
+
}
|
|
2568
|
+
type ReviewNotificationSettings {
|
|
2569
|
+
enabled: Boolean!
|
|
2570
|
+
appEnabled: Boolean!
|
|
2571
|
+
connected: Boolean!
|
|
2572
|
+
connectionID: String!
|
|
2573
|
+
channels: [ReviewNotificationChannel!]!
|
|
2574
|
+
}
|
|
2575
|
+
input ReviewAttachmentInput { filename: String! contentBase64: String! }
|
|
2576
|
+
input ReviewCommentInput {
|
|
2577
|
+
deploymentID: ID!
|
|
2578
|
+
threadID: ID
|
|
2579
|
+
body: String!
|
|
2580
|
+
page: String
|
|
2581
|
+
title: String
|
|
2582
|
+
selector: String
|
|
2583
|
+
selectedText: String
|
|
2584
|
+
x: Float
|
|
2585
|
+
y: Float
|
|
2586
|
+
viewportWidth: Int
|
|
2587
|
+
viewportHeight: Int
|
|
2588
|
+
userAgent: String
|
|
2589
|
+
requestID: ID
|
|
2590
|
+
attachments: [ReviewAttachmentInput!]
|
|
2591
|
+
}
|
|
2592
|
+
extend type Query {
|
|
2593
|
+
"Personal feedback notification settings. Omit deploymentID for the account-wide switch."
|
|
2594
|
+
reviewNotificationSettings(deploymentID: ID): ReviewNotificationSettings!
|
|
2595
|
+
reviewThreads(deploymentID: ID!, offset: Int, limit: Int): ReviewPage!
|
|
2596
|
+
reviewThread(deploymentID: ID!, threadID: ID!): ReviewThread!
|
|
2597
|
+
reviewLinks(deploymentID: ID!): [ReviewLink!]!
|
|
2598
|
+
reviewAttachment(deploymentID: ID!, threadID: ID!, attachmentID: ID!): ReviewFile!
|
|
2599
|
+
}
|
|
2600
|
+
extend type Mutation {
|
|
2601
|
+
"Set the account-wide feedback switch, or one app override when deploymentID is present. Defaults are on; delivery is at most once an hour per account."
|
|
2602
|
+
setReviewNotificationSettings(deploymentID: ID, connectionID: ID, enabled: Boolean!): ReviewNotificationSettings!
|
|
2603
|
+
"Create a revocable 30-day guest link, or a one-hour personal toolbar session."
|
|
2604
|
+
createReviewLink(deploymentID: ID!, personal: Boolean = false): ReviewLink!
|
|
2605
|
+
revokeReviewLink(deploymentID: ID!, linkID: ID!): Boolean!
|
|
2606
|
+
addReviewComment(input: ReviewCommentInput!): ReviewThread!
|
|
2607
|
+
"Delete one comment and its attachments. Authors may delete their own; the app owner may moderate all comments."
|
|
2608
|
+
deleteReviewComment(deploymentID: ID!, threadID: ID!, messageID: ID!): Boolean!
|
|
2609
|
+
resolveReviewThread(deploymentID: ID!, threadID: ID!, resolved: Boolean!): ReviewThread!
|
|
2610
|
+
}
|
|
2611
|
+
|
|
2612
|
+
"A commit of an app's platform git repository."
|
|
2613
|
+
type AppCommit {
|
|
2614
|
+
sha: String!
|
|
2615
|
+
"The commit message (its first 64 KiB)."
|
|
2616
|
+
message: String!
|
|
2617
|
+
authorName: String!
|
|
2618
|
+
authorEmail: String!
|
|
2619
|
+
"When the change was authored (RFC3339)."
|
|
2620
|
+
authoredAt: String!
|
|
2621
|
+
"Paths changed against the first parent (every path of a first commit)."
|
|
2622
|
+
filesChanged: Int!
|
|
2623
|
+
"Aliases whose live release runs this commit."
|
|
2624
|
+
deployedTo: [String!]!
|
|
2625
|
+
}
|
|
2626
|
+
|
|
2627
|
+
type AppCommitPage {
|
|
2628
|
+
branch: String!
|
|
2629
|
+
"The branch head; null while the branch has no commits."
|
|
2630
|
+
head: String
|
|
2631
|
+
commits: [AppCommit!]!
|
|
2632
|
+
"Pass as before for the older commits; null on the last page."
|
|
2633
|
+
nextBefore: String
|
|
2634
|
+
"Whether pushes (and restores) deploy the app."
|
|
2635
|
+
autoDeploy: Boolean!
|
|
2636
|
+
"File writes whose commits have not landed yet: the app's files have them, and they land in order as soon as the git server takes them."
|
|
2637
|
+
waitingCommits: Int!
|
|
2638
|
+
"When the oldest waiting write was made (RFC3339); null when none waits."
|
|
2639
|
+
waitingSince: String
|
|
2640
|
+
"The commit every live alias of the app runs, whether or not it is on this page."
|
|
2641
|
+
deployed: [AppDeployedCommit!]!
|
|
2642
|
+
}
|
|
2643
|
+
|
|
2644
|
+
"The commit one live alias runs (AppCommitPage.deployed)."
|
|
2645
|
+
type AppDeployedCommit {
|
|
2646
|
+
alias: String!
|
|
2647
|
+
sha: String!
|
|
2648
|
+
"The release serving the alias."
|
|
2649
|
+
deploymentID: ID!
|
|
2650
|
+
}
|
|
2651
|
+
|
|
2652
|
+
type AppCommitFile {
|
|
2653
|
+
path: String!
|
|
2654
|
+
"added, modified, deleted or type changed."
|
|
2655
|
+
status: String!
|
|
2656
|
+
}
|
|
2657
|
+
|
|
2658
|
+
type AppCommitDiff {
|
|
2659
|
+
commit: AppCommit!
|
|
2660
|
+
files: [AppCommitFile!]!
|
|
2661
|
+
"Unified diff against the first parent, at most 64 KiB (16 KiB per file); lines starting with … say what was left out."
|
|
2662
|
+
patch: String!
|
|
2663
|
+
truncated: Boolean!
|
|
2664
|
+
additions: Int!
|
|
2665
|
+
deletions: Int!
|
|
2666
|
+
}
|
|
2667
|
+
|
|
2668
|
+
input RestoreAppVersionInput {
|
|
2669
|
+
workspaceID: ID!
|
|
2670
|
+
"Full 40-character sha of the commit whose files the app gets back."
|
|
2671
|
+
sha: String!
|
|
2672
|
+
"When set, refuse (changing nothing) unless the branch head is still this commit."
|
|
2673
|
+
expectedHead: String
|
|
2674
|
+
"Message of the new commit; default Restore <short sha> (<its message>)."
|
|
2675
|
+
message: String
|
|
2676
|
+
}
|
|
2677
|
+
|
|
2678
|
+
input MoveAppToGitHubInput {
|
|
2679
|
+
workspaceID: ID!
|
|
2680
|
+
"GitHub account or organization to create the repository in; default the caller's own GitHub account."
|
|
2681
|
+
owner: String
|
|
2682
|
+
"Name of the new repository; default the app's alias."
|
|
2683
|
+
repo: String
|
|
2684
|
+
"When set, refuse (changing nothing) unless the branch head is still this commit."
|
|
2685
|
+
expectedHead: String
|
|
2686
|
+
}
|
|
2687
|
+
|
|
2688
|
+
input EnablePlatformGitInput {
|
|
2689
|
+
workspaceID: ID!
|
|
2690
|
+
}
|
|
2691
|
+
|
|
2692
|
+
type EnablePlatformGitPayload {
|
|
2693
|
+
"The app's source, now deploying from its platform repository."
|
|
2694
|
+
workspace: Workspace!
|
|
2695
|
+
"The repository by alias (https://git.unfz.to/<alias>.git)."
|
|
2696
|
+
cloneURL: String!
|
|
2697
|
+
"The repository by workspace ID, which never changes."
|
|
2698
|
+
stableCloneURL: String!
|
|
2699
|
+
branch: String!
|
|
2700
|
+
"The commit holding the app's files; null for an app without files, whose first push fills it."
|
|
2701
|
+
commitSHA: String
|
|
2702
|
+
"False when the repository already held exactly these files."
|
|
2703
|
+
committed: Boolean!
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2706
|
+
type MoveAppToGitHubPayload {
|
|
2707
|
+
"owner/name of the GitHub repository."
|
|
2708
|
+
repository: String!
|
|
2709
|
+
repoURL: String!
|
|
2710
|
+
"False when an earlier attempt of this move created the repository, or the caller named an empty one."
|
|
2711
|
+
created: Boolean!
|
|
2712
|
+
"The app had moved before: nothing was done."
|
|
2713
|
+
alreadyMoved: Boolean!
|
|
2714
|
+
"The branch head the app deploys, on GitHub too."
|
|
2715
|
+
head: String!
|
|
2716
|
+
"Whether every push to the branch on GitHub deploys the app."
|
|
2717
|
+
webhookInstalled: Boolean!
|
|
2718
|
+
"The platform repository, kept read-only."
|
|
2719
|
+
platformCloneURL: String!
|
|
2720
|
+
"What else happened, such as a push that landed during the move."
|
|
2721
|
+
note: String
|
|
2722
|
+
}
|
|
2723
|
+
|
|
2724
|
+
type RestoreAppVersionPayload {
|
|
2725
|
+
"The new commit; with committed false, the head that already holds that version."
|
|
2726
|
+
sha: String!
|
|
2727
|
+
committed: Boolean!
|
|
2728
|
+
"Whether the new commit is deployed like a push. The deploy is an import queued behind the restore: its deployment is the one whose gitCommit is sha (deploymentsPage with the workspace, then waitForDeployment)."
|
|
2729
|
+
deploys: Boolean!
|
|
2730
|
+
message: String!
|
|
2731
|
+
"The app's branch."
|
|
2732
|
+
branch: String!
|
|
2733
|
+
"The alias a push deploys to, when the link names one; null otherwise (unfazed.json apps[] deploys each of its aliases)."
|
|
2734
|
+
deployAlias: String
|
|
2735
|
+
"The commit restored from (the sha asked for)."
|
|
2736
|
+
restoredFrom: String!
|
|
2737
|
+
"The branch head the new commit was made on; null with committed false."
|
|
2738
|
+
parent: String
|
|
2739
|
+
}
|
|
2740
|
+
|
|
2741
|
+
enum WorkflowRunStatus { PENDING RUNNING COMPLETED FAILED CANCELLED }
|
|
2742
|
+
|
|
2743
|
+
type WorkflowValue { text: String! bytes: Int! truncated: Boolean! error: Boolean! }
|
|
2744
|
+
type WorkflowError { message: String! stack: String code: String truncated: Boolean! }
|
|
2745
|
+
type WorkflowAttribute { key: String! value: String! }
|
|
2746
|
+
|
|
2747
|
+
type WorkflowRunSummary {
|
|
2748
|
+
runID: ID! workflowName: String! displayName: String! module: String!
|
|
2749
|
+
status: WorkflowRunStatus! deploymentID: String!
|
|
2750
|
+
createdAt: String! startedAt: String completedAt: String updatedAt: String! expiredAt: String
|
|
2751
|
+
errorCode: String attributes: [WorkflowAttribute!]!
|
|
2752
|
+
}
|
|
2753
|
+
type WorkflowRunPage { runs: [WorkflowRunSummary!]! nextCursor: String hasMore: Boolean! }
|
|
2754
|
+
|
|
2755
|
+
type WorkflowStep {
|
|
2756
|
+
stepID: ID! stepName: String! displayName: String! module: String!
|
|
2757
|
+
status: String! attempt: Int!
|
|
2758
|
+
createdAt: String! startedAt: String completedAt: String updatedAt: String! retryAfter: String
|
|
2759
|
+
}
|
|
2760
|
+
type WorkflowStepPage { steps: [WorkflowStep!]! nextCursor: String hasMore: Boolean! }
|
|
2761
|
+
type WorkflowWait { correlationID: ID! status: String! createdAt: String! resumeAt: String completedAt: String }
|
|
2762
|
+
type WorkflowHook {
|
|
2763
|
+
hookID: ID! kind: String! status: String! createdAt: String!
|
|
2764
|
+
receivedCount: Int! lastReceivedAt: String disposedAt: String
|
|
2765
|
+
}
|
|
2766
|
+
type WorkflowStreamInfo { name: String! tailIndex: Int done: Boolean }
|
|
2767
|
+
type WorkflowEvent {
|
|
2768
|
+
eventID: ID! eventType: String! correlationID: String createdAt: String!
|
|
2769
|
+
info: JSON! infoTruncated: Boolean!
|
|
2770
|
+
}
|
|
2771
|
+
type WorkflowEventPage { events: [WorkflowEvent!]! nextCursor: String hasMore: Boolean! }
|
|
2772
|
+
|
|
2773
|
+
type WorkflowRun {
|
|
2774
|
+
run: WorkflowRunSummary!
|
|
2775
|
+
input: WorkflowValue output: WorkflowValue error: WorkflowError
|
|
2776
|
+
steps: [WorkflowStep!]! stepsNextCursor: String stepsHasMore: Boolean!
|
|
2777
|
+
waits: [WorkflowWait!]! hooks: [WorkflowHook!]! streams: [WorkflowStreamInfo!]!
|
|
2778
|
+
eventsScanned: Int! eventsComplete: Boolean!
|
|
2779
|
+
waitsTruncated: Boolean! hooksTruncated: Boolean!
|
|
2780
|
+
}
|
|
2781
|
+
type WorkflowStepDetail {
|
|
2782
|
+
step: WorkflowStep! input: WorkflowValue output: WorkflowValue error: WorkflowError
|
|
2783
|
+
events: [WorkflowEvent!]! eventsHasMore: Boolean!
|
|
2784
|
+
}
|
|
2785
|
+
type WorkflowEventDetail { event: WorkflowEvent! data: WorkflowValue }
|
|
2786
|
+
type WorkflowStreamChunk { index: Int! bytes: Int! encoding: String! text: String! truncated: Boolean! }
|
|
2787
|
+
type WorkflowStreamPage {
|
|
2788
|
+
name: String! chunks: [WorkflowStreamChunk!]! nextCursor: String hasMore: Boolean!
|
|
2789
|
+
done: Boolean! tailIndex: Int!
|
|
2790
|
+
}
|
|
2791
|
+
type WorkflowInfo { version: Int! package: String! workflow: String! specVersion: Int workflows: [WorkflowName!]! }
|
|
2792
|
+
type WorkflowName { name: String! displayName: String! module: String! }
|
|
2793
|
+
|
|
2794
|
+
"The app's queue counters, read from its data node (docs/workflow-world.md, Counters)."
|
|
2795
|
+
type WorkflowQueueCounters {
|
|
2796
|
+
"Messages waiting for delivery, due now or later: due plus the delayed ones (ready - due). Delayed messages include wake-ups left by sleeps that were woken early; each is delivered at its time and dropped."
|
|
2797
|
+
ready: Int!
|
|
2798
|
+
"Ready messages whose due time has passed, waiting for a delivery slot."
|
|
2799
|
+
due: Int!
|
|
2800
|
+
"Messages being delivered to the app now."
|
|
2801
|
+
leased: Int!
|
|
2802
|
+
"Messages given up after 24 h of failed deliveries."
|
|
2803
|
+
dead: Int!
|
|
2804
|
+
"The earliest due time of a due message; null when none is due (delayed messages do not count)."
|
|
2805
|
+
oldestDueAt: String
|
|
2806
|
+
"Bytes stored and charged: live messages, idempotency keys and dead messages."
|
|
2807
|
+
bytes: Int!
|
|
2808
|
+
"Dead messages dropped over the dead-letter cap, oldest first."
|
|
2809
|
+
deadEvicted: Int!
|
|
2810
|
+
}
|
|
2811
|
+
type WorkflowDeadMessage {
|
|
2812
|
+
messageID: ID! queueName: String! contentType: String! createdAt: String! deadAt: String!
|
|
2813
|
+
attempt: Int! deliveryCount: Int! size: Int! payloadPreview: String
|
|
2814
|
+
}
|
|
2815
|
+
type WorkflowQueue { counters: WorkflowQueueCounters! dead: [WorkflowDeadMessage!]! deadNextCursor: String deadUnavailable: Boolean! }
|
|
2816
|
+
|
|
2817
|
+
extend type Query {
|
|
2818
|
+
workflowInfo(alias: String!): WorkflowInfo!
|
|
2819
|
+
workflowRuns(alias: String!, status: [WorkflowRunStatus!], workflowName: String, limit: Int, cursor: String): WorkflowRunPage!
|
|
2820
|
+
workflowRun(alias: String!, runID: ID!): WorkflowRun!
|
|
2821
|
+
workflowSteps(alias: String!, runID: ID!, limit: Int, cursor: String): WorkflowStepPage!
|
|
2822
|
+
workflowStep(alias: String!, runID: ID!, stepID: ID!): WorkflowStepDetail!
|
|
2823
|
+
workflowEvents(alias: String!, runID: ID!, correlationID: String, newestFirst: Boolean, limit: Int, cursor: String): WorkflowEventPage!
|
|
2824
|
+
workflowEvent(alias: String!, runID: ID!, eventID: ID!): WorkflowEventDetail!
|
|
2825
|
+
workflowStream(alias: String!, runID: ID!, name: String!, limit: Int, cursor: String): WorkflowStreamPage!
|
|
2826
|
+
workflowQueue(alias: String!, deadLimit: Int, deadCursor: String): WorkflowQueue!
|
|
2827
|
+
}
|
|
2828
|
+
|
|
2829
|
+
input WakeWorkflowRunInput { alias: String! runID: ID! correlationIDs: [ID!] }
|
|
2830
|
+
input CancelWorkflowRunInput { alias: String! runID: ID! reason: String }
|
|
2831
|
+
input ReplayDeadWorkflowMessagesInput { alias: String! messageIDs: [ID!] all: Boolean }
|
|
2832
|
+
type WakeWorkflowRunPayload { stoppedCount: Int! }
|
|
2833
|
+
type CancelWorkflowRunPayload { runID: ID! status: WorkflowRunStatus! }
|
|
2834
|
+
type ReplayDeadWorkflowMessagesPayload { replayed: Int! skipped: Int! remainingDead: Int! }
|
|
2835
|
+
|
|
2836
|
+
extend type Mutation {
|
|
2837
|
+
wakeWorkflowRun(input: WakeWorkflowRunInput!): WakeWorkflowRunPayload!
|
|
2838
|
+
cancelWorkflowRun(input: CancelWorkflowRunInput!): CancelWorkflowRunPayload!
|
|
2839
|
+
replayDeadWorkflowMessages(input: ReplayDeadWorkflowMessagesInput!): ReplayDeadWorkflowMessagesPayload!
|
|
2840
|
+
}
|
|
2841
|
+
|
|
2842
|
+
"One piece a deletion holds: a release, the workspace's files and env, an app's env, its App State, a box disk, an integration resource."
|
|
2843
|
+
type DeletedPiece {
|
|
2844
|
+
id: ID!
|
|
2845
|
+
kind: String!
|
|
2846
|
+
"Where it is held: control-plane, app-state:<namespace>, box-disk:<workspace>, provider:<kind>."
|
|
2847
|
+
host: String!
|
|
2848
|
+
location: String!
|
|
2849
|
+
bytes: Float!
|
|
2850
|
+
"Why it is no longer held (expired, erasure, budget, restored); null while it is."
|
|
2851
|
+
closed: String
|
|
2852
|
+
closedAt: String
|
|
2853
|
+
}
|
|
2854
|
+
|
|
2855
|
+
"One deletion the platform holds (docs/soft-delete.md): what was deleted, whose, when and by whom, and until when it can be restored. Platform operator only."
|
|
2856
|
+
type DeletedItem {
|
|
2857
|
+
deletionID: ID!
|
|
2858
|
+
"app, workspace, release, run_agent or linked_agent."
|
|
2859
|
+
subjectKind: String!
|
|
2860
|
+
subjectID: String!
|
|
2861
|
+
what: String!
|
|
2862
|
+
workspaceID: ID
|
|
2863
|
+
workspaceName: String
|
|
2864
|
+
aliases: [String!]!
|
|
2865
|
+
"Custom domains a restore serves again."
|
|
2866
|
+
domains: [String!]!
|
|
2867
|
+
ownerID: String
|
|
2868
|
+
deletedAt: String!
|
|
2869
|
+
deletedBy: String
|
|
2870
|
+
"The surface the delete came through: mcp, graphql, form, api, system."
|
|
2871
|
+
via: String!
|
|
2872
|
+
"delete_app, delete_workspace, delete_deployment, git_retired, delete_agent, delete_linked_agent."
|
|
2873
|
+
path: String!
|
|
2874
|
+
"When everything it holds is erased for good."
|
|
2875
|
+
purgeAfter: String!
|
|
2876
|
+
"held, restoring, restored or purged."
|
|
2877
|
+
state: String!
|
|
2878
|
+
restoredAt: String
|
|
2879
|
+
restoredBy: String
|
|
2880
|
+
"Bytes it holds on the control plane."
|
|
2881
|
+
bytes: Float!
|
|
2882
|
+
pieces: [DeletedPiece!]!
|
|
2883
|
+
"Whether restoreDeleted can bring it back now; refusal says why not."
|
|
2884
|
+
restorable: Boolean!
|
|
2885
|
+
refusal: String
|
|
2886
|
+
"Other open deletions of the same subject (a delete finished by deleting again later) that restoring this one brings back with it."
|
|
2887
|
+
restoresWith: [ID!]!
|
|
2888
|
+
"Other open deletions of the same app (a release deleted on its own, or the app deleted after one of its releases); each is restored on its own."
|
|
2889
|
+
related: [ID!]!
|
|
2890
|
+
}
|
|
2891
|
+
|
|
2892
|
+
"What restoreDeleted brought back."
|
|
2893
|
+
type DeletedRestorePayload {
|
|
2894
|
+
deletionID: ID!
|
|
2895
|
+
"restored, or already_restored for one restored before (its apps were started again)."
|
|
2896
|
+
status: String!
|
|
2897
|
+
workspaceID: ID
|
|
2898
|
+
releases: Int!
|
|
2899
|
+
apps: [String!]!
|
|
2900
|
+
domains: [String!]!
|
|
2901
|
+
bindings: [String!]!
|
|
2902
|
+
"App env entries set again since the delete, which kept their current values."
|
|
2903
|
+
envKept: [String!]!
|
|
2904
|
+
"Where each restored app serves, or why it did not start yet."
|
|
2905
|
+
placement: [String!]!
|
|
2906
|
+
"Other deletions of the same subject restored with it."
|
|
2907
|
+
with: [ID!]!
|
|
2908
|
+
}
|
|
2909
|
+
|
|
2910
|
+
"What purgeDeleted erased."
|
|
2911
|
+
type DeletedPurgePayload {
|
|
2912
|
+
deletionID: ID!
|
|
2913
|
+
purged: Int!
|
|
2914
|
+
bytes: Float!
|
|
2915
|
+
}
|
|
2916
|
+
|
|
2917
|
+
extend type Query {
|
|
2918
|
+
"The deleted apps, workspaces and releases the platform holds, newest first, a page at a time, with what a restore would bring back and until when. Platform operator only; anyone else is refused."
|
|
2919
|
+
deletedItems(
|
|
2920
|
+
"Only deletions in this state: held, restoring, restored or purged."
|
|
2921
|
+
state: String
|
|
2922
|
+
"Matching deletions to skip, for the next page."
|
|
2923
|
+
offset: Int
|
|
2924
|
+
"At most this many, newest first (default 50, at most 500)."
|
|
2925
|
+
limit: Int
|
|
2926
|
+
): [DeletedItem!]!
|
|
2927
|
+
}
|
|
2928
|
+
|
|
2929
|
+
extend type Mutation {
|
|
2930
|
+
"Restore one deletion with everything it held, under the same ids: the workspace, releases with their env and secrets, integration bindings, and the alias on its old epoch, so App State, the box disk and custom domains reattach and the app serves again as before. Refused, changing nothing, while its alias is held by another app (named), once anything of it was purged, or when a piece is missing. Safe to retry. Platform operator only."
|
|
2931
|
+
restoreDeleted(deletionID: ID!): DeletedRestorePayload!
|
|
2932
|
+
"Erase one deletion now instead of after its retention, overriding an investigation hold: files, records, App State, the box disk, integration resources at their providers, custom domains. It can never be restored afterwards. reason is kept with the erasure. Platform operator only."
|
|
2933
|
+
purgeDeleted(deletionID: ID!, reason: String!): DeletedPurgePayload!
|
|
2934
|
+
}
|
|
2935
|
+
|
|
2936
|
+
"One file of writeWorkspaceFiles, as MCP write_workspace_files takes it."
|
|
2937
|
+
input WorkspaceFileWriteInput {
|
|
2938
|
+
"Relative path, such as server.ts or assets/logo.png."
|
|
2939
|
+
path: String!
|
|
2940
|
+
"The file: UTF-8 text, or base64-encoded bytes with encoding base64."
|
|
2941
|
+
content: String!
|
|
2942
|
+
"text (the default) or base64."
|
|
2943
|
+
encoding: String
|
|
2944
|
+
}
|
|
2945
|
+
|
|
2946
|
+
input WriteWorkspaceFilesInput {
|
|
2947
|
+
workspaceID: ID!
|
|
2948
|
+
"Written in the given order; a repeated path keeps its last content. At most 100 files, 16 MiB each and 32 MiB in all (decoded) per call: more fails the whole call before anything is written."
|
|
2949
|
+
files: [WorkspaceFileWriteInput!]!
|
|
2950
|
+
"On an app with platform git: the message of the call's ONE commit; default names the files. Ignored on other apps."
|
|
2951
|
+
commitMessage: String
|
|
2952
|
+
}
|
|
2953
|
+
|
|
2954
|
+
"One file's outcome in writeWorkspaceFiles, in the order given."
|
|
2955
|
+
type WorkspaceFileWriteResult {
|
|
2956
|
+
path: String!
|
|
2957
|
+
ok: Boolean!
|
|
2958
|
+
"The written file; null when this path failed."
|
|
2959
|
+
file: WorkspaceFile
|
|
2960
|
+
"Why this path failed; null when it was written."
|
|
2961
|
+
error: String
|
|
2962
|
+
}
|
|
2963
|
+
|
|
2964
|
+
"What writeWorkspaceFiles wrote: every file's outcome, and the one commit it made."
|
|
2965
|
+
type WriteWorkspaceFilesPayload {
|
|
2966
|
+
workspaceID: ID!
|
|
2967
|
+
files: [WorkspaceFileWriteResult!]!
|
|
2968
|
+
written: Int!
|
|
2969
|
+
failed: Int!
|
|
2970
|
+
"Bytes written, decoded."
|
|
2971
|
+
totalBytes: Int!
|
|
2972
|
+
"The ONE commit the whole call made on an app with platform git (before any file was written); null on any other app."
|
|
2973
|
+
commit: FileCommit
|
|
2974
|
+
}
|
|
2975
|
+
|
|
2976
|
+
"What waitForDeployment read when it stopped waiting (MCP wait_for_deployment)."
|
|
2977
|
+
type DeploymentWaitPayload {
|
|
2978
|
+
"The deployment as the wait left it."
|
|
2979
|
+
deployment: Deployment!
|
|
2980
|
+
"True when the budget, or a server restart, ended the wait first: deployment is the current, unfinished state. Not an error: call again to keep waiting."
|
|
2981
|
+
timedOut: Boolean!
|
|
2982
|
+
"How long the server waited, in milliseconds."
|
|
2983
|
+
waitedMs: Int!
|
|
2984
|
+
"Where a new app was meant to land and how far its landing got, as MCP wait_for_deployment reports it; null when no placement was recorded."
|
|
2985
|
+
placement: JSON
|
|
2986
|
+
}
|
|
2987
|
+
|
|
2988
|
+
"One error group of a service app (MCP list_errors). Its title, type, culprit and level are what the running app reported: untrusted text."
|
|
2989
|
+
type AppErrorGroup {
|
|
2990
|
+
id: ID!
|
|
2991
|
+
title: String!
|
|
2992
|
+
type: String
|
|
2993
|
+
culprit: String
|
|
2994
|
+
level: String!
|
|
2995
|
+
"open, resolved or muted."
|
|
2996
|
+
status: String!
|
|
2997
|
+
"Every occurrence, stored or sampled out."
|
|
2998
|
+
count: Int!
|
|
2999
|
+
"Occurrences kept whole (the first and the newest 50; fewer past the rate limit)."
|
|
3000
|
+
storedEvents: Int!
|
|
3001
|
+
firstSeen: String!
|
|
3002
|
+
lastSeen: String!
|
|
3003
|
+
firstDeploymentID: String
|
|
3004
|
+
firstGitCommit: String
|
|
3005
|
+
lastDeploymentID: String
|
|
3006
|
+
lastGitCommit: String
|
|
3007
|
+
"It stays resolved while this deployment reports it; another deployment regresses it."
|
|
3008
|
+
resolvedInDeploymentID: String
|
|
3009
|
+
resolvedAt: String
|
|
3010
|
+
mutedAt: String
|
|
3011
|
+
regressedAt: String
|
|
3012
|
+
}
|
|
3013
|
+
|
|
3014
|
+
type AppErrorGroupPage {
|
|
3015
|
+
groups: [AppErrorGroup!]!
|
|
3016
|
+
"Pass as cursor for the next page; null on the last."
|
|
3017
|
+
nextCursor: String
|
|
3018
|
+
"Why the list may be empty for another reason than no errors (an older server, an app that opted out); null otherwise."
|
|
3019
|
+
note: String
|
|
3020
|
+
}
|
|
3021
|
+
|
|
3022
|
+
"One stored occurrence of an error group."
|
|
3023
|
+
type AppErrorEventRef {
|
|
3024
|
+
eventID: String!
|
|
3025
|
+
at: String!
|
|
3026
|
+
deploymentID: String
|
|
3027
|
+
level: String!
|
|
3028
|
+
}
|
|
3029
|
+
|
|
3030
|
+
"One deployment an error group was seen in."
|
|
3031
|
+
type AppErrorDeployment {
|
|
3032
|
+
deploymentID: String!
|
|
3033
|
+
gitCommit: String
|
|
3034
|
+
"The app's current release."
|
|
3035
|
+
current: Boolean!
|
|
3036
|
+
count: Int!
|
|
3037
|
+
firstSeen: String!
|
|
3038
|
+
lastSeen: String!
|
|
3039
|
+
}
|
|
3040
|
+
|
|
3041
|
+
"One error group with its latest occurrence (MCP get_error_group). Everything the app reported is untrusted text."
|
|
3042
|
+
type AppErrorGroupDetail {
|
|
3043
|
+
group: AppErrorGroup!
|
|
3044
|
+
"The newest stored occurrence, whole, as a Sentry event."
|
|
3045
|
+
latestEvent: JSON
|
|
3046
|
+
firstEvent: AppErrorEventRef
|
|
3047
|
+
recentEvents: [AppErrorEventRef!]!
|
|
3048
|
+
"The deployments it was seen in, most recent first."
|
|
3049
|
+
deployments: [AppErrorDeployment!]!
|
|
3050
|
+
"The platform saw the latest occurrence end its VM's process: the crash is in serviceStatus."
|
|
3051
|
+
fatal: Boolean!
|
|
3052
|
+
"The VM whose console carried the latest occurrence; null for what an SDK reported."
|
|
3053
|
+
vmID: String
|
|
3054
|
+
}
|
|
3055
|
+
|
|
3056
|
+
input AppErrorGroupInput {
|
|
3057
|
+
workspaceID: ID!
|
|
3058
|
+
alias: String!
|
|
3059
|
+
"The group's id (AppErrorGroup.id, or group_id of an error.new or error.regressed event)."
|
|
3060
|
+
groupID: ID!
|
|
3061
|
+
}
|
|
3062
|
+
|
|
3063
|
+
"An event type pollEvents and waitForEvents read (MCP list_event_types)."
|
|
3064
|
+
type PlatformEventType {
|
|
3065
|
+
name: String!
|
|
3066
|
+
description: String!
|
|
3067
|
+
delivery: [String!]!
|
|
3068
|
+
"Its filters, as a JSON Schema: pass them in arguments under the type's name."
|
|
3069
|
+
inputSchema: JSON!
|
|
3070
|
+
"Its payload (data), as a JSON Schema."
|
|
3071
|
+
payloadSchema: JSON!
|
|
3072
|
+
}
|
|
3073
|
+
|
|
3074
|
+
"Which events to read (MCP poll_events)."
|
|
3075
|
+
input PlatformEventsInput {
|
|
3076
|
+
"Event types; omit for every type you may receive."
|
|
3077
|
+
names: [String!]
|
|
3078
|
+
"Filters per type, keyed by its name, e.g. {\"deployment.finished\": {\"alias\": \"shop\", \"status\": \"FAILED\"}}."
|
|
3079
|
+
arguments: JSON
|
|
3080
|
+
"Where to continue; omit to start from now (nothing is replayed)."
|
|
3081
|
+
cursor: String
|
|
3082
|
+
"At most this many events."
|
|
3083
|
+
max: Int
|
|
3084
|
+
}
|
|
3085
|
+
|
|
3086
|
+
"One event (deployment.finished, service.crashed, error.new, git.conflict, …). Its data is minimal: ids, statuses, excerpts."
|
|
3087
|
+
type PlatformEvent {
|
|
3088
|
+
eventID: ID!
|
|
3089
|
+
name: String!
|
|
3090
|
+
timestamp: String!
|
|
3091
|
+
data: JSON!
|
|
3092
|
+
}
|
|
3093
|
+
|
|
3094
|
+
type PlatformEventPage {
|
|
3095
|
+
events: [PlatformEvent!]!
|
|
3096
|
+
"Pass back as cursor: at once while hasMore, otherwise after nextPollMs (or to waitForEvents)."
|
|
3097
|
+
cursor: String!
|
|
3098
|
+
"Events may be missing (a cursor older than the history, or a control-plane crash): re-read state."
|
|
3099
|
+
truncated: Boolean!
|
|
3100
|
+
hasMore: Boolean!
|
|
3101
|
+
nextPollMs: Int!
|
|
3102
|
+
"waitForEvents only: the budget ended the wait with no event. Call again with cursor."
|
|
3103
|
+
timedOut: Boolean!
|
|
3104
|
+
}
|
|
3105
|
+
|
|
3106
|
+
extend type Query {
|
|
3107
|
+
"Block until a deployment leaves BUILDING (and a new app's direct landing ends) or timeoutSeconds pass (default 45, at most 50), then return it — the server-side wait of MCP wait_for_deployment, woken by the deploy pipeline itself, so a client never polls. A timeout is not an error: timedOut is true and the deployment is the current state; call again to keep waiting."
|
|
3108
|
+
waitForDeployment(id: ID!, timeoutSeconds: Int): DeploymentWaitPayload!
|
|
3109
|
+
"A service app's error groups, most recently seen first (MCP list_errors). status: open, resolved or muted (default all); limit 1 to 100 (default 20); cursor is the previous page's nextCursor."
|
|
3110
|
+
appErrors(workspaceID: ID!, alias: String!, status: String, limit: Int, cursor: String): AppErrorGroupPage!
|
|
3111
|
+
"One error group of a service app with its latest occurrence, recent occurrences and the deployments it was seen in (MCP get_error_group)."
|
|
3112
|
+
appErrorGroup(workspaceID: ID!, alias: String!, groupID: ID!): AppErrorGroupDetail!
|
|
3113
|
+
"The event types pollEvents and waitForEvents read, with each type's filters and payload (MCP list_event_types)."
|
|
3114
|
+
platformEventTypes: [PlatformEventType!]!
|
|
3115
|
+
"What happened to the apps, runs and custom domains you can see since cursor (MCP poll_events; the cursors are the same). Omit cursor to start from now."
|
|
3116
|
+
pollEvents(input: PlatformEventsInput): PlatformEventPage!
|
|
3117
|
+
"pollEvents that blocks server-side until an event arrives or timeoutSeconds pass (default 45, at most 50; MCP wait_for_events). A timeout is not an error: timedOut is true, with a cursor to call again with."
|
|
3118
|
+
waitForEvents(input: PlatformEventsInput, timeoutSeconds: Int): PlatformEventPage!
|
|
3119
|
+
}
|
|
3120
|
+
|
|
3121
|
+
extend type Mutation {
|
|
3122
|
+
"Create or replace MANY files in ONE call (MCP write_workspace_files): each file text or base64. On an app with platform git the whole call is ONE commit on its branch (commit), made before any file is written: if it fails, the call fails and nothing is written. Otherwise not transactional: files are written in order, each atomically, and a file's failure (files[].error) does not undo the others. Requires deploy scope."
|
|
3123
|
+
writeWorkspaceFiles(input: WriteWorkspaceFilesInput!): WriteWorkspaceFilesPayload!
|
|
3124
|
+
"Mark an error group resolved in the app's current deployment, once its fix is deployed (MCP resolve_error_group). Requires deploy scope."
|
|
3125
|
+
resolveAppErrorGroup(input: AppErrorGroupInput!): AppErrorGroup!
|
|
3126
|
+
"Mute an expected error group: still counted, never regresses or sends events (MCP mute_error_group). Requires deploy scope."
|
|
3127
|
+
muteAppErrorGroup(input: AppErrorGroupInput!): AppErrorGroup!
|
|
3128
|
+
"Open a resolved or muted error group again (MCP reopen_error_group). Requires deploy scope."
|
|
3129
|
+
reopenAppErrorGroup(input: AppErrorGroupInput!): AppErrorGroup!
|
|
3130
|
+
}
|