@remixhq/core 0.1.8 → 0.1.10

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";
@@ -284,7 +304,12 @@ type CollabApiClient = {
284
304
  listApps(params?: {
285
305
  projectId?: string;
286
306
  organizationId?: string;
307
+ ownership?: "mine" | "shared" | "all";
308
+ accessScope?: "all_readable" | "explicit_member";
309
+ createdBy?: "me" | string;
287
310
  forked?: "only" | "exclude" | "all";
311
+ limit?: number;
312
+ offset?: number;
288
313
  }): Promise<unknown>;
289
314
  getApp(appId: string): Promise<unknown>;
290
315
  getMergeRequest(mrId: string): Promise<unknown>;
@@ -376,6 +401,8 @@ type CollabApiClient = {
376
401
  targetAppId?: string;
377
402
  status?: string | string[];
378
403
  kind?: string;
404
+ limit?: number;
405
+ offset?: number;
379
406
  }): Promise<unknown>;
380
407
  openMergeRequest(sourceAppId: string): Promise<unknown>;
381
408
  getMergeRequestReview(mrId: string): Promise<unknown>;
@@ -399,21 +426,39 @@ type CollabApiClient = {
399
426
  role?: string;
400
427
  ttlDays?: number;
401
428
  }): Promise<unknown>;
402
- listOrganizationMembers(orgId: string): Promise<unknown>;
429
+ listOrganizationMembers(orgId: string, params?: {
430
+ limit?: number;
431
+ offset?: number;
432
+ }): Promise<unknown>;
403
433
  updateOrganizationMember(orgId: string, userId: string, payload: {
404
434
  role: OrganizationMemberRole;
405
435
  }): Promise<unknown>;
406
- listProjectMembers(projectId: string): Promise<unknown>;
436
+ listProjectMembers(projectId: string, params?: {
437
+ limit?: number;
438
+ offset?: number;
439
+ }): Promise<unknown>;
407
440
  updateProjectMember(projectId: string, userId: string, payload: {
408
441
  role: ProjectMemberRole;
409
442
  }): Promise<unknown>;
410
- listAppMembers(appId: string): Promise<unknown>;
443
+ listAppMembers(appId: string, params?: {
444
+ limit?: number;
445
+ offset?: number;
446
+ }): Promise<unknown>;
411
447
  updateAppMember(appId: string, userId: string, payload: {
412
448
  role: AppMemberRole;
413
449
  }): Promise<unknown>;
414
- listOrganizationInvites(orgId: string): Promise<unknown>;
415
- listProjectInvites(projectId: string): Promise<unknown>;
416
- listAppInvites(appId: string): Promise<unknown>;
450
+ listOrganizationInvites(orgId: string, params?: {
451
+ limit?: number;
452
+ offset?: number;
453
+ }): Promise<unknown>;
454
+ listProjectInvites(projectId: string, params?: {
455
+ limit?: number;
456
+ offset?: number;
457
+ }): Promise<unknown>;
458
+ listAppInvites(appId: string, params?: {
459
+ limit?: number;
460
+ offset?: number;
461
+ }): Promise<unknown>;
417
462
  resendOrganizationInvite(orgId: string, inviteId: string, payload?: {
418
463
  ttlDays?: number;
419
464
  }): Promise<unknown>;
@@ -474,6 +519,24 @@ declare function collabAdd(params: {
474
519
  };
475
520
  }): Promise<JsonObject>;
476
521
 
522
+ declare function collabFinalizeTurn(params: {
523
+ api: CollabApiClient;
524
+ cwd: string;
525
+ prompt: string;
526
+ assistantResponse: string;
527
+ diff?: string | null;
528
+ diffSource?: "worktree" | "external";
529
+ sync?: boolean;
530
+ allowBranchMismatch?: boolean;
531
+ idempotencyKey?: string | null;
532
+ actor?: {
533
+ type?: string;
534
+ name?: string;
535
+ version?: string;
536
+ provider?: string;
537
+ };
538
+ }): Promise<CollabFinalizeTurnResult>;
539
+
477
540
  declare function collabRecordingPreflight(params: {
478
541
  api: CollabApiClient;
479
542
  cwd: string;
@@ -524,10 +587,17 @@ declare function collabListMergeRequests(params: {
524
587
  appId?: string | null;
525
588
  status?: string | string[];
526
589
  kind?: string | null;
590
+ limit?: number;
591
+ offset?: number;
527
592
  }): Promise<{
528
593
  queue: MergeRequestQueue;
529
594
  appId: string | null;
530
595
  mergeRequests: MergeRequest[];
596
+ pagination: {
597
+ limit: number;
598
+ offset: number;
599
+ hasMore: boolean;
600
+ };
531
601
  }>;
532
602
 
533
603
  declare function getMemberRolesForScope(scope: InvitationScopeType): readonly string[];
@@ -537,10 +607,17 @@ declare function collabListMembers(params: {
537
607
  cwd: string;
538
608
  scope: InvitationScopeType;
539
609
  targetId?: string | null;
610
+ limit?: number;
611
+ offset?: number;
540
612
  }): Promise<{
541
613
  scopeType: InvitationScopeType;
542
614
  targetId: string;
543
615
  members: CollabMember[];
616
+ pagination: {
617
+ limit: number;
618
+ offset: number;
619
+ hasMore: boolean;
620
+ };
544
621
  }>;
545
622
  declare function collabUpdateMemberRole(params: {
546
623
  api: CollabApiClient;
@@ -599,8 +676,19 @@ declare function collabInvite(params: {
599
676
 
600
677
  declare function collabList(params: {
601
678
  api: CollabApiClient;
679
+ ownership?: "mine" | "shared" | "all";
680
+ accessScope?: "all_readable" | "explicit_member";
681
+ createdBy?: "me" | string;
682
+ forked?: "only" | "exclude" | "all";
683
+ limit?: number;
684
+ offset?: number;
602
685
  }): Promise<{
603
686
  apps: JsonObject[];
687
+ pagination: {
688
+ limit: number;
689
+ offset: number;
690
+ hasMore: boolean;
691
+ };
604
692
  }>;
605
693
 
606
694
  declare function collabReconcile(params: {
@@ -797,4 +885,4 @@ declare function collabView(params: {
797
885
  mrId: string;
798
886
  }): Promise<MergeRequestReview>;
799
887
 
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 };
888
+ 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 };