@chrysb/alphaclaw 0.4.6-beta.7 → 0.4.6-beta.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.
- package/bin/alphaclaw.js +2 -32
- package/lib/public/css/theme.css +19 -0
- package/lib/public/js/app.js +1 -1
- package/lib/public/js/components/doctor/helpers.js +71 -5
- package/lib/public/js/components/doctor/index.js +89 -28
- package/lib/public/js/components/envars.js +0 -1
- package/lib/public/js/components/onboarding/welcome-config.js +39 -17
- package/lib/public/js/components/onboarding/welcome-form-step.js +142 -47
- package/lib/public/js/components/onboarding/welcome-import-step.js +306 -0
- package/lib/public/js/components/onboarding/welcome-placeholder-review-step.js +99 -0
- package/lib/public/js/components/onboarding/welcome-secret-review-step.js +191 -0
- package/lib/public/js/components/segmented-control.js +7 -1
- package/lib/public/js/components/welcome/index.js +112 -0
- package/lib/public/js/components/welcome/use-welcome.js +561 -0
- package/lib/public/js/lib/api.js +221 -161
- package/lib/server/commands.js +1 -0
- package/lib/server/constants.js +0 -1
- package/lib/server/doctor/bootstrap-context.js +191 -0
- package/lib/server/doctor/prompt.js +20 -4
- package/lib/server/doctor/service.js +18 -4
- package/lib/server/gateway.js +15 -40
- package/lib/server/onboarding/github.js +120 -19
- package/lib/server/onboarding/import/import-applier.js +321 -0
- package/lib/server/onboarding/import/import-config.js +69 -0
- package/lib/server/onboarding/import/import-scanner.js +469 -0
- package/lib/server/onboarding/import/import-temp.js +63 -0
- package/lib/server/onboarding/import/secret-detector.js +289 -0
- package/lib/server/onboarding/index.js +256 -29
- package/lib/server/onboarding/workspace.js +38 -6
- package/lib/server/routes/onboarding.js +281 -12
- package/lib/server.js +12 -3
- package/package.json +1 -1
- package/lib/public/js/components/welcome.js +0 -318
package/lib/public/js/lib/api.js
CHANGED
|
@@ -23,26 +23,26 @@ export const authFetch = async (url, opts = {}) => {
|
|
|
23
23
|
try {
|
|
24
24
|
window.localStorage?.clear?.();
|
|
25
25
|
} catch {}
|
|
26
|
-
window.location.href =
|
|
27
|
-
throw new Error(
|
|
26
|
+
window.location.href = "/setup";
|
|
27
|
+
throw new Error("Unauthorized");
|
|
28
28
|
}
|
|
29
29
|
return res;
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
export async function fetchStatus() {
|
|
33
|
-
const res = await authFetch(
|
|
33
|
+
const res = await authFetch("/api/status");
|
|
34
34
|
return res.json();
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
export async function fetchPairings() {
|
|
38
|
-
const res = await authFetch(
|
|
38
|
+
const res = await authFetch("/api/pairings");
|
|
39
39
|
return res.json();
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
export async function approvePairing(id, channel) {
|
|
43
43
|
const res = await authFetch(`/api/pairings/${id}/approve`, {
|
|
44
|
-
method:
|
|
45
|
-
headers: {
|
|
44
|
+
method: "POST",
|
|
45
|
+
headers: { "Content-Type": "application/json" },
|
|
46
46
|
body: JSON.stringify({ channel }),
|
|
47
47
|
});
|
|
48
48
|
return res.json();
|
|
@@ -50,15 +50,15 @@ export async function approvePairing(id, channel) {
|
|
|
50
50
|
|
|
51
51
|
export async function rejectPairing(id, channel) {
|
|
52
52
|
const res = await authFetch(`/api/pairings/${id}/reject`, {
|
|
53
|
-
method:
|
|
54
|
-
headers: {
|
|
53
|
+
method: "POST",
|
|
54
|
+
headers: { "Content-Type": "application/json" },
|
|
55
55
|
body: JSON.stringify({ channel }),
|
|
56
56
|
});
|
|
57
57
|
return res.json();
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export async function fetchGoogleAccounts() {
|
|
61
|
-
const res = await authFetch(
|
|
61
|
+
const res = await authFetch("/api/google/accounts");
|
|
62
62
|
return res.json();
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -99,9 +99,9 @@ export async function saveGoogleCredentials({
|
|
|
99
99
|
personal = false,
|
|
100
100
|
accountId = "",
|
|
101
101
|
}) {
|
|
102
|
-
const res = await authFetch(
|
|
103
|
-
method:
|
|
104
|
-
headers: {
|
|
102
|
+
const res = await authFetch("/api/google/credentials", {
|
|
103
|
+
method: "POST",
|
|
104
|
+
headers: { "Content-Type": "application/json" },
|
|
105
105
|
body: JSON.stringify({
|
|
106
106
|
clientId,
|
|
107
107
|
clientSecret,
|
|
@@ -122,18 +122,18 @@ export async function saveGoogleAccount({
|
|
|
122
122
|
personal = false,
|
|
123
123
|
accountId = "",
|
|
124
124
|
}) {
|
|
125
|
-
const res = await authFetch(
|
|
126
|
-
method:
|
|
127
|
-
headers: {
|
|
125
|
+
const res = await authFetch("/api/google/accounts", {
|
|
126
|
+
method: "POST",
|
|
127
|
+
headers: { "Content-Type": "application/json" },
|
|
128
128
|
body: JSON.stringify({ email, services, client, personal, accountId }),
|
|
129
129
|
});
|
|
130
130
|
return res.json();
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
export async function disconnectGoogle(accountId = "") {
|
|
134
|
-
const res = await authFetch(
|
|
135
|
-
method:
|
|
136
|
-
headers: {
|
|
134
|
+
const res = await authFetch("/api/google/disconnect", {
|
|
135
|
+
method: "POST",
|
|
136
|
+
headers: { "Content-Type": "application/json" },
|
|
137
137
|
body: JSON.stringify({ accountId }),
|
|
138
138
|
});
|
|
139
139
|
return res.json();
|
|
@@ -188,7 +188,10 @@ export const renewGmailWatch = async ({
|
|
|
188
188
|
const res = await authFetch("/api/gmail/watch/renew", {
|
|
189
189
|
method: "POST",
|
|
190
190
|
headers: { "Content-Type": "application/json" },
|
|
191
|
-
body: JSON.stringify({
|
|
191
|
+
body: JSON.stringify({
|
|
192
|
+
accountId: String(accountId || ""),
|
|
193
|
+
force: Boolean(force),
|
|
194
|
+
}),
|
|
192
195
|
});
|
|
193
196
|
return parseJsonOrThrow(res, "Could not renew Gmail watch");
|
|
194
197
|
};
|
|
@@ -236,7 +239,9 @@ export const fetchDoctorCards = async ({ runId = "all" } = {}) => {
|
|
|
236
239
|
};
|
|
237
240
|
|
|
238
241
|
export const fetchDoctorRun = async (runId) => {
|
|
239
|
-
const res = await authFetch(
|
|
242
|
+
const res = await authFetch(
|
|
243
|
+
`/api/doctor/runs/${encodeURIComponent(String(runId || ""))}`,
|
|
244
|
+
);
|
|
240
245
|
return parseJsonOrThrow(res, "Could not load Doctor run");
|
|
241
246
|
};
|
|
242
247
|
|
|
@@ -248,11 +253,14 @@ export const fetchDoctorRunCards = async (runId) => {
|
|
|
248
253
|
};
|
|
249
254
|
|
|
250
255
|
export const updateDoctorCardStatus = async ({ cardId, status }) => {
|
|
251
|
-
const res = await authFetch(
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
+
const res = await authFetch(
|
|
257
|
+
`/api/doctor/cards/${encodeURIComponent(String(cardId || ""))}/status`,
|
|
258
|
+
{
|
|
259
|
+
method: "POST",
|
|
260
|
+
headers: { "Content-Type": "application/json" },
|
|
261
|
+
body: JSON.stringify({ status: String(status || "") }),
|
|
262
|
+
},
|
|
263
|
+
);
|
|
256
264
|
return parseJsonOrThrow(res, "Could not update Doctor card status");
|
|
257
265
|
};
|
|
258
266
|
|
|
@@ -295,114 +303,122 @@ export const sendAgentMessage = async ({
|
|
|
295
303
|
};
|
|
296
304
|
|
|
297
305
|
export async function restartGateway() {
|
|
298
|
-
const res = await authFetch(
|
|
299
|
-
return parseJsonOrThrow(res,
|
|
306
|
+
const res = await authFetch("/api/gateway/restart", { method: "POST" });
|
|
307
|
+
return parseJsonOrThrow(res, "Could not restart gateway");
|
|
300
308
|
}
|
|
301
309
|
|
|
302
310
|
export async function fetchRestartStatus() {
|
|
303
|
-
const res = await authFetch(
|
|
304
|
-
return parseJsonOrThrow(res,
|
|
311
|
+
const res = await authFetch("/api/restart-status");
|
|
312
|
+
return parseJsonOrThrow(res, "Could not load restart status");
|
|
305
313
|
}
|
|
306
314
|
|
|
307
315
|
export async function fetchWatchdogStatus() {
|
|
308
|
-
const res = await authFetch(
|
|
309
|
-
return parseJsonOrThrow(res,
|
|
316
|
+
const res = await authFetch("/api/watchdog/status");
|
|
317
|
+
return parseJsonOrThrow(res, "Could not load watchdog status");
|
|
310
318
|
}
|
|
311
319
|
|
|
312
320
|
export async function fetchUsageSummary(days = 30) {
|
|
313
321
|
const params = new URLSearchParams({ days: String(days) });
|
|
314
322
|
const res = await authFetch(`/api/usage/summary?${params.toString()}`);
|
|
315
|
-
return parseJsonOrThrow(res,
|
|
323
|
+
return parseJsonOrThrow(res, "Could not load usage summary");
|
|
316
324
|
}
|
|
317
325
|
|
|
318
326
|
export async function fetchUsageSessions(limit = 50) {
|
|
319
327
|
const params = new URLSearchParams({ limit: String(limit) });
|
|
320
328
|
const res = await authFetch(`/api/usage/sessions?${params.toString()}`);
|
|
321
|
-
return parseJsonOrThrow(res,
|
|
329
|
+
return parseJsonOrThrow(res, "Could not load usage sessions");
|
|
322
330
|
}
|
|
323
331
|
|
|
324
332
|
export async function fetchUsageSessionDetail(sessionId) {
|
|
325
|
-
const res = await authFetch(
|
|
326
|
-
|
|
333
|
+
const res = await authFetch(
|
|
334
|
+
`/api/usage/sessions/${encodeURIComponent(String(sessionId || ""))}`,
|
|
335
|
+
);
|
|
336
|
+
return parseJsonOrThrow(res, "Could not load usage session detail");
|
|
327
337
|
}
|
|
328
338
|
|
|
329
339
|
export async function fetchUsageSessionTimeSeries(sessionId, maxPoints = 100) {
|
|
330
340
|
const params = new URLSearchParams({ maxPoints: String(maxPoints) });
|
|
331
|
-
const safeSessionId = encodeURIComponent(String(sessionId ||
|
|
332
|
-
const res = await authFetch(
|
|
333
|
-
|
|
341
|
+
const safeSessionId = encodeURIComponent(String(sessionId || ""));
|
|
342
|
+
const res = await authFetch(
|
|
343
|
+
`/api/usage/sessions/${safeSessionId}/timeseries?${params.toString()}`,
|
|
344
|
+
);
|
|
345
|
+
return parseJsonOrThrow(res, "Could not load usage time series");
|
|
334
346
|
}
|
|
335
347
|
|
|
336
348
|
export async function fetchWatchdogEvents(limit = 20) {
|
|
337
|
-
const res = await authFetch(
|
|
338
|
-
|
|
349
|
+
const res = await authFetch(
|
|
350
|
+
`/api/watchdog/events?limit=${encodeURIComponent(String(limit))}`,
|
|
351
|
+
);
|
|
352
|
+
return parseJsonOrThrow(res, "Could not load watchdog events");
|
|
339
353
|
}
|
|
340
354
|
|
|
341
355
|
export async function fetchWatchdogLogs(tail = 65536) {
|
|
342
|
-
const res = await authFetch(
|
|
343
|
-
|
|
356
|
+
const res = await authFetch(
|
|
357
|
+
`/api/watchdog/logs?tail=${encodeURIComponent(String(tail))}`,
|
|
358
|
+
);
|
|
359
|
+
if (!res.ok) throw new Error("Could not load watchdog logs");
|
|
344
360
|
return res.text();
|
|
345
361
|
}
|
|
346
362
|
|
|
347
363
|
export async function triggerWatchdogRepair() {
|
|
348
|
-
const res = await authFetch(
|
|
349
|
-
return parseJsonOrThrow(res,
|
|
364
|
+
const res = await authFetch("/api/watchdog/repair", { method: "POST" });
|
|
365
|
+
return parseJsonOrThrow(res, "Could not trigger watchdog repair");
|
|
350
366
|
}
|
|
351
367
|
|
|
352
368
|
export async function fetchWatchdogResources() {
|
|
353
|
-
const res = await authFetch(
|
|
354
|
-
return parseJsonOrThrow(res,
|
|
369
|
+
const res = await authFetch("/api/watchdog/resources");
|
|
370
|
+
return parseJsonOrThrow(res, "Could not load system resources");
|
|
355
371
|
}
|
|
356
372
|
|
|
357
373
|
export async function fetchWatchdogSettings() {
|
|
358
|
-
const res = await authFetch(
|
|
359
|
-
return parseJsonOrThrow(res,
|
|
374
|
+
const res = await authFetch("/api/watchdog/settings");
|
|
375
|
+
return parseJsonOrThrow(res, "Could not load watchdog settings");
|
|
360
376
|
}
|
|
361
377
|
|
|
362
378
|
export async function updateWatchdogSettings(settings) {
|
|
363
|
-
const res = await authFetch(
|
|
364
|
-
method:
|
|
365
|
-
headers: {
|
|
379
|
+
const res = await authFetch("/api/watchdog/settings", {
|
|
380
|
+
method: "PUT",
|
|
381
|
+
headers: { "Content-Type": "application/json" },
|
|
366
382
|
body: JSON.stringify(settings || {}),
|
|
367
383
|
});
|
|
368
|
-
return parseJsonOrThrow(res,
|
|
384
|
+
return parseJsonOrThrow(res, "Could not update watchdog settings");
|
|
369
385
|
}
|
|
370
386
|
|
|
371
387
|
export async function fetchDashboardUrl() {
|
|
372
|
-
const res = await authFetch(
|
|
388
|
+
const res = await authFetch("/api/gateway/dashboard");
|
|
373
389
|
return res.json();
|
|
374
390
|
}
|
|
375
391
|
|
|
376
392
|
export async function fetchOpenclawVersion(refresh = false) {
|
|
377
|
-
const query = refresh ?
|
|
393
|
+
const query = refresh ? "?refresh=1" : "";
|
|
378
394
|
const res = await authFetch(`/api/openclaw/version${query}`);
|
|
379
395
|
return res.json();
|
|
380
396
|
}
|
|
381
397
|
|
|
382
398
|
export async function updateOpenclaw() {
|
|
383
|
-
const res = await authFetch(
|
|
399
|
+
const res = await authFetch("/api/openclaw/update", { method: "POST" });
|
|
384
400
|
return res.json();
|
|
385
401
|
}
|
|
386
402
|
|
|
387
403
|
export async function fetchAlphaclawVersion(refresh = false) {
|
|
388
|
-
const query = refresh ?
|
|
404
|
+
const query = refresh ? "?refresh=1" : "";
|
|
389
405
|
const res = await authFetch(`/api/alphaclaw/version${query}`);
|
|
390
406
|
return res.json();
|
|
391
407
|
}
|
|
392
408
|
|
|
393
409
|
export async function updateAlphaclaw() {
|
|
394
|
-
const res = await authFetch(
|
|
410
|
+
const res = await authFetch("/api/alphaclaw/update", { method: "POST" });
|
|
395
411
|
return res.json();
|
|
396
412
|
}
|
|
397
413
|
|
|
398
414
|
export async function fetchSyncCron() {
|
|
399
|
-
const res = await authFetch(
|
|
415
|
+
const res = await authFetch("/api/sync-cron");
|
|
400
416
|
const text = await res.text();
|
|
401
417
|
let data;
|
|
402
418
|
try {
|
|
403
419
|
data = text ? JSON.parse(text) : {};
|
|
404
420
|
} catch {
|
|
405
|
-
throw new Error(text ||
|
|
421
|
+
throw new Error(text || "Could not parse sync cron response");
|
|
406
422
|
}
|
|
407
423
|
if (!res.ok) {
|
|
408
424
|
throw new Error(data.error || text || `HTTP ${res.status}`);
|
|
@@ -411,9 +427,9 @@ export async function fetchSyncCron() {
|
|
|
411
427
|
}
|
|
412
428
|
|
|
413
429
|
export async function updateSyncCron(payload) {
|
|
414
|
-
const res = await authFetch(
|
|
415
|
-
method:
|
|
416
|
-
headers: {
|
|
430
|
+
const res = await authFetch("/api/sync-cron", {
|
|
431
|
+
method: "PUT",
|
|
432
|
+
headers: { "Content-Type": "application/json" },
|
|
417
433
|
body: JSON.stringify(payload),
|
|
418
434
|
});
|
|
419
435
|
const text = await res.text();
|
|
@@ -421,7 +437,7 @@ export async function updateSyncCron(payload) {
|
|
|
421
437
|
try {
|
|
422
438
|
data = text ? JSON.parse(text) : {};
|
|
423
439
|
} catch {
|
|
424
|
-
throw new Error(text ||
|
|
440
|
+
throw new Error(text || "Could not parse sync cron response");
|
|
425
441
|
}
|
|
426
442
|
if (!res.ok) {
|
|
427
443
|
throw new Error(data.error || text || `HTTP ${res.status}`);
|
|
@@ -430,135 +446,176 @@ export async function updateSyncCron(payload) {
|
|
|
430
446
|
}
|
|
431
447
|
|
|
432
448
|
export async function fetchDevicePairings() {
|
|
433
|
-
const res = await authFetch(
|
|
449
|
+
const res = await authFetch("/api/devices");
|
|
434
450
|
return res.json();
|
|
435
451
|
}
|
|
436
452
|
|
|
437
453
|
export async function approveDevice(id) {
|
|
438
|
-
const res = await authFetch(`/api/devices/${id}/approve`, { method:
|
|
454
|
+
const res = await authFetch(`/api/devices/${id}/approve`, { method: "POST" });
|
|
439
455
|
return res.json();
|
|
440
456
|
}
|
|
441
457
|
|
|
442
458
|
export async function rejectDevice(id) {
|
|
443
|
-
const res = await authFetch(`/api/devices/${id}/reject`, { method:
|
|
459
|
+
const res = await authFetch(`/api/devices/${id}/reject`, { method: "POST" });
|
|
444
460
|
return res.json();
|
|
445
461
|
}
|
|
446
462
|
|
|
447
463
|
export const fetchAuthStatus = async () => {
|
|
448
|
-
const res = await authFetch(
|
|
464
|
+
const res = await authFetch("/api/auth/status");
|
|
449
465
|
return res.json();
|
|
450
466
|
};
|
|
451
467
|
|
|
452
468
|
export const logout = async () => {
|
|
453
|
-
const res = await authFetch(
|
|
469
|
+
const res = await authFetch("/api/auth/logout", { method: "POST" });
|
|
454
470
|
return res.json();
|
|
455
471
|
};
|
|
456
472
|
|
|
457
473
|
export async function fetchOnboardStatus() {
|
|
458
|
-
const res = await authFetch(
|
|
474
|
+
const res = await authFetch("/api/onboard/status");
|
|
475
|
+
return res.json();
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
export async function runOnboard(vars, modelKey, { importMode = false } = {}) {
|
|
479
|
+
const res = await authFetch("/api/onboard", {
|
|
480
|
+
method: "POST",
|
|
481
|
+
headers: { "Content-Type": "application/json" },
|
|
482
|
+
body: JSON.stringify({ vars, modelKey, importMode }),
|
|
483
|
+
});
|
|
484
|
+
return res.json();
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
export async function verifyGithubOnboardingRepo(repo, token, mode = "new") {
|
|
488
|
+
const res = await authFetch("/api/onboard/github/verify", {
|
|
489
|
+
method: "POST",
|
|
490
|
+
headers: { "Content-Type": "application/json" },
|
|
491
|
+
body: JSON.stringify({ repo, token, mode }),
|
|
492
|
+
});
|
|
459
493
|
return res.json();
|
|
460
494
|
}
|
|
461
495
|
|
|
462
|
-
export async function
|
|
463
|
-
const res = await authFetch(
|
|
464
|
-
method:
|
|
465
|
-
headers: {
|
|
466
|
-
body: JSON.stringify({
|
|
496
|
+
export async function scanImportRepo(tempDir) {
|
|
497
|
+
const res = await authFetch("/api/onboard/import/scan", {
|
|
498
|
+
method: "POST",
|
|
499
|
+
headers: { "Content-Type": "application/json" },
|
|
500
|
+
body: JSON.stringify({ tempDir }),
|
|
467
501
|
});
|
|
468
502
|
return res.json();
|
|
469
503
|
}
|
|
470
504
|
|
|
471
|
-
export async function
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
505
|
+
export async function applyImport({
|
|
506
|
+
tempDir,
|
|
507
|
+
approvedSecrets = [],
|
|
508
|
+
skipSecretExtraction = false,
|
|
509
|
+
githubRepo = "",
|
|
510
|
+
githubToken = "",
|
|
511
|
+
}) {
|
|
512
|
+
const res = await authFetch("/api/onboard/import/apply", {
|
|
513
|
+
method: "POST",
|
|
514
|
+
headers: { "Content-Type": "application/json" },
|
|
515
|
+
body: JSON.stringify({
|
|
516
|
+
tempDir,
|
|
517
|
+
approvedSecrets,
|
|
518
|
+
skipSecretExtraction,
|
|
519
|
+
githubRepo,
|
|
520
|
+
githubToken,
|
|
521
|
+
}),
|
|
476
522
|
});
|
|
477
523
|
return res.json();
|
|
478
524
|
}
|
|
479
525
|
|
|
480
526
|
export const fetchModels = async () => {
|
|
481
|
-
const res = await authFetch(
|
|
527
|
+
const res = await authFetch("/api/models");
|
|
482
528
|
return res.json();
|
|
483
529
|
};
|
|
484
530
|
|
|
485
531
|
export const fetchModelStatus = async () => {
|
|
486
|
-
const res = await authFetch(
|
|
532
|
+
const res = await authFetch("/api/models/status");
|
|
487
533
|
return res.json();
|
|
488
534
|
};
|
|
489
535
|
|
|
490
536
|
export const setPrimaryModel = async (modelKey) => {
|
|
491
|
-
const res = await authFetch(
|
|
492
|
-
method:
|
|
493
|
-
headers: {
|
|
537
|
+
const res = await authFetch("/api/models/set", {
|
|
538
|
+
method: "POST",
|
|
539
|
+
headers: { "Content-Type": "application/json" },
|
|
494
540
|
body: JSON.stringify({ modelKey }),
|
|
495
541
|
});
|
|
496
542
|
return res.json();
|
|
497
543
|
};
|
|
498
544
|
|
|
499
545
|
export const fetchModelsConfig = async () => {
|
|
500
|
-
const res = await authFetch(
|
|
546
|
+
const res = await authFetch("/api/models/config");
|
|
501
547
|
return res.json();
|
|
502
548
|
};
|
|
503
549
|
|
|
504
|
-
export const saveModelsConfig = async ({
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
550
|
+
export const saveModelsConfig = async ({
|
|
551
|
+
primary,
|
|
552
|
+
configuredModels,
|
|
553
|
+
profiles,
|
|
554
|
+
authOrder,
|
|
555
|
+
}) => {
|
|
556
|
+
const res = await authFetch("/api/models/config", {
|
|
557
|
+
method: "PUT",
|
|
558
|
+
headers: { "Content-Type": "application/json" },
|
|
508
559
|
body: JSON.stringify({ primary, configuredModels, profiles, authOrder }),
|
|
509
560
|
});
|
|
510
561
|
return res.json();
|
|
511
562
|
};
|
|
512
563
|
|
|
513
564
|
export const fetchAuthProfiles = async () => {
|
|
514
|
-
const res = await authFetch(
|
|
565
|
+
const res = await authFetch("/api/models/auth");
|
|
515
566
|
return res.json();
|
|
516
567
|
};
|
|
517
568
|
|
|
518
569
|
export const upsertAuthProfile = async (profileId, credential) => {
|
|
519
|
-
const res = await authFetch(
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
570
|
+
const res = await authFetch(
|
|
571
|
+
`/api/models/auth/${encodeURIComponent(profileId)}`,
|
|
572
|
+
{
|
|
573
|
+
method: "PUT",
|
|
574
|
+
headers: { "Content-Type": "application/json" },
|
|
575
|
+
body: JSON.stringify(credential),
|
|
576
|
+
},
|
|
577
|
+
);
|
|
524
578
|
return res.json();
|
|
525
579
|
};
|
|
526
580
|
|
|
527
581
|
export const deleteAuthProfile = async (profileId) => {
|
|
528
|
-
const res = await authFetch(
|
|
529
|
-
|
|
530
|
-
|
|
582
|
+
const res = await authFetch(
|
|
583
|
+
`/api/models/auth/${encodeURIComponent(profileId)}`,
|
|
584
|
+
{
|
|
585
|
+
method: "DELETE",
|
|
586
|
+
},
|
|
587
|
+
);
|
|
531
588
|
return res.json();
|
|
532
589
|
};
|
|
533
590
|
|
|
534
591
|
export const fetchCodexStatus = async () => {
|
|
535
|
-
const res = await authFetch(
|
|
592
|
+
const res = await authFetch("/api/codex/status");
|
|
536
593
|
return res.json();
|
|
537
594
|
};
|
|
538
595
|
|
|
539
596
|
export const disconnectCodex = async () => {
|
|
540
|
-
const res = await authFetch(
|
|
597
|
+
const res = await authFetch("/api/codex/disconnect", { method: "POST" });
|
|
541
598
|
return res.json();
|
|
542
599
|
};
|
|
543
600
|
|
|
544
601
|
export const exchangeCodexOAuth = async (input) => {
|
|
545
|
-
const res = await authFetch(
|
|
546
|
-
method:
|
|
547
|
-
headers: {
|
|
602
|
+
const res = await authFetch("/api/codex/exchange", {
|
|
603
|
+
method: "POST",
|
|
604
|
+
headers: { "Content-Type": "application/json" },
|
|
548
605
|
body: JSON.stringify({ input }),
|
|
549
606
|
});
|
|
550
607
|
return res.json();
|
|
551
608
|
};
|
|
552
609
|
|
|
553
610
|
export async function fetchEnvVars() {
|
|
554
|
-
const res = await authFetch(
|
|
611
|
+
const res = await authFetch("/api/env");
|
|
555
612
|
return res.json();
|
|
556
613
|
}
|
|
557
614
|
|
|
558
615
|
export async function saveEnvVars(vars) {
|
|
559
|
-
const res = await authFetch(
|
|
560
|
-
method:
|
|
561
|
-
headers: {
|
|
616
|
+
const res = await authFetch("/api/env", {
|
|
617
|
+
method: "PUT",
|
|
618
|
+
headers: { "Content-Type": "application/json" },
|
|
562
619
|
body: JSON.stringify({ vars }),
|
|
563
620
|
});
|
|
564
621
|
const text = await res.text();
|
|
@@ -566,7 +623,7 @@ export async function saveEnvVars(vars) {
|
|
|
566
623
|
try {
|
|
567
624
|
data = text ? JSON.parse(text) : {};
|
|
568
625
|
} catch {
|
|
569
|
-
throw new Error(text ||
|
|
626
|
+
throw new Error(text || "Could not parse env save response");
|
|
570
627
|
}
|
|
571
628
|
if (!res.ok) {
|
|
572
629
|
throw new Error(data.error || text || `HTTP ${res.status}`);
|
|
@@ -589,107 +646,110 @@ const parseJsonOrThrow = async (res, fallbackError) => {
|
|
|
589
646
|
};
|
|
590
647
|
|
|
591
648
|
export async function fetchWebhooks() {
|
|
592
|
-
const res = await authFetch(
|
|
593
|
-
return parseJsonOrThrow(res,
|
|
649
|
+
const res = await authFetch("/api/webhooks");
|
|
650
|
+
return parseJsonOrThrow(res, "Could not load webhooks");
|
|
594
651
|
}
|
|
595
652
|
|
|
596
653
|
export async function fetchWebhookDetail(name) {
|
|
597
654
|
const res = await authFetch(`/api/webhooks/${encodeURIComponent(name)}`);
|
|
598
|
-
return parseJsonOrThrow(res,
|
|
655
|
+
return parseJsonOrThrow(res, "Could not load webhook detail");
|
|
599
656
|
}
|
|
600
657
|
|
|
601
658
|
export async function createWebhook(name) {
|
|
602
|
-
const res = await authFetch(
|
|
603
|
-
method:
|
|
604
|
-
headers: {
|
|
659
|
+
const res = await authFetch("/api/webhooks", {
|
|
660
|
+
method: "POST",
|
|
661
|
+
headers: { "Content-Type": "application/json" },
|
|
605
662
|
body: JSON.stringify({ name }),
|
|
606
663
|
});
|
|
607
|
-
return parseJsonOrThrow(res,
|
|
664
|
+
return parseJsonOrThrow(res, "Could not create webhook");
|
|
608
665
|
}
|
|
609
666
|
|
|
610
667
|
export async function deleteWebhook(name, { deleteTransformDir = false } = {}) {
|
|
611
668
|
const res = await authFetch(`/api/webhooks/${encodeURIComponent(name)}`, {
|
|
612
|
-
method:
|
|
613
|
-
headers: {
|
|
669
|
+
method: "DELETE",
|
|
670
|
+
headers: { "Content-Type": "application/json" },
|
|
614
671
|
body: JSON.stringify({ deleteTransformDir: !!deleteTransformDir }),
|
|
615
672
|
});
|
|
616
|
-
return parseJsonOrThrow(res,
|
|
673
|
+
return parseJsonOrThrow(res, "Could not delete webhook");
|
|
617
674
|
}
|
|
618
675
|
|
|
619
|
-
export async function fetchWebhookRequests(
|
|
676
|
+
export async function fetchWebhookRequests(
|
|
677
|
+
name,
|
|
678
|
+
{ limit = 50, offset = 0, status = "all" } = {},
|
|
679
|
+
) {
|
|
620
680
|
const params = new URLSearchParams({
|
|
621
681
|
limit: String(limit),
|
|
622
682
|
offset: String(offset),
|
|
623
|
-
status: String(status ||
|
|
683
|
+
status: String(status || "all"),
|
|
624
684
|
});
|
|
625
685
|
const res = await authFetch(
|
|
626
686
|
`/api/webhooks/${encodeURIComponent(name)}/requests?${params.toString()}`,
|
|
627
687
|
);
|
|
628
|
-
return parseJsonOrThrow(res,
|
|
688
|
+
return parseJsonOrThrow(res, "Could not load webhook requests");
|
|
629
689
|
}
|
|
630
690
|
|
|
631
691
|
export async function fetchWebhookRequest(name, id) {
|
|
632
692
|
const res = await authFetch(
|
|
633
693
|
`/api/webhooks/${encodeURIComponent(name)}/requests/${encodeURIComponent(String(id))}`,
|
|
634
694
|
);
|
|
635
|
-
return parseJsonOrThrow(res,
|
|
695
|
+
return parseJsonOrThrow(res, "Could not load webhook request");
|
|
636
696
|
}
|
|
637
697
|
|
|
638
698
|
export const fetchBrowseTree = async (depth = 10) => {
|
|
639
699
|
const params = new URLSearchParams({ depth: String(depth) });
|
|
640
700
|
const res = await authFetch(`/api/browse/tree?${params.toString()}`);
|
|
641
|
-
return parseJsonOrThrow(res,
|
|
701
|
+
return parseJsonOrThrow(res, "Could not load file tree");
|
|
642
702
|
};
|
|
643
703
|
|
|
644
704
|
export const fetchFileContent = async (filePath) => {
|
|
645
|
-
const params = new URLSearchParams({ path: String(filePath ||
|
|
705
|
+
const params = new URLSearchParams({ path: String(filePath || "") });
|
|
646
706
|
const res = await authFetch(`/api/browse/read?${params.toString()}`);
|
|
647
|
-
return parseJsonOrThrow(res,
|
|
707
|
+
return parseJsonOrThrow(res, "Could not load file content");
|
|
648
708
|
};
|
|
649
709
|
|
|
650
710
|
export const saveFileContent = async (filePath, content) => {
|
|
651
|
-
const res = await authFetch(
|
|
652
|
-
method:
|
|
653
|
-
headers: {
|
|
711
|
+
const res = await authFetch("/api/browse/write", {
|
|
712
|
+
method: "PUT",
|
|
713
|
+
headers: { "Content-Type": "application/json" },
|
|
654
714
|
body: JSON.stringify({ path: filePath, content }),
|
|
655
715
|
});
|
|
656
|
-
return parseJsonOrThrow(res,
|
|
716
|
+
return parseJsonOrThrow(res, "Could not save file");
|
|
657
717
|
};
|
|
658
718
|
|
|
659
719
|
export const createBrowseFile = async (filePath) => {
|
|
660
|
-
const res = await authFetch(
|
|
661
|
-
method:
|
|
662
|
-
headers: {
|
|
663
|
-
body: JSON.stringify({ path: String(filePath ||
|
|
720
|
+
const res = await authFetch("/api/browse/create-file", {
|
|
721
|
+
method: "POST",
|
|
722
|
+
headers: { "Content-Type": "application/json" },
|
|
723
|
+
body: JSON.stringify({ path: String(filePath || "") }),
|
|
664
724
|
});
|
|
665
|
-
return parseJsonOrThrow(res,
|
|
725
|
+
return parseJsonOrThrow(res, "Could not create file");
|
|
666
726
|
};
|
|
667
727
|
|
|
668
728
|
export const createBrowseFolder = async (folderPath) => {
|
|
669
|
-
const res = await authFetch(
|
|
670
|
-
method:
|
|
671
|
-
headers: {
|
|
672
|
-
body: JSON.stringify({ path: String(folderPath ||
|
|
729
|
+
const res = await authFetch("/api/browse/create-folder", {
|
|
730
|
+
method: "POST",
|
|
731
|
+
headers: { "Content-Type": "application/json" },
|
|
732
|
+
body: JSON.stringify({ path: String(folderPath || "") }),
|
|
673
733
|
});
|
|
674
|
-
return parseJsonOrThrow(res,
|
|
734
|
+
return parseJsonOrThrow(res, "Could not create folder");
|
|
675
735
|
};
|
|
676
736
|
|
|
677
737
|
export const moveBrowsePath = async (from, to) => {
|
|
678
|
-
const res = await authFetch(
|
|
679
|
-
method:
|
|
680
|
-
headers: {
|
|
681
|
-
body: JSON.stringify({ from: String(from ||
|
|
738
|
+
const res = await authFetch("/api/browse/move", {
|
|
739
|
+
method: "POST",
|
|
740
|
+
headers: { "Content-Type": "application/json" },
|
|
741
|
+
body: JSON.stringify({ from: String(from || ""), to: String(to || "") }),
|
|
682
742
|
});
|
|
683
|
-
return parseJsonOrThrow(res,
|
|
743
|
+
return parseJsonOrThrow(res, "Could not move path");
|
|
684
744
|
};
|
|
685
745
|
|
|
686
746
|
export const deleteBrowseFile = async (filePath) => {
|
|
687
|
-
const res = await authFetch(
|
|
688
|
-
method:
|
|
689
|
-
headers: {
|
|
690
|
-
body: JSON.stringify({ path: String(filePath ||
|
|
747
|
+
const res = await authFetch("/api/browse/delete", {
|
|
748
|
+
method: "DELETE",
|
|
749
|
+
headers: { "Content-Type": "application/json" },
|
|
750
|
+
body: JSON.stringify({ path: String(filePath || "") }),
|
|
691
751
|
});
|
|
692
|
-
return parseJsonOrThrow(res,
|
|
752
|
+
return parseJsonOrThrow(res, "Could not delete file");
|
|
693
753
|
};
|
|
694
754
|
|
|
695
755
|
export const downloadBrowseFile = async (filePath) => {
|
|
@@ -724,23 +784,23 @@ export const downloadBrowseFile = async (filePath) => {
|
|
|
724
784
|
};
|
|
725
785
|
|
|
726
786
|
export const restoreBrowseFile = async (filePath) => {
|
|
727
|
-
const res = await authFetch(
|
|
728
|
-
method:
|
|
729
|
-
headers: {
|
|
730
|
-
body: JSON.stringify({ path: String(filePath ||
|
|
787
|
+
const res = await authFetch("/api/browse/restore", {
|
|
788
|
+
method: "POST",
|
|
789
|
+
headers: { "Content-Type": "application/json" },
|
|
790
|
+
body: JSON.stringify({ path: String(filePath || "") }),
|
|
731
791
|
});
|
|
732
|
-
return parseJsonOrThrow(res,
|
|
792
|
+
return parseJsonOrThrow(res, "Could not restore file");
|
|
733
793
|
};
|
|
734
794
|
|
|
735
795
|
export const fetchBrowseGitSummary = async () => {
|
|
736
|
-
const res = await authFetch(
|
|
737
|
-
return parseJsonOrThrow(res,
|
|
796
|
+
const res = await authFetch("/api/browse/git-summary");
|
|
797
|
+
return parseJsonOrThrow(res, "Could not load git summary");
|
|
738
798
|
};
|
|
739
799
|
|
|
740
800
|
export const fetchBrowseFileDiff = async (filePath) => {
|
|
741
801
|
const params = new URLSearchParams({ path: String(filePath || "") });
|
|
742
802
|
const res = await authFetch(`/api/browse/git-diff?${params.toString()}`);
|
|
743
|
-
return parseJsonOrThrow(res,
|
|
803
|
+
return parseJsonOrThrow(res, "Could not load file diff");
|
|
744
804
|
};
|
|
745
805
|
|
|
746
806
|
export const fetchBrowseSqliteTable = async ({
|
|
@@ -760,10 +820,10 @@ export const fetchBrowseSqliteTable = async ({
|
|
|
760
820
|
};
|
|
761
821
|
|
|
762
822
|
export const syncBrowseChanges = async (message = "") => {
|
|
763
|
-
const res = await authFetch(
|
|
764
|
-
method:
|
|
765
|
-
headers: {
|
|
823
|
+
const res = await authFetch("/api/browse/git-sync", {
|
|
824
|
+
method: "POST",
|
|
825
|
+
headers: { "Content-Type": "application/json" },
|
|
766
826
|
body: JSON.stringify({ message: String(message || "") }),
|
|
767
827
|
});
|
|
768
|
-
return parseJsonOrThrow(res,
|
|
828
|
+
return parseJsonOrThrow(res, "Could not sync changes");
|
|
769
829
|
};
|