@appforge-ci/core 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/agent-readiness.d.ts +163 -0
- package/dist/agent-readiness.d.ts.map +1 -0
- package/dist/agent-readiness.js +179 -0
- package/dist/agent-readiness.js.map +1 -0
- package/dist/agent-readiness.test.d.ts +2 -0
- package/dist/agent-readiness.test.d.ts.map +1 -0
- package/dist/agent-readiness.test.js +177 -0
- package/dist/agent-readiness.test.js.map +1 -0
- package/dist/api-client.d.ts +529 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +551 -0
- package/dist/api-client.js.map +1 -0
- package/dist/api-client.test.d.ts +2 -0
- package/dist/api-client.test.d.ts.map +1 -0
- package/dist/api-client.test.js +305 -0
- package/dist/api-client.test.js.map +1 -0
- package/dist/build-cost.test.d.ts +2 -0
- package/dist/build-cost.test.d.ts.map +1 -0
- package/dist/build-cost.test.js +21 -0
- package/dist/build-cost.test.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/ota-artifact.d.ts +41 -0
- package/dist/ota-artifact.d.ts.map +1 -0
- package/dist/ota-artifact.js +43 -0
- package/dist/ota-artifact.js.map +1 -0
- package/dist/ota-artifact.test.d.ts +2 -0
- package/dist/ota-artifact.test.d.ts.map +1 -0
- package/dist/ota-artifact.test.js +44 -0
- package/dist/ota-artifact.test.js.map +1 -0
- package/dist/ota-bundle-hash.d.ts +38 -0
- package/dist/ota-bundle-hash.d.ts.map +1 -0
- package/dist/ota-bundle-hash.js +40 -0
- package/dist/ota-bundle-hash.js.map +1 -0
- package/dist/ota-bundle-hash.test.d.ts +2 -0
- package/dist/ota-bundle-hash.test.d.ts.map +1 -0
- package/dist/ota-bundle-hash.test.js +28 -0
- package/dist/ota-bundle-hash.test.js.map +1 -0
- package/dist/ota-rollout.d.ts +38 -0
- package/dist/ota-rollout.d.ts.map +1 -0
- package/dist/ota-rollout.js +53 -0
- package/dist/ota-rollout.js.map +1 -0
- package/dist/ota-rollout.test.d.ts +2 -0
- package/dist/ota-rollout.test.d.ts.map +1 -0
- package/dist/ota-rollout.test.js +48 -0
- package/dist/ota-rollout.test.js.map +1 -0
- package/dist/schemas.d.ts +776 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +538 -0
- package/dist/schemas.js.map +1 -0
- package/dist/token-packs.test.d.ts +2 -0
- package/dist/token-packs.test.d.ts.map +1 -0
- package/dist/token-packs.test.js +34 -0
- package/dist/token-packs.test.js.map +1 -0
- package/dist/types.d.ts +445 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +80 -0
- package/dist/types.js.map +1 -0
- package/package.json +35 -0
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
import type { AgentCommand, AgentInfo, ApiTokenInfo, App, BillingMode, BillingUsage, Build, BuildFailureExplanation, LedgerEntry, MonthlyInvoice, Org, OtaChannel, OtaManifest, OtaRelease, SmokeTestVerdict, TokenPack, User, VncSession } from "./types.js";
|
|
2
|
+
export interface ApiClientOptions {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
/** Bearer token — either a user session JWT or a CLI/agent API token. */
|
|
5
|
+
token?: string;
|
|
6
|
+
/**
|
|
7
|
+
* Fleet management (listAgents/createEnrollmentToken/sendAgentCommand)
|
|
8
|
+
* is served by a separately-deployed admin Worker, not the customer-
|
|
9
|
+
* facing API — see apps/admin-api. Falls back to `baseUrl` if unset,
|
|
10
|
+
* which only matters for callers that never touch those three methods.
|
|
11
|
+
*/
|
|
12
|
+
adminApiUrl?: string;
|
|
13
|
+
/** Test seam only — same "optional, defaults to the real thing" shape
|
|
14
|
+
* `packages/admin-cli`'s `waitForCommandResolution`/`packages/cli`'s
|
|
15
|
+
* `followBuildLogs` already use for their own injectable dependencies.
|
|
16
|
+
* Every real caller (dashboard, CLI, agent) omits this and gets the
|
|
17
|
+
* real global `fetch`. */
|
|
18
|
+
fetchImpl?: typeof fetch;
|
|
19
|
+
/** Test seam only — production callers always get the real
|
|
20
|
+
* `DEFAULT_REQUEST_TIMEOUT_MS`. See that constant's own docblock. */
|
|
21
|
+
requestTimeoutMs?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Every `ApiClient` call is a small JSON request/response — no file
|
|
25
|
+
* upload/download is ever routed through this client (build artifacts and
|
|
26
|
+
* OTA bundles go straight to/from R2 via a presigned URL the caller fetches
|
|
27
|
+
* separately) — but a handful of routes (`explainBuildFailure`,
|
|
28
|
+
* `analyzeSmokeTest`, `askDocsChat`, `generateAppforgeConfig`) proxy to
|
|
29
|
+
* Anthropic server-side and can legitimately take tens of seconds for a
|
|
30
|
+
* real completion, well past what a plain CRUD call needs. 60s is
|
|
31
|
+
* generous enough to cover the slowest of those with room to spare, while
|
|
32
|
+
* still being a real ceiling: without one, a connection that stalls after
|
|
33
|
+
* opening (a network partition, a proxy holding the connection open
|
|
34
|
+
* without sending further bytes, a hung Worker instance) left every
|
|
35
|
+
* caller's `fetch` promise pending forever — same shape as `packages/
|
|
36
|
+
* agent/src/lib/api.ts`'s already-fixed `AgentApi.request`, but for the
|
|
37
|
+
* single shared client every dashboard page, CLI command, and admin-cli
|
|
38
|
+
* command talks to the control plane through. */
|
|
39
|
+
export declare const DEFAULT_REQUEST_TIMEOUT_MS = 60000;
|
|
40
|
+
export declare class ApiError extends Error {
|
|
41
|
+
status: number;
|
|
42
|
+
body: unknown;
|
|
43
|
+
constructor(status: number, body: unknown);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Shared "what should the user see" extraction for a caught error from
|
|
47
|
+
* any `ApiClient` call. `ApiError` extends `Error`, so a naive
|
|
48
|
+
* `err instanceof Error ? err.message : fallback` always matches an
|
|
49
|
+
* `ApiError` too and returns *this class's own* constructor string —
|
|
50
|
+
* `API error ${status}: ${JSON.stringify(body)}`, meant for logs/
|
|
51
|
+
* debugging — instead of the server's actual user-facing text at
|
|
52
|
+
* `body.error`. This was independently found and fixed the same way in
|
|
53
|
+
* `Login.tsx`/`Signup.tsx`/`Device.tsx`/`VerifyEmail.tsx` (dashboard)
|
|
54
|
+
* and `VncViewer.tsx`'s own `vncViewerErrorMessage` before this shared
|
|
55
|
+
* helper existed; new callers (both CLIs' top-level handlers first, per
|
|
56
|
+
* ROADMAP.md) should use this instead of repeating the same extraction
|
|
57
|
+
* inline.
|
|
58
|
+
*/
|
|
59
|
+
export declare function apiErrorMessage(err: unknown, fallback: string): string;
|
|
60
|
+
/**
|
|
61
|
+
* Small typed fetch wrapper shared by the CLI and the dashboard so both
|
|
62
|
+
* talk to the control-plane API through the same request/response shapes.
|
|
63
|
+
*/
|
|
64
|
+
export declare class ApiClient {
|
|
65
|
+
private opts;
|
|
66
|
+
constructor(opts: ApiClientOptions);
|
|
67
|
+
private request;
|
|
68
|
+
private adminRequest;
|
|
69
|
+
/**
|
|
70
|
+
* `twoFactor` is only needed on a second call, after a first call
|
|
71
|
+
* without it throws `ApiError(401, { requiresTotp: true })` — see
|
|
72
|
+
* apps/api/src/routes/auth.ts's login handler. `recoveryCode` is a
|
|
73
|
+
* lost-authenticator alternate to `totpCode`, never both at once.
|
|
74
|
+
*/
|
|
75
|
+
login(email: string, password: string, twoFactor?: {
|
|
76
|
+
totpCode?: string;
|
|
77
|
+
recoveryCode?: string;
|
|
78
|
+
}): Promise<{
|
|
79
|
+
token: string;
|
|
80
|
+
user: User;
|
|
81
|
+
}>;
|
|
82
|
+
signup(email: string, password: string, name: string | undefined, orgName: string): Promise<{
|
|
83
|
+
token: string;
|
|
84
|
+
user: User;
|
|
85
|
+
org: Org;
|
|
86
|
+
}>;
|
|
87
|
+
me(): Promise<{
|
|
88
|
+
user: User;
|
|
89
|
+
orgs: Org[];
|
|
90
|
+
}>;
|
|
91
|
+
/**
|
|
92
|
+
* Redeems the token from the signup verification email's link
|
|
93
|
+
* (`apps/api/src/lib/email-verification.ts`'s `verifyUrl`). No auth of
|
|
94
|
+
* its own — the route this hits (`POST /auth/verify-email`) doesn't
|
|
95
|
+
* require a session, since whoever clicked the link may not be logged
|
|
96
|
+
* in on this browser at all. Was previously unreachable from any
|
|
97
|
+
* client: this method, plus a dashboard route to call it, is the fix.
|
|
98
|
+
*/
|
|
99
|
+
verifyEmail(token: string): Promise<{
|
|
100
|
+
ok: true;
|
|
101
|
+
}>;
|
|
102
|
+
/** Requires an existing session — unlike `verifyEmail`, this is only
|
|
103
|
+
* ever offered to an already-logged-in user who hasn't verified yet
|
|
104
|
+
* (see `Security.tsx`). Rate-limited server-side. */
|
|
105
|
+
resendVerification(): Promise<{
|
|
106
|
+
ok: true;
|
|
107
|
+
}>;
|
|
108
|
+
/** Requires re-entering the current password — same reasoning as
|
|
109
|
+
* `disableTwoFactor` below: a stolen session token alone must not be
|
|
110
|
+
* enough to take over the account's own fallback credential.
|
|
111
|
+
* Rate-limited server-side, keyed by user. Also revokes every other
|
|
112
|
+
* live session for the account (a leaked token stops working
|
|
113
|
+
* immediately) — `token` is a freshly-issued replacement for *this*
|
|
114
|
+
* session specifically, so the caller must swap it in (e.g. into
|
|
115
|
+
* `session.token`) or this same request's own session gets logged
|
|
116
|
+
* out by its own success. */
|
|
117
|
+
changePassword(currentPassword: string, newPassword: string): Promise<{
|
|
118
|
+
ok: true;
|
|
119
|
+
token: string;
|
|
120
|
+
}>;
|
|
121
|
+
/** No auth of its own — this is the entry point for someone who can't
|
|
122
|
+
* log in at all. Always resolves the same way regardless of whether
|
|
123
|
+
* the email is actually registered (see the route's own doc
|
|
124
|
+
* comment) — never use the response to decide whether to tell the
|
|
125
|
+
* caller "no account with that email". */
|
|
126
|
+
forgotPassword(email: string): Promise<{
|
|
127
|
+
ok: true;
|
|
128
|
+
}>;
|
|
129
|
+
/** Redeems the token from the forgot-password email's link
|
|
130
|
+
* (`apps/api/src/lib/password-reset.ts`'s `resetUrl`). No auth of its
|
|
131
|
+
* own, same reasoning as `verifyEmail` above. Also revokes every
|
|
132
|
+
* other live session for the account and returns a fresh one, same
|
|
133
|
+
* as `changePassword`/`disableTwoFactor` — a reset is at least as
|
|
134
|
+
* strong proof of ownership as re-entering the current password. */
|
|
135
|
+
resetPassword(token: string, newPassword: string): Promise<{
|
|
136
|
+
ok: true;
|
|
137
|
+
token: string;
|
|
138
|
+
}>;
|
|
139
|
+
/** Starts (or restarts) enrollment — the secret is only ever returned
|
|
140
|
+
* here and from confirmTwoFactor's success, never again afterward. */
|
|
141
|
+
enrollTwoFactor(): Promise<{
|
|
142
|
+
secret: string;
|
|
143
|
+
otpauthUri: string;
|
|
144
|
+
}>;
|
|
145
|
+
/** Redeems the first code from an authenticator app to actually turn
|
|
146
|
+
* 2FA on — `recoveryCodes` is shown exactly once, same as the secret
|
|
147
|
+
* above; the caller is responsible for surfacing it to the user now.
|
|
148
|
+
* Also requires re-entering the account password, same reasoning and
|
|
149
|
+
* requirement as `disableTwoFactor` below: without it, any live
|
|
150
|
+
* session (a stolen JWT, or a CLI/webhook API token, which never
|
|
151
|
+
* expires on its own) was enough to confirm 2FA with an
|
|
152
|
+
* attacker-chosen secret, permanently locking the real account owner
|
|
153
|
+
* out at their next login — see docs/security.md's "2FA (TOTP)" note. */
|
|
154
|
+
confirmTwoFactor(code: string, password: string): Promise<{
|
|
155
|
+
ok: true;
|
|
156
|
+
recoveryCodes: string[];
|
|
157
|
+
}>;
|
|
158
|
+
/** Requires re-entering the account password — see docs/security.md's
|
|
159
|
+
* "2FA (TOTP)" note on why a session token alone isn't enough here.
|
|
160
|
+
* Also revokes every other live session for the account, same
|
|
161
|
+
* reasoning and `token`-swap requirement as `changePassword` above —
|
|
162
|
+
* the JWT this very request authenticated with might be the leaked
|
|
163
|
+
* one 2FA existed to guard against. */
|
|
164
|
+
disableTwoFactor(password: string): Promise<{
|
|
165
|
+
ok: true;
|
|
166
|
+
token: string;
|
|
167
|
+
}>;
|
|
168
|
+
/** Invalidates every existing recovery code and returns a fresh set,
|
|
169
|
+
* shown exactly once like the original set from confirmTwoFactor.
|
|
170
|
+
* Also requires re-entering the account password, same reasoning as
|
|
171
|
+
* `disableTwoFactor` above: without it, a stolen session token alone
|
|
172
|
+
* was enough to silently destroy the real owner's recovery path
|
|
173
|
+
* (this codebase has no account-recovery flow) and hand the
|
|
174
|
+
* attacker a fresh set of recovery codes instead — see
|
|
175
|
+
* docs/security.md's "2FA (TOTP)" note. */
|
|
176
|
+
regenerateRecoveryCodes(password: string): Promise<{
|
|
177
|
+
ok: true;
|
|
178
|
+
recoveryCodes: string[];
|
|
179
|
+
}>;
|
|
180
|
+
/** `appforge-admin login --web`'s device-authorization flow (#5) — the CLI calls this first, no auth of its own yet. */
|
|
181
|
+
startDeviceAuth(): Promise<{
|
|
182
|
+
deviceCode: string;
|
|
183
|
+
userCode: string;
|
|
184
|
+
verificationUrl: string;
|
|
185
|
+
expiresInSeconds: number;
|
|
186
|
+
intervalSeconds: number;
|
|
187
|
+
}>;
|
|
188
|
+
/** Poll with the long deviceCode until status stops being "pending" — same shape as gh/OAuth device flow polling. */
|
|
189
|
+
pollDeviceAuth(deviceCode: string): Promise<{
|
|
190
|
+
status: "pending" | "denied" | "expired";
|
|
191
|
+
} | {
|
|
192
|
+
status: "approved";
|
|
193
|
+
token: string;
|
|
194
|
+
orgId: string;
|
|
195
|
+
orgName: string;
|
|
196
|
+
}>;
|
|
197
|
+
/** Called from the dashboard (already has a user session) with the short, human-typed userCode. */
|
|
198
|
+
approveDeviceAuth(userCode: string): Promise<{
|
|
199
|
+
ok: true;
|
|
200
|
+
orgName: string;
|
|
201
|
+
}>;
|
|
202
|
+
denyDeviceAuth(userCode: string): Promise<{
|
|
203
|
+
ok: true;
|
|
204
|
+
}>;
|
|
205
|
+
/** Drafts an appforge.yaml from real project files — see #8. `files` is path -> file contents for whatever the caller found on disk. */
|
|
206
|
+
generateAppforgeConfig(input: {
|
|
207
|
+
detectedPlatform: "ios" | "android" | "flutter" | "react-native" | null;
|
|
208
|
+
files: Record<string, string>;
|
|
209
|
+
}): Promise<{
|
|
210
|
+
yaml: string;
|
|
211
|
+
}>;
|
|
212
|
+
/** Public, unauthenticated docs Q&A widget (pricing page) — see #10. Resend the whole conversation each call; nothing is kept server-side. */
|
|
213
|
+
askDocsChat(history: {
|
|
214
|
+
role: "user" | "assistant";
|
|
215
|
+
content: string;
|
|
216
|
+
}[]): Promise<{
|
|
217
|
+
answer: string;
|
|
218
|
+
}>;
|
|
219
|
+
createApiToken(orgId: string, label: string): Promise<{
|
|
220
|
+
token: string;
|
|
221
|
+
}>;
|
|
222
|
+
/** Never includes the token value itself or its hash — see
|
|
223
|
+
* `ApiTokenInfo`'s own docblock. */
|
|
224
|
+
listApiTokens(orgId: string, pagination?: {
|
|
225
|
+
limit?: number;
|
|
226
|
+
offset?: number;
|
|
227
|
+
}): Promise<{
|
|
228
|
+
tokens: ApiTokenInfo[];
|
|
229
|
+
}>;
|
|
230
|
+
/** Immediate and permanent — there's no undo once a token is
|
|
231
|
+
* revoked (a fresh one via `createApiToken` is the only way back). */
|
|
232
|
+
revokeApiToken(orgId: string, tokenId: string): Promise<{
|
|
233
|
+
revoked: true;
|
|
234
|
+
tokenId: string;
|
|
235
|
+
}>;
|
|
236
|
+
/** Fixes a typo'd or since-changed org name (e.g. a placeholder used
|
|
237
|
+
* at signup) without any of `updateApp`'s deletion/recreation
|
|
238
|
+
* downsides — there's nothing else to break, since unlike an app's
|
|
239
|
+
* `webhookSecret`, an org's identity has no dependent secret tied to
|
|
240
|
+
* it. `name` is the only updatable field; see `updateOrgSchema`'s own
|
|
241
|
+
* docblock in `packages/core/src/schemas.ts`. */
|
|
242
|
+
updateOrg(orgId: string, input: {
|
|
243
|
+
name?: string;
|
|
244
|
+
buildWebhookUrl?: string | null;
|
|
245
|
+
}): Promise<{
|
|
246
|
+
org: Org;
|
|
247
|
+
}>;
|
|
248
|
+
listApps(orgId: string, pagination?: {
|
|
249
|
+
limit?: number;
|
|
250
|
+
offset?: number;
|
|
251
|
+
}): Promise<{
|
|
252
|
+
apps: App[];
|
|
253
|
+
}>;
|
|
254
|
+
createApp(orgId: string, input: {
|
|
255
|
+
name: string;
|
|
256
|
+
platform: string;
|
|
257
|
+
repoUrl: string;
|
|
258
|
+
defaultBranch: string;
|
|
259
|
+
}): Promise<{
|
|
260
|
+
app: App;
|
|
261
|
+
}>;
|
|
262
|
+
/** A single app's own name/platform/etc. — `listApps` only ever returns a
|
|
263
|
+
* whole org's apps, so a page that already knows just the `appId` (any
|
|
264
|
+
* `/apps/:appId/*` page) needs this rather than fetching every app in
|
|
265
|
+
* the org just to find the one it's showing. */
|
|
266
|
+
getApp(appId: string): Promise<{
|
|
267
|
+
app: App;
|
|
268
|
+
}>;
|
|
269
|
+
/** The one route that actually returns `webhookSecret` — every other
|
|
270
|
+
* app response (`getApp`/`listApps`/`createApp`/`updateApp`)
|
|
271
|
+
* deliberately omits it. This is the value GitHub's webhook settings
|
|
272
|
+
* "Secret" field needs, per `docs/security.md`'s "GitHub webhooks"
|
|
273
|
+
* note; without it there's no way to ever configure a working
|
|
274
|
+
* webhook at all. */
|
|
275
|
+
getAppWebhookSecret(appId: string): Promise<{
|
|
276
|
+
webhookSecret: string;
|
|
277
|
+
}>;
|
|
278
|
+
/** `platform` isn't updatable — see `updateAppSchema`'s own docblock
|
|
279
|
+
* in `packages/core/src/schemas.ts`. */
|
|
280
|
+
updateApp(appId: string, input: {
|
|
281
|
+
name?: string;
|
|
282
|
+
repoUrl?: string;
|
|
283
|
+
defaultBranch?: string;
|
|
284
|
+
}): Promise<{
|
|
285
|
+
app: App;
|
|
286
|
+
}>;
|
|
287
|
+
/** Permanently removes the app and cascades every `Build`/OTA row for
|
|
288
|
+
* it — 409s (a plain `ApiError`) if a build is still queued/leased/
|
|
289
|
+
* running, so an in-flight build never has its `App` row vanish out
|
|
290
|
+
* from under it. */
|
|
291
|
+
deleteApp(appId: string): Promise<{
|
|
292
|
+
deleted: true;
|
|
293
|
+
appId: string;
|
|
294
|
+
}>;
|
|
295
|
+
/** Build-secrets v1 (ROADMAP.md, split off from #322) — sets or
|
|
296
|
+
* overwrites a named secret for this app, injected as an env var
|
|
297
|
+
* under that name on every build. Never returns the value back;
|
|
298
|
+
* see `getAppSecretNames` for why. */
|
|
299
|
+
setAppSecret(appId: string, input: {
|
|
300
|
+
name: string;
|
|
301
|
+
value: string;
|
|
302
|
+
}): Promise<{
|
|
303
|
+
name: string;
|
|
304
|
+
}>;
|
|
305
|
+
/** Names only — this codebase has no route anywhere that returns a
|
|
306
|
+
* secret's decrypted value once it's been set (same discipline
|
|
307
|
+
* `getAppWebhookSecret` deliberately doesn't extend to). */
|
|
308
|
+
getAppSecretNames(appId: string): Promise<{
|
|
309
|
+
names: string[];
|
|
310
|
+
}>;
|
|
311
|
+
deleteAppSecret(appId: string, name: string): Promise<{
|
|
312
|
+
deleted: true;
|
|
313
|
+
name: string;
|
|
314
|
+
}>;
|
|
315
|
+
/** Fleet-secrets v1 (issue #392) — sets or overwrites one of the
|
|
316
|
+
* org's fleet-wide infra secrets (`JWT_SECRET`,
|
|
317
|
+
* `JWT_SECRET_PREVIOUS`, `INTERNAL_SERVICE_TOKEN`; see
|
|
318
|
+
* `FLEET_SECRET_NAMES`). Every Mac mini enrolled in this org picks
|
|
319
|
+
* the new value up on its next heartbeat and re-applies it locally,
|
|
320
|
+
* so this call *is* the rotation — there's no per-machine follow-up
|
|
321
|
+
* step. Never returns the value back, same as `setAppSecret`. */
|
|
322
|
+
setFleetSecret(orgId: string, input: {
|
|
323
|
+
name: string;
|
|
324
|
+
value: string;
|
|
325
|
+
}): Promise<{
|
|
326
|
+
name: string;
|
|
327
|
+
}>;
|
|
328
|
+
/** Names only — as with `getAppSecretNames`, no route anywhere returns
|
|
329
|
+
* a fleet secret's decrypted value to a human-facing client; the only
|
|
330
|
+
* decrypt-and-return path in this codebase is apps/admin-api's
|
|
331
|
+
* `GET /agents/fleet-secrets`, which requires an agent bearer token. */
|
|
332
|
+
getFleetSecretNames(orgId: string): Promise<{
|
|
333
|
+
names: string[];
|
|
334
|
+
}>;
|
|
335
|
+
deleteFleetSecret(orgId: string, name: string): Promise<{
|
|
336
|
+
deleted: true;
|
|
337
|
+
name: string;
|
|
338
|
+
}>;
|
|
339
|
+
listBuilds(appId: string): Promise<{
|
|
340
|
+
builds: Build[];
|
|
341
|
+
}>;
|
|
342
|
+
/** Best-effort suggestions for the trigger-build form's "Workflow"
|
|
343
|
+
* field — see `apps/api/src/lib/appforge-yaml.ts`'s own docblock for
|
|
344
|
+
* why this can legitimately come back empty (private repo, no
|
|
345
|
+
* appforge.yaml on this branch yet, etc.) rather than erroring. */
|
|
346
|
+
listAppWorkflows(appId: string): Promise<{
|
|
347
|
+
workflows: string[];
|
|
348
|
+
}>;
|
|
349
|
+
getBuild(buildId: string): Promise<{
|
|
350
|
+
build: Build;
|
|
351
|
+
}>;
|
|
352
|
+
triggerBuild(input: {
|
|
353
|
+
appId: string;
|
|
354
|
+
workflow: string;
|
|
355
|
+
branch?: string;
|
|
356
|
+
}): Promise<{
|
|
357
|
+
build: Build;
|
|
358
|
+
}>;
|
|
359
|
+
cancelBuild(buildId: string): Promise<{
|
|
360
|
+
build: Build;
|
|
361
|
+
}>;
|
|
362
|
+
listAgents(orgId: string): Promise<{
|
|
363
|
+
agents: AgentInfo[];
|
|
364
|
+
}>;
|
|
365
|
+
createEnrollmentToken(orgId: string): Promise<{
|
|
366
|
+
enrollmentToken: string;
|
|
367
|
+
expiresAt: string;
|
|
368
|
+
}>;
|
|
369
|
+
/** Permanently remove a Mac mini from the fleet. The daemon on the
|
|
370
|
+
* machine itself must be stopped separately — see apps/admin-api's
|
|
371
|
+
* DELETE handler and `appforge-admin agents decommission`. */
|
|
372
|
+
deleteAgent(orgId: string, agentId: string): Promise<{
|
|
373
|
+
deleted: true;
|
|
374
|
+
agentId: string;
|
|
375
|
+
}>;
|
|
376
|
+
/** `scriptName` is only used by RUN_MAINTENANCE_SCRIPT; `targetVersion`
|
|
377
|
+
* only by UPDATE_AGENT (npm version or, for a repo-checkout install, a
|
|
378
|
+
* git ref); `buildId` only by CANCEL_BUILD (which of this agent's
|
|
379
|
+
* possibly-several concurrent builds to kill) — all three are ignored
|
|
380
|
+
* server-side for every other command type. `buildId` was the one
|
|
381
|
+
* missing piece keeping CANCEL_BUILD entirely unreachable from any
|
|
382
|
+
* client despite the rest of the stack (route, schema, DB column,
|
|
383
|
+
* agent handling) already being fully built — see ROADMAP.md. */
|
|
384
|
+
sendAgentCommand(agentId: string, type: string, scriptName?: string, targetVersion?: string, buildId?: string): Promise<{
|
|
385
|
+
command: {
|
|
386
|
+
id: string;
|
|
387
|
+
};
|
|
388
|
+
}>;
|
|
389
|
+
/** Remote-management history for one agent, newest first — how the
|
|
390
|
+
* Fleet page shows whether a DRAIN/REBOOT/... actually landed
|
|
391
|
+
* (`done`/`failed` + the agent's `result` string) instead of leaving
|
|
392
|
+
* the operator guessing after a click. */
|
|
393
|
+
listAgentCommands(agentId: string, limit?: number): Promise<{
|
|
394
|
+
commands: AgentCommand[];
|
|
395
|
+
}>;
|
|
396
|
+
/** VNC "Connect" button, Phase 1c: mints a 5-minute session token plus
|
|
397
|
+
* the `wsUrl` (`apps/device-stream`'s `/vnc` relay, see that Worker's
|
|
398
|
+
* Phase 1b) the dashboard's viewer page dials it against. Called fresh
|
|
399
|
+
* each time the viewer page mounts, same "no pre-fetched token sitting
|
|
400
|
+
* in a URL or router state" shape as `startDeviceTestSession`.
|
|
401
|
+
*
|
|
402
|
+
* `options.requestControl` (Feature 3) asks the server for a session
|
|
403
|
+
* that can also forward mouse/keyboard input, not just watch — sent
|
|
404
|
+
* as `{ mode: "control" }` only when true, so an omitted/false call
|
|
405
|
+
* sends no body at all, unchanged from before this option existed.
|
|
406
|
+
* This is only ever a *request*: the response's own `mode` field
|
|
407
|
+
* ("view" | "control") is what the server actually granted (`403` if
|
|
408
|
+
* control was requested but `Agent.remoteControlEnabled` isn't set —
|
|
409
|
+
* see `apps/admin-api/src/routes/fleet.ts`), and callers must treat
|
|
410
|
+
* that field, never their own request, as authoritative. */
|
|
411
|
+
startVncSession(orgId: string, agentId: string, options?: {
|
|
412
|
+
requestControl?: boolean;
|
|
413
|
+
}): Promise<{
|
|
414
|
+
agentId: string;
|
|
415
|
+
token: string;
|
|
416
|
+
expiresAt: string;
|
|
417
|
+
wsUrl: string;
|
|
418
|
+
mode: "view" | "control";
|
|
419
|
+
}>;
|
|
420
|
+
/** Grants or revokes `Agent.remoteControlEnabled` (Feature 3) — the
|
|
421
|
+
* one and only way that flag changes, mirroring `deleteAgent` above's
|
|
422
|
+
* "dedicated route with its own DB write" shape rather than the
|
|
423
|
+
* AgentCommand queue, since this is a persisted authorization bit
|
|
424
|
+
* `startVncSession` needs to read synchronously, not a directive for
|
|
425
|
+
* the agent daemon to act on. See `appforge-admin agents
|
|
426
|
+
* allow-remote-control` (`packages/admin-cli`) for the CLI surface
|
|
427
|
+
* this same route backs. */
|
|
428
|
+
setAgentRemoteControl(orgId: string, agentId: string, enabled: boolean): Promise<{
|
|
429
|
+
agentId: string;
|
|
430
|
+
remoteControlEnabled: number;
|
|
431
|
+
}>;
|
|
432
|
+
/** The audit trail's read side — who's requested a VNC "Connect"
|
|
433
|
+
* session for this agent and when, newest first. How a "Last VNC
|
|
434
|
+
* session" column reads this (`apps/dashboard/src/pages/Fleet.tsx`),
|
|
435
|
+
* same shape `listAgentCommands` above already established. */
|
|
436
|
+
listVncSessions(orgId: string, agentId: string): Promise<{
|
|
437
|
+
sessions: VncSession[];
|
|
438
|
+
}>;
|
|
439
|
+
getBalance(orgId: string): Promise<{
|
|
440
|
+
tokenBalance: number;
|
|
441
|
+
buildCostTokens: number;
|
|
442
|
+
}>;
|
|
443
|
+
listTokenPacks(): Promise<{
|
|
444
|
+
packs: TokenPack[];
|
|
445
|
+
}>;
|
|
446
|
+
/** Starts an LHV Paytech checkout session for a token top-up — also opportunistically saves a card for MIT monthly billing. */
|
|
447
|
+
createLhvCheckoutSession(orgId: string, packId: string): Promise<{
|
|
448
|
+
url: string;
|
|
449
|
+
}>;
|
|
450
|
+
isLhvConfigured(): Promise<{
|
|
451
|
+
configured: boolean;
|
|
452
|
+
}>;
|
|
453
|
+
listLedger(orgId: string): Promise<{
|
|
454
|
+
entries: LedgerEntry[];
|
|
455
|
+
}>;
|
|
456
|
+
getBillingUsage(orgId: string): Promise<BillingUsage>;
|
|
457
|
+
setBillingMode(orgId: string, mode: BillingMode): Promise<{
|
|
458
|
+
org: Org;
|
|
459
|
+
}>;
|
|
460
|
+
listMonthlyInvoices(orgId: string): Promise<{
|
|
461
|
+
invoices: MonthlyInvoice[];
|
|
462
|
+
}>;
|
|
463
|
+
/** AI triage of a failed build's log — see docs/ai-failure-triage.md.
|
|
464
|
+
* Throws ApiError(501) if ANTHROPIC_API_KEY isn't configured on this
|
|
465
|
+
* deployment; callers should show that as "not available here", not
|
|
466
|
+
* as a generic error. */
|
|
467
|
+
explainBuildFailure(buildId: string): Promise<{
|
|
468
|
+
explanation: BuildFailureExplanation;
|
|
469
|
+
}>;
|
|
470
|
+
/** On-demand re-analysis of every smoke-test screenshot a build produced
|
|
471
|
+
* (#9), one verdict per screenshot in index order — same
|
|
472
|
+
* 501-if-unconfigured contract as explainBuildFailure above. */
|
|
473
|
+
analyzeSmokeTest(buildId: string): Promise<{
|
|
474
|
+
verdicts: SmokeTestVerdict[];
|
|
475
|
+
}>;
|
|
476
|
+
startDeviceTestSession(buildId: string): Promise<{
|
|
477
|
+
sessionId: string;
|
|
478
|
+
wsUrl: string;
|
|
479
|
+
token: string;
|
|
480
|
+
}>;
|
|
481
|
+
/** `appKey` is required — the manifest endpoint has no unauthenticated
|
|
482
|
+
* fallback (see `apps/api/src/routes/ota.ts`'s docblock on it), only
|
|
483
|
+
* `generateOtaAppKey`'s one-time response ever reveals a usable
|
|
484
|
+
* value. This call carries no user session (a mobile app binary has
|
|
485
|
+
* none), so the key travels as a query param rather than the
|
|
486
|
+
* `authorization` header `request()` already reserves for the
|
|
487
|
+
* dashboard/CLI's bearer token. */
|
|
488
|
+
getOtaManifest(appId: string, channel: string, appKey: string, currentHash?: string, installationId?: string): Promise<OtaManifest | null>;
|
|
489
|
+
/** Generates (rotates) this app's OTA manifest key — see
|
|
490
|
+
* `getOtaManifest`. Returned once; the server keeps only its hash. */
|
|
491
|
+
generateOtaAppKey(appId: string): Promise<{
|
|
492
|
+
appKey: string;
|
|
493
|
+
}>;
|
|
494
|
+
listOtaReleases(appId: string, channel?: string, pagination?: {
|
|
495
|
+
limit?: number;
|
|
496
|
+
offset?: number;
|
|
497
|
+
}): Promise<{
|
|
498
|
+
releases: OtaRelease[];
|
|
499
|
+
}>;
|
|
500
|
+
listOtaChannels(appId: string, pagination?: {
|
|
501
|
+
limit?: number;
|
|
502
|
+
offset?: number;
|
|
503
|
+
}): Promise<{
|
|
504
|
+
channels: OtaChannel[];
|
|
505
|
+
}>;
|
|
506
|
+
promoteOtaRelease(appId: string, input: {
|
|
507
|
+
buildId: string;
|
|
508
|
+
channel?: string;
|
|
509
|
+
mandatory?: boolean;
|
|
510
|
+
rollout?: number;
|
|
511
|
+
}): Promise<{
|
|
512
|
+
release: OtaRelease;
|
|
513
|
+
}>;
|
|
514
|
+
/** Progresses an existing release's rollout in place (10% -> 50% ->
|
|
515
|
+
* 100%) instead of re-promoting the same build, which would mint a
|
|
516
|
+
* new release id and reshuffle `isInStagedRollout`'s per-install
|
|
517
|
+
* bucketing — see `updateOtaReleaseRolloutSchema`'s own docblock in
|
|
518
|
+
* `packages/core/src/schemas.ts`. */
|
|
519
|
+
updateOtaReleaseRollout(appId: string, releaseId: string, rollout: number): Promise<{
|
|
520
|
+
release: OtaRelease;
|
|
521
|
+
}>;
|
|
522
|
+
setActiveOtaRelease(appId: string, channel: string, releaseId: string | null): Promise<{
|
|
523
|
+
ok: true;
|
|
524
|
+
}>;
|
|
525
|
+
rollbackOtaChannel(appId: string, channel: string): Promise<{
|
|
526
|
+
release: OtaRelease | null;
|
|
527
|
+
}>;
|
|
528
|
+
}
|
|
529
|
+
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
|