@remixhq/core 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,385 @@
1
+ import {
2
+ RemixError
3
+ } from "./chunk-YZ34ICNN.js";
4
+
5
+ // src/api/client.ts
6
+ async function readJsonSafe(res) {
7
+ const ct = res.headers.get("content-type") ?? "";
8
+ if (!ct.toLowerCase().includes("application/json")) return null;
9
+ try {
10
+ return await res.json();
11
+ } catch {
12
+ return null;
13
+ }
14
+ }
15
+ function createApiClient(config, opts) {
16
+ const apiKey = (opts?.apiKey ?? "").trim();
17
+ const tokenProvider = opts?.tokenProvider;
18
+ const CLIENT_KEY_HEADER = "x-comerge-api-key";
19
+ async function request(path, init) {
20
+ if (!tokenProvider) {
21
+ throw new RemixError("API client is missing a token provider.", {
22
+ exitCode: 1,
23
+ hint: "Configure auth before creating the Remix API client."
24
+ });
25
+ }
26
+ const auth = await tokenProvider();
27
+ const url = new URL(path, config.apiUrl).toString();
28
+ const doFetch = async (bearer) => fetch(url, {
29
+ ...init,
30
+ headers: {
31
+ Accept: "application/json",
32
+ "Content-Type": "application/json",
33
+ ...init?.headers ?? {},
34
+ Authorization: `Bearer ${bearer}`,
35
+ ...apiKey ? { [CLIENT_KEY_HEADER]: apiKey } : {}
36
+ }
37
+ });
38
+ let res = await doFetch(auth.token);
39
+ if (res.status === 401 && !auth.fromEnv && auth.session?.refresh_token) {
40
+ const refreshed = await tokenProvider({ forceRefresh: true });
41
+ res = await doFetch(refreshed.token);
42
+ }
43
+ if (!res.ok) {
44
+ const body = await readJsonSafe(res);
45
+ const msg = (body && typeof body === "object" && body && "message" in body && typeof body.message === "string" ? body.message : null) ?? `Request failed (status ${res.status})`;
46
+ throw new RemixError(msg, { exitCode: 1, hint: body ? JSON.stringify(body, null, 2) : null });
47
+ }
48
+ const json = await readJsonSafe(res);
49
+ return json ?? null;
50
+ }
51
+ async function requestBinary(path, init) {
52
+ if (!tokenProvider) {
53
+ throw new RemixError("API client is missing a token provider.", {
54
+ exitCode: 1,
55
+ hint: "Configure auth before creating the Remix API client."
56
+ });
57
+ }
58
+ const auth = await tokenProvider();
59
+ const url = new URL(path, config.apiUrl).toString();
60
+ const doFetch = async (bearer) => fetch(url, {
61
+ ...init,
62
+ headers: {
63
+ Accept: "*/*",
64
+ ...init?.headers ?? {},
65
+ Authorization: `Bearer ${bearer}`,
66
+ ...apiKey ? { [CLIENT_KEY_HEADER]: apiKey } : {}
67
+ }
68
+ });
69
+ let res = await doFetch(auth.token);
70
+ if (res.status === 401 && !auth.fromEnv && auth.session?.refresh_token) {
71
+ const refreshed = await tokenProvider({ forceRefresh: true });
72
+ res = await doFetch(refreshed.token);
73
+ }
74
+ if (!res.ok) {
75
+ const body = await readJsonSafe(res);
76
+ const msg = (body && typeof body === "object" && body && "message" in body && typeof body.message === "string" ? body.message : null) ?? `Request failed (status ${res.status})`;
77
+ throw new RemixError(msg, { exitCode: 1, hint: body ? JSON.stringify(body, null, 2) : null });
78
+ }
79
+ const contentDisposition = res.headers.get("content-disposition") ?? "";
80
+ const fileNameMatch = contentDisposition.match(/filename=\"([^\"]+)\"/i);
81
+ return {
82
+ data: Buffer.from(await res.arrayBuffer()),
83
+ fileName: fileNameMatch?.[1] ?? null,
84
+ contentType: res.headers.get("content-type")
85
+ };
86
+ }
87
+ return {
88
+ getMe: () => request("/v1/me", { method: "GET" }),
89
+ listOrganizations: () => request("/v1/organizations", { method: "GET" }),
90
+ getOrganization: (orgId) => request(`/v1/organizations/${encodeURIComponent(orgId)}`, { method: "GET" }),
91
+ listProjects: (params) => {
92
+ const qs = new URLSearchParams();
93
+ if (params?.organizationId) qs.set("organizationId", params.organizationId);
94
+ if (params?.clientAppId) qs.set("clientAppId", params.clientAppId);
95
+ const suffix = qs.toString() ? `?${qs.toString()}` : "";
96
+ return request(`/v1/projects${suffix}`, { method: "GET" });
97
+ },
98
+ getProject: (projectId) => request(`/v1/projects/${encodeURIComponent(projectId)}`, { method: "GET" }),
99
+ resolveProjectBinding: (params) => {
100
+ const qs = new URLSearchParams();
101
+ if (params.repoFingerprint) qs.set("repoFingerprint", params.repoFingerprint);
102
+ if (params.remoteUrl) qs.set("remoteUrl", params.remoteUrl);
103
+ return request(`/v1/projects/bindings/resolve?${qs.toString()}`, { method: "GET" });
104
+ },
105
+ autoEnableDeveloper: () => request("/v1/developer/auto-enable", { method: "POST" }),
106
+ listClientApps: (params) => {
107
+ const qs = params?.orgId ? `?orgId=${encodeURIComponent(params.orgId)}` : "";
108
+ return request(`/v1/developer/client-apps${qs}`, { method: "GET" });
109
+ },
110
+ createClientApp: (payload) => request("/v1/developer/client-apps", { method: "POST", body: JSON.stringify(payload) }),
111
+ createClientAppKey: (clientAppId, payload) => request(`/v1/developer/client-apps/${encodeURIComponent(clientAppId)}/keys`, {
112
+ method: "POST",
113
+ body: JSON.stringify(payload ?? {})
114
+ }),
115
+ listApps: (params) => {
116
+ const qs = new URLSearchParams();
117
+ if (params?.projectId) qs.set("projectId", params.projectId);
118
+ if (params?.organizationId) qs.set("organizationId", params.organizationId);
119
+ if (params?.forked) qs.set("forked", params.forked);
120
+ if (typeof params?.limit === "number") qs.set("limit", String(params.limit));
121
+ if (typeof params?.offset === "number") qs.set("offset", String(params.offset));
122
+ const suffix = qs.toString() ? `?${qs.toString()}` : "";
123
+ return request(`/v1/apps${suffix}`, { method: "GET" });
124
+ },
125
+ getApp: (appId) => request(`/v1/apps/${encodeURIComponent(appId)}`, { method: "GET" }),
126
+ getAppContext: (appId) => request(`/v1/apps/${encodeURIComponent(appId)}/context`, { method: "GET" }),
127
+ getAppOverview: (appId) => request(`/v1/apps/${encodeURIComponent(appId)}/overview`, { method: "GET" }),
128
+ listAppTimeline: (appId, params) => {
129
+ const qs = new URLSearchParams();
130
+ if (typeof params?.limit === "number") qs.set("limit", String(params.limit));
131
+ if (params?.cursor) qs.set("cursor", params.cursor);
132
+ const suffix = qs.toString() ? `?${qs.toString()}` : "";
133
+ return request(`/v1/apps/${encodeURIComponent(appId)}/timeline${suffix}`, { method: "GET" });
134
+ },
135
+ getAppTimelineEvent: (appId, eventId) => request(`/v1/apps/${encodeURIComponent(appId)}/timeline/${encodeURIComponent(eventId)}`, { method: "GET" }),
136
+ listAppEditQueue: (appId, params) => {
137
+ const qs = new URLSearchParams();
138
+ if (typeof params?.limit === "number") qs.set("limit", String(params.limit));
139
+ if (typeof params?.offset === "number") qs.set("offset", String(params.offset));
140
+ const suffix = qs.toString() ? `?${qs.toString()}` : "";
141
+ return request(`/v1/apps/${encodeURIComponent(appId)}/edit-queue${suffix}`, { method: "GET" });
142
+ },
143
+ getMergeRequest: (mrId) => request(`/v1/merge-requests/${encodeURIComponent(mrId)}`, { method: "GET" }),
144
+ presignImportUpload: (payload) => request("/v1/apps/import/upload/presign", { method: "POST", body: JSON.stringify(payload) }),
145
+ importFromUpload: (payload) => request("/v1/apps/import/upload", { method: "POST", body: JSON.stringify(payload) }),
146
+ presignImportUploadFirstParty: (payload) => request("/v1/apps/import/upload/presign/first-party", { method: "POST", body: JSON.stringify(payload) }),
147
+ importFromUploadFirstParty: (payload) => request("/v1/apps/import/upload/first-party", { method: "POST", body: JSON.stringify(payload) }),
148
+ importFromGithubFirstParty: (payload) => request("/v1/apps/import/github/first-party", { method: "POST", body: JSON.stringify(payload) }),
149
+ forkApp: (appId, payload) => request(`/v1/apps/${encodeURIComponent(appId)}/fork`, { method: "POST", body: JSON.stringify(payload ?? {}) }),
150
+ downloadAppBundle: (appId) => requestBinary(`/v1/apps/${encodeURIComponent(appId)}/download.bundle`, { method: "GET" }),
151
+ createChangeStep: (appId, payload) => request(`/v1/apps/${encodeURIComponent(appId)}/change-steps`, {
152
+ method: "POST",
153
+ body: JSON.stringify(payload)
154
+ }),
155
+ createCollabTurn: (appId, payload) => request(`/v1/apps/${encodeURIComponent(appId)}/collab-turns`, {
156
+ method: "POST",
157
+ body: JSON.stringify(payload)
158
+ }),
159
+ listCollabTurns: (appId, params) => {
160
+ const qs = new URLSearchParams();
161
+ if (params?.limit !== void 0) qs.set("limit", String(params.limit));
162
+ if (params?.offset !== void 0) qs.set("offset", String(params.offset));
163
+ if (params?.changeStepId) qs.set("changeStepId", params.changeStepId);
164
+ if (params?.threadId) qs.set("threadId", params.threadId);
165
+ if (params?.createdAfter) qs.set("createdAfter", params.createdAfter);
166
+ if (params?.createdBefore) qs.set("createdBefore", params.createdBefore);
167
+ const suffix = qs.toString() ? `?${qs.toString()}` : "";
168
+ return request(`/v1/apps/${encodeURIComponent(appId)}/collab-turns${suffix}`, { method: "GET" });
169
+ },
170
+ getCollabTurn: (appId, collabTurnId) => request(`/v1/apps/${encodeURIComponent(appId)}/collab-turns/${encodeURIComponent(collabTurnId)}`, {
171
+ method: "GET"
172
+ }),
173
+ getAgentMemorySummary: (appId) => request(`/v1/apps/${encodeURIComponent(appId)}/agent-memory/summary`, { method: "GET" }),
174
+ listAgentMemoryTimeline: (appId, params) => {
175
+ const qs = new URLSearchParams();
176
+ if (params?.limit !== void 0) qs.set("limit", String(params.limit));
177
+ if (params?.offset !== void 0) qs.set("offset", String(params.offset));
178
+ if (params?.createdAfter) qs.set("createdAfter", params.createdAfter);
179
+ if (params?.createdBefore) qs.set("createdBefore", params.createdBefore);
180
+ if (params?.kinds?.length) {
181
+ for (const kind of params.kinds) qs.append("kinds", kind);
182
+ }
183
+ const suffix = qs.toString() ? `?${qs.toString()}` : "";
184
+ return request(`/v1/apps/${encodeURIComponent(appId)}/agent-memory/timeline${suffix}`, { method: "GET" });
185
+ },
186
+ searchAgentMemory: (appId, params) => {
187
+ const qs = new URLSearchParams();
188
+ qs.set("q", params.q);
189
+ if (params.limit !== void 0) qs.set("limit", String(params.limit));
190
+ if (params.offset !== void 0) qs.set("offset", String(params.offset));
191
+ if (params.createdAfter) qs.set("createdAfter", params.createdAfter);
192
+ if (params.createdBefore) qs.set("createdBefore", params.createdBefore);
193
+ if (params.kinds?.length) {
194
+ for (const kind of params.kinds) qs.append("kinds", kind);
195
+ }
196
+ return request(`/v1/apps/${encodeURIComponent(appId)}/agent-memory/search?${qs.toString()}`, { method: "GET" });
197
+ },
198
+ getChangeStep: (appId, changeStepId) => request(`/v1/apps/${encodeURIComponent(appId)}/change-steps/${encodeURIComponent(changeStepId)}`, { method: "GET" }),
199
+ getChangeStepDiff: (appId, changeStepId) => request(`/v1/apps/${encodeURIComponent(appId)}/change-steps/${encodeURIComponent(changeStepId)}/diff`, {
200
+ method: "GET"
201
+ }),
202
+ startChangeStepReplay: (appId, payload) => request(`/v1/apps/${encodeURIComponent(appId)}/change-steps/replays`, {
203
+ method: "POST",
204
+ body: JSON.stringify(payload)
205
+ }),
206
+ getChangeStepReplay: (appId, replayId) => request(`/v1/apps/${encodeURIComponent(appId)}/change-steps/replays/${encodeURIComponent(replayId)}`, {
207
+ method: "GET"
208
+ }),
209
+ getChangeStepReplayDiff: (appId, replayId) => request(`/v1/apps/${encodeURIComponent(appId)}/change-steps/replays/${encodeURIComponent(replayId)}/diff`, {
210
+ method: "GET"
211
+ }),
212
+ listMergeRequests: (params) => {
213
+ const qs = new URLSearchParams();
214
+ if (params?.queue) qs.set("queue", params.queue);
215
+ if (params?.appId) qs.set("appId", params.appId);
216
+ if (params?.sourceAppId) qs.set("sourceAppId", params.sourceAppId);
217
+ if (params?.targetAppId) qs.set("targetAppId", params.targetAppId);
218
+ if (Array.isArray(params?.status)) {
219
+ for (const status of params.status) qs.append("status", status);
220
+ } else if (typeof params?.status === "string") {
221
+ qs.set("status", params.status);
222
+ }
223
+ if (params?.kind) qs.set("kind", params.kind);
224
+ if (typeof params?.limit === "number") qs.set("limit", String(params.limit));
225
+ if (typeof params?.offset === "number") qs.set("offset", String(params.offset));
226
+ const suffix = qs.toString() ? `?${qs.toString()}` : "";
227
+ return request(`/v1/merge-requests${suffix}`, { method: "GET" });
228
+ },
229
+ openMergeRequest: (sourceAppId) => request("/v1/merge-requests", { method: "POST", body: JSON.stringify({ sourceAppId }) }),
230
+ getMergeRequestReview: (mrId) => request(`/v1/merge-requests/${encodeURIComponent(mrId)}/review`, { method: "GET" }),
231
+ updateMergeRequest: (mrId, payload) => request(`/v1/merge-requests/${encodeURIComponent(mrId)}`, { method: "PATCH", body: JSON.stringify(payload) }),
232
+ createOrganizationInvite: (orgId, payload) => request(`/v1/organizations/${encodeURIComponent(orgId)}/invitations`, {
233
+ method: "POST",
234
+ body: JSON.stringify(payload)
235
+ }),
236
+ createProjectInvite: (projectId, payload) => request(`/v1/projects/${encodeURIComponent(projectId)}/invitations`, {
237
+ method: "POST",
238
+ body: JSON.stringify(payload)
239
+ }),
240
+ createAppInvite: (appId, payload) => request(`/v1/apps/${encodeURIComponent(appId)}/invitations`, {
241
+ method: "POST",
242
+ body: JSON.stringify(payload)
243
+ }),
244
+ listOrganizationMembers: (orgId, params) => {
245
+ const qs = new URLSearchParams();
246
+ if (typeof params?.limit === "number") qs.set("limit", String(params.limit));
247
+ if (typeof params?.offset === "number") qs.set("offset", String(params.offset));
248
+ const suffix = qs.toString() ? `?${qs.toString()}` : "";
249
+ return request(`/v1/organizations/${encodeURIComponent(orgId)}/members${suffix}`, { method: "GET" });
250
+ },
251
+ updateOrganizationMember: (orgId, userId, payload) => request(`/v1/organizations/${encodeURIComponent(orgId)}/members/${encodeURIComponent(userId)}`, {
252
+ method: "PATCH",
253
+ body: JSON.stringify(payload)
254
+ }),
255
+ listProjectMembers: (projectId, params) => {
256
+ const qs = new URLSearchParams();
257
+ if (typeof params?.limit === "number") qs.set("limit", String(params.limit));
258
+ if (typeof params?.offset === "number") qs.set("offset", String(params.offset));
259
+ const suffix = qs.toString() ? `?${qs.toString()}` : "";
260
+ return request(`/v1/projects/${encodeURIComponent(projectId)}/members${suffix}`, { method: "GET" });
261
+ },
262
+ updateProjectMember: (projectId, userId, payload) => request(`/v1/projects/${encodeURIComponent(projectId)}/members/${encodeURIComponent(userId)}`, {
263
+ method: "PATCH",
264
+ body: JSON.stringify(payload)
265
+ }),
266
+ listAppMembers: (appId, params) => {
267
+ const qs = new URLSearchParams();
268
+ if (typeof params?.limit === "number") qs.set("limit", String(params.limit));
269
+ if (typeof params?.offset === "number") qs.set("offset", String(params.offset));
270
+ const suffix = qs.toString() ? `?${qs.toString()}` : "";
271
+ return request(`/v1/apps/${encodeURIComponent(appId)}/members${suffix}`, { method: "GET" });
272
+ },
273
+ updateAppMember: (appId, userId, payload) => request(`/v1/apps/${encodeURIComponent(appId)}/members/${encodeURIComponent(userId)}`, {
274
+ method: "PATCH",
275
+ body: JSON.stringify(payload)
276
+ }),
277
+ listOrganizationInvites: (orgId, params) => {
278
+ const qs = new URLSearchParams();
279
+ if (typeof params?.limit === "number") qs.set("limit", String(params.limit));
280
+ if (typeof params?.offset === "number") qs.set("offset", String(params.offset));
281
+ const suffix = qs.toString() ? `?${qs.toString()}` : "";
282
+ return request(`/v1/organizations/${encodeURIComponent(orgId)}/invitations${suffix}`, { method: "GET" });
283
+ },
284
+ listProjectInvites: (projectId, params) => {
285
+ const qs = new URLSearchParams();
286
+ if (typeof params?.limit === "number") qs.set("limit", String(params.limit));
287
+ if (typeof params?.offset === "number") qs.set("offset", String(params.offset));
288
+ const suffix = qs.toString() ? `?${qs.toString()}` : "";
289
+ return request(`/v1/projects/${encodeURIComponent(projectId)}/invitations${suffix}`, { method: "GET" });
290
+ },
291
+ listAppInvites: (appId, params) => {
292
+ const qs = new URLSearchParams();
293
+ if (typeof params?.limit === "number") qs.set("limit", String(params.limit));
294
+ if (typeof params?.offset === "number") qs.set("offset", String(params.offset));
295
+ const suffix = qs.toString() ? `?${qs.toString()}` : "";
296
+ return request(`/v1/apps/${encodeURIComponent(appId)}/invitations${suffix}`, { method: "GET" });
297
+ },
298
+ resendOrganizationInvite: (orgId, inviteId, payload) => request(`/v1/organizations/${encodeURIComponent(orgId)}/invitations/${encodeURIComponent(inviteId)}/resend`, {
299
+ method: "POST",
300
+ body: JSON.stringify(payload ?? {})
301
+ }),
302
+ resendProjectInvite: (projectId, inviteId, payload) => request(`/v1/projects/${encodeURIComponent(projectId)}/invitations/${encodeURIComponent(inviteId)}/resend`, {
303
+ method: "POST",
304
+ body: JSON.stringify(payload ?? {})
305
+ }),
306
+ resendAppInvite: (appId, inviteId, payload) => request(`/v1/apps/${encodeURIComponent(appId)}/invitations/${encodeURIComponent(inviteId)}/resend`, {
307
+ method: "POST",
308
+ body: JSON.stringify(payload ?? {})
309
+ }),
310
+ revokeOrganizationInvite: (orgId, inviteId) => request(`/v1/organizations/${encodeURIComponent(orgId)}/invitations/${encodeURIComponent(inviteId)}`, {
311
+ method: "DELETE"
312
+ }),
313
+ revokeProjectInvite: (projectId, inviteId) => request(`/v1/projects/${encodeURIComponent(projectId)}/invitations/${encodeURIComponent(inviteId)}`, {
314
+ method: "DELETE"
315
+ }),
316
+ revokeAppInvite: (appId, inviteId) => request(`/v1/apps/${encodeURIComponent(appId)}/invitations/${encodeURIComponent(inviteId)}`, {
317
+ method: "DELETE"
318
+ }),
319
+ acceptInvitation: (payload) => request("/v1/invitations/accept", { method: "POST", body: JSON.stringify(payload) }),
320
+ syncUpstreamApp: (appId) => request(`/v1/apps/${encodeURIComponent(appId)}/sync-upstream`, {
321
+ method: "POST",
322
+ body: JSON.stringify({})
323
+ }),
324
+ preflightAppReconcile: (appId, payload) => request(`/v1/apps/${encodeURIComponent(appId)}/reconcile/preflight`, {
325
+ method: "POST",
326
+ body: JSON.stringify(payload)
327
+ }),
328
+ startAppReconcile: (appId, payload) => request(`/v1/apps/${encodeURIComponent(appId)}/reconcile/start`, {
329
+ method: "POST",
330
+ body: JSON.stringify(payload)
331
+ }),
332
+ getAppReconcile: (appId, reconcileId) => request(`/v1/apps/${encodeURIComponent(appId)}/reconcile/${encodeURIComponent(reconcileId)}`, { method: "GET" }),
333
+ downloadAppReconcileBundle: (appId, reconcileId) => requestBinary(`/v1/apps/${encodeURIComponent(appId)}/reconcile/${encodeURIComponent(reconcileId)}/download.bundle`, {
334
+ method: "GET"
335
+ }),
336
+ syncLocalApp: (appId, payload) => request(`/v1/apps/${encodeURIComponent(appId)}/sync-local`, {
337
+ method: "POST",
338
+ body: JSON.stringify(payload)
339
+ }),
340
+ initiateBundle: (appId, payload) => request(`/v1/apps/${encodeURIComponent(appId)}/bundles`, { method: "POST", body: JSON.stringify(payload) }),
341
+ getBundle: (appId, bundleId) => request(`/v1/apps/${encodeURIComponent(appId)}/bundles/${encodeURIComponent(bundleId)}`, { method: "GET" }),
342
+ getBundleDownloadUrl: (appId, bundleId, options) => request(
343
+ `/v1/apps/${encodeURIComponent(appId)}/bundles/${encodeURIComponent(bundleId)}/download?redirect=${options?.redirect ?? false}`,
344
+ { method: "GET" }
345
+ ),
346
+ getBundleAssetsDownloadUrl: (appId, bundleId, options) => {
347
+ const qs = new URLSearchParams({
348
+ redirect: String(options?.redirect ?? false),
349
+ kind: options?.kind ?? "metro-assets"
350
+ });
351
+ return request(
352
+ `/v1/apps/${encodeURIComponent(appId)}/bundles/${encodeURIComponent(bundleId)}/assets/download?${qs.toString()}`,
353
+ { method: "GET" }
354
+ );
355
+ },
356
+ listAgentRuns: (appId, params) => {
357
+ const qs = new URLSearchParams();
358
+ if (typeof params?.limit === "number") qs.set("limit", String(params.limit));
359
+ if (typeof params?.offset === "number") qs.set("offset", String(params.offset));
360
+ if (params?.status) qs.set("status", params.status);
361
+ if (params?.currentPhase) qs.set("currentPhase", params.currentPhase);
362
+ if (params?.createdAfter) qs.set("createdAfter", params.createdAfter);
363
+ if (params?.createdBefore) qs.set("createdBefore", params.createdBefore);
364
+ const suffix = qs.toString() ? `?${qs.toString()}` : "";
365
+ return request(`/v1/apps/${encodeURIComponent(appId)}/agent-runs${suffix}`, { method: "GET" });
366
+ },
367
+ getAgentRun: (appId, runId) => request(`/v1/apps/${encodeURIComponent(appId)}/agent-runs/${encodeURIComponent(runId)}`, { method: "GET" }),
368
+ listAgentRunEvents: (appId, runId, params) => {
369
+ const qs = new URLSearchParams();
370
+ if (typeof params?.limit === "number") qs.set("limit", String(params.limit));
371
+ if (typeof params?.offset === "number") qs.set("offset", String(params.offset));
372
+ if (params?.createdAfter) qs.set("createdAfter", params.createdAfter);
373
+ if (params?.createdBefore) qs.set("createdBefore", params.createdBefore);
374
+ const suffix = qs.toString() ? `?${qs.toString()}` : "";
375
+ return request(`/v1/apps/${encodeURIComponent(appId)}/agent-runs/${encodeURIComponent(runId)}/events${suffix}`, {
376
+ method: "GET"
377
+ });
378
+ },
379
+ getSandboxStatus: (appId) => request(`/v1/apps/${encodeURIComponent(appId)}/sandbox/status`, { method: "GET" })
380
+ };
381
+ }
382
+
383
+ export {
384
+ createApiClient
385
+ };
package/dist/collab.d.ts CHANGED
@@ -241,6 +241,26 @@ type CollabTurn = {
241
241
  prompt: string | null;
242
242
  assistantResponse: string | null;
243
243
  };
244
+ type CollabFinalizeTurnMode = "changed_turn" | "no_diff_turn";
245
+ type CollabFinalizeTurnAutoSync = {
246
+ requested: boolean;
247
+ eligible: boolean;
248
+ attempted: boolean;
249
+ applied: boolean;
250
+ trackedChangesDiscarded: boolean;
251
+ capturedUntrackedPathsCandidate: string[];
252
+ localHeadBefore: string | null;
253
+ localHeadAfter: string | null;
254
+ localRepoMutated: boolean;
255
+ };
256
+ type CollabFinalizeTurnResult = {
257
+ mode: CollabFinalizeTurnMode;
258
+ idempotencyKey: string;
259
+ changeStep: JsonObject | null;
260
+ collabTurn: CollabTurn | null;
261
+ autoSync: CollabFinalizeTurnAutoSync | null;
262
+ warnings: string[];
263
+ };
244
264
  type InvitationScopeType = "organization" | "project" | "app";
245
265
  type MembershipScopeType = InvitationScopeType;
246
266
  type OrganizationMemberRole = "owner" | "admin" | "member" | "viewer";
@@ -285,6 +305,8 @@ type CollabApiClient = {
285
305
  projectId?: string;
286
306
  organizationId?: string;
287
307
  forked?: "only" | "exclude" | "all";
308
+ limit?: number;
309
+ offset?: number;
288
310
  }): Promise<unknown>;
289
311
  getApp(appId: string): Promise<unknown>;
290
312
  getMergeRequest(mrId: string): Promise<unknown>;
@@ -376,6 +398,8 @@ type CollabApiClient = {
376
398
  targetAppId?: string;
377
399
  status?: string | string[];
378
400
  kind?: string;
401
+ limit?: number;
402
+ offset?: number;
379
403
  }): Promise<unknown>;
380
404
  openMergeRequest(sourceAppId: string): Promise<unknown>;
381
405
  getMergeRequestReview(mrId: string): Promise<unknown>;
@@ -399,21 +423,39 @@ type CollabApiClient = {
399
423
  role?: string;
400
424
  ttlDays?: number;
401
425
  }): Promise<unknown>;
402
- listOrganizationMembers(orgId: string): Promise<unknown>;
426
+ listOrganizationMembers(orgId: string, params?: {
427
+ limit?: number;
428
+ offset?: number;
429
+ }): Promise<unknown>;
403
430
  updateOrganizationMember(orgId: string, userId: string, payload: {
404
431
  role: OrganizationMemberRole;
405
432
  }): Promise<unknown>;
406
- listProjectMembers(projectId: string): Promise<unknown>;
433
+ listProjectMembers(projectId: string, params?: {
434
+ limit?: number;
435
+ offset?: number;
436
+ }): Promise<unknown>;
407
437
  updateProjectMember(projectId: string, userId: string, payload: {
408
438
  role: ProjectMemberRole;
409
439
  }): Promise<unknown>;
410
- listAppMembers(appId: string): Promise<unknown>;
440
+ listAppMembers(appId: string, params?: {
441
+ limit?: number;
442
+ offset?: number;
443
+ }): Promise<unknown>;
411
444
  updateAppMember(appId: string, userId: string, payload: {
412
445
  role: AppMemberRole;
413
446
  }): Promise<unknown>;
414
- listOrganizationInvites(orgId: string): Promise<unknown>;
415
- listProjectInvites(projectId: string): Promise<unknown>;
416
- listAppInvites(appId: string): Promise<unknown>;
447
+ listOrganizationInvites(orgId: string, params?: {
448
+ limit?: number;
449
+ offset?: number;
450
+ }): Promise<unknown>;
451
+ listProjectInvites(projectId: string, params?: {
452
+ limit?: number;
453
+ offset?: number;
454
+ }): Promise<unknown>;
455
+ listAppInvites(appId: string, params?: {
456
+ limit?: number;
457
+ offset?: number;
458
+ }): Promise<unknown>;
417
459
  resendOrganizationInvite(orgId: string, inviteId: string, payload?: {
418
460
  ttlDays?: number;
419
461
  }): Promise<unknown>;
@@ -474,6 +516,24 @@ declare function collabAdd(params: {
474
516
  };
475
517
  }): Promise<JsonObject>;
476
518
 
519
+ declare function collabFinalizeTurn(params: {
520
+ api: CollabApiClient;
521
+ cwd: string;
522
+ prompt: string;
523
+ assistantResponse: string;
524
+ diff?: string | null;
525
+ diffSource?: "worktree" | "external";
526
+ sync?: boolean;
527
+ allowBranchMismatch?: boolean;
528
+ idempotencyKey?: string | null;
529
+ actor?: {
530
+ type?: string;
531
+ name?: string;
532
+ version?: string;
533
+ provider?: string;
534
+ };
535
+ }): Promise<CollabFinalizeTurnResult>;
536
+
477
537
  declare function collabRecordingPreflight(params: {
478
538
  api: CollabApiClient;
479
539
  cwd: string;
@@ -524,10 +584,17 @@ declare function collabListMergeRequests(params: {
524
584
  appId?: string | null;
525
585
  status?: string | string[];
526
586
  kind?: string | null;
587
+ limit?: number;
588
+ offset?: number;
527
589
  }): Promise<{
528
590
  queue: MergeRequestQueue;
529
591
  appId: string | null;
530
592
  mergeRequests: MergeRequest[];
593
+ pagination: {
594
+ limit: number;
595
+ offset: number;
596
+ hasMore: boolean;
597
+ };
531
598
  }>;
532
599
 
533
600
  declare function getMemberRolesForScope(scope: InvitationScopeType): readonly string[];
@@ -537,10 +604,17 @@ declare function collabListMembers(params: {
537
604
  cwd: string;
538
605
  scope: InvitationScopeType;
539
606
  targetId?: string | null;
607
+ limit?: number;
608
+ offset?: number;
540
609
  }): Promise<{
541
610
  scopeType: InvitationScopeType;
542
611
  targetId: string;
543
612
  members: CollabMember[];
613
+ pagination: {
614
+ limit: number;
615
+ offset: number;
616
+ hasMore: boolean;
617
+ };
544
618
  }>;
545
619
  declare function collabUpdateMemberRole(params: {
546
620
  api: CollabApiClient;
@@ -599,8 +673,16 @@ declare function collabInvite(params: {
599
673
 
600
674
  declare function collabList(params: {
601
675
  api: CollabApiClient;
676
+ forked?: "only" | "exclude" | "all";
677
+ limit?: number;
678
+ offset?: number;
602
679
  }): Promise<{
603
680
  apps: JsonObject[];
681
+ pagination: {
682
+ limit: number;
683
+ offset: number;
684
+ hasMore: boolean;
685
+ };
604
686
  }>;
605
687
 
606
688
  declare function collabReconcile(params: {
@@ -797,4 +879,4 @@ declare function collabView(params: {
797
879
  mrId: string;
798
880
  }): Promise<MergeRequestReview>;
799
881
 
800
- export { type AppMember, type AppMemberRole, type AppReconcileResponse, type CollabApiClient, type CollabApproveMode, type CollabApproveResult, type CollabMember, type CollabRecordingPreflight, type CollabRecordingPreflightStatus, type CollabStatus, type CollabStatusBlockedReason, type CollabStatusRecommendedAction, type CollabTurn, type InvitationScopeType, type JsonObject, type MembershipScopeType, type MergeRequest, type MergeRequestQueue, type MergeRequestReview, type MergeRequestStatus, type OrganizationMember, type OrganizationMemberRole, type ProjectMember, type ProjectMemberRole, type ReconcilePreflightResponse, type SyncLocalResponse, type SyncUpstreamResponse, collabAdd, collabApprove, collabCheckout, collabInit, collabInvite, collabList, collabListMembers, collabListMergeRequests, collabReconcile, collabRecordTurn, collabRecordingPreflight, collabReject, collabRemix, collabRequestMerge, collabStatus, collabSync, collabSyncUpstream, collabUpdateMemberRole, collabView, getMemberRolesForScope, validateMemberRole };
882
+ export { type AppMember, type AppMemberRole, type AppReconcileResponse, type CollabApiClient, type CollabApproveMode, type CollabApproveResult, type CollabFinalizeTurnAutoSync, type CollabFinalizeTurnMode, type CollabFinalizeTurnResult, type CollabMember, type CollabRecordingPreflight, type CollabRecordingPreflightStatus, type CollabStatus, type CollabStatusBlockedReason, type CollabStatusRecommendedAction, type CollabTurn, type InvitationScopeType, type JsonObject, type MembershipScopeType, type MergeRequest, type MergeRequestQueue, type MergeRequestReview, type MergeRequestStatus, type OrganizationMember, type OrganizationMemberRole, type ProjectMember, type ProjectMemberRole, type ReconcilePreflightResponse, type SyncLocalResponse, type SyncUpstreamResponse, collabAdd, collabApprove, collabCheckout, collabFinalizeTurn, collabInit, collabInvite, collabList, collabListMembers, collabListMergeRequests, collabReconcile, collabRecordTurn, collabRecordingPreflight, collabReject, collabRemix, collabRequestMerge, collabStatus, collabSync, collabSyncUpstream, collabUpdateMemberRole, collabView, getMemberRolesForScope, validateMemberRole };