@idapt/browser-app-sdk 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.cjs CHANGED
@@ -345,15 +345,6 @@ async function moveFile(ctx, id, parentId, opts = {}) {
345
345
  });
346
346
  return res.data;
347
347
  }
348
- async function runFile(ctx, id, input = {}, opts = {}) {
349
- const res = await request(ctx, {
350
- method: "POST",
351
- path: `/api/v1/drive/files/${id}/run`,
352
- body: input,
353
- signal: opts.signal
354
- });
355
- return res.data;
356
- }
357
348
 
358
349
  // ../sdk/src/api/agents.ts
359
350
  var AgentsApi = class {
@@ -519,251 +510,168 @@ var AudioApi = class {
519
510
  constructor(ctx) {
520
511
  this.ctx = ctx;
521
512
  }
522
- /** Text-to-speech. Responds HTTP 201 with the written file ref under `data`. */
523
- async speak(input, opts = {}) {
513
+ /** List the available TTS / transcription models. */
514
+ async listModels(opts = {}) {
524
515
  const res = await request(this.ctx, {
525
- method: "POST",
526
- path: "/api/v1/audio/speech",
527
- body: input,
516
+ method: "GET",
517
+ path: "/api/v1/audio/models",
528
518
  signal: opts.signal
529
519
  });
530
520
  return res.data;
531
521
  }
532
- async transcribe(input, opts = {}) {
533
- const form = new FormData();
534
- const filename = input.filename ?? (input.file instanceof File ? input.file.name : "audio");
535
- form.set("file", input.file, filename);
536
- if (input.model) form.set("model", input.model);
537
- if (input.language) form.set("language", input.language);
522
+ /** List the TTS voice catalog (filter by language / gender). */
523
+ async listVoices(input = {}, opts = {}) {
538
524
  const res = await request(this.ctx, {
539
- method: "POST",
540
- path: "/api/v1/audio/transcriptions",
541
- bodyRaw: form,
525
+ method: "GET",
526
+ path: "/api/v1/audio/voices",
527
+ query: input,
542
528
  signal: opts.signal
543
529
  });
544
530
  return res.data;
545
531
  }
546
- async *streamSpeech(input, opts = {}) {
547
- const res = await requestRaw(this.ctx, {
548
- method: "POST",
549
- path: "/api/v1/audio/speech/stream",
550
- body: input,
551
- signal: opts.signal,
552
- expectJson: false
553
- });
554
- yield* parseSpeechStream(res, opts.signal);
555
- }
556
- async *streamTranscribe(input, opts = {}) {
557
- const form = new FormData();
558
- const filename = input.filename ?? (input.file instanceof File ? input.file.name : "audio");
559
- form.set("file", input.file, filename);
560
- if (input.model) form.set("model", input.model);
561
- if (input.language) form.set("language", input.language);
562
- const res = await requestRaw(this.ctx, {
563
- method: "POST",
564
- path: "/api/v1/audio/transcriptions/stream",
565
- bodyRaw: form,
566
- signal: opts.signal,
567
- expectJson: false
568
- });
569
- yield* parseTranscriptionStream(res, opts.signal);
570
- }
571
532
  };
572
- async function* parseSpeechStream(response, signal) {
573
- for await (const frame of parseSse(response, signal)) {
574
- const payload = safeJson(frame.data);
575
- if (frame.event === "chunk") {
576
- const audio = payload?.audio;
577
- if (typeof audio === "string") yield { type: "chunk", audio };
578
- } else if (frame.event === "done") {
579
- const event = { type: "done" };
580
- const totalBytes = numberOrUndefined(payload?.totalBytes);
581
- const durationMs = numberOrUndefined(payload?.durationMs);
582
- const charCount = numberOrUndefined(payload?.charCount);
583
- if (totalBytes !== void 0) event.total_bytes = totalBytes;
584
- if (durationMs !== void 0) event.duration_ms = durationMs;
585
- if (charCount !== void 0) event.char_count = charCount;
586
- if (typeof payload?.cached === "boolean") event.cached = payload.cached;
587
- yield event;
588
- } else if (frame.event === "error") {
589
- yield errorEvent(payload);
590
- }
591
- }
592
- }
593
- async function* parseTranscriptionStream(response, signal) {
594
- for await (const frame of parseSse(response, signal)) {
595
- const payload = safeJson(frame.data);
596
- if (frame.event === "partial") {
597
- const text = payload?.text;
598
- if (typeof text === "string") yield { type: "partial", text };
599
- } else if (frame.event === "final") {
600
- const text = payload?.text;
601
- if (typeof text === "string") yield { type: "final", text };
602
- } else if (frame.event === "error") {
603
- yield errorEvent(payload);
604
- }
605
- }
606
- }
607
- async function* parseSse(response, signal) {
608
- if (!response.body) return;
609
- const reader = response.body.getReader();
610
- const decoder = new TextDecoder();
611
- let buffer = "";
612
- try {
613
- while (true) {
614
- if (signal?.aborted) return;
615
- const { done, value } = await reader.read();
616
- if (done) break;
617
- buffer += decoder.decode(value, { stream: true }).replace(/\r\n/g, "\n");
618
- while (true) {
619
- const boundary = buffer.indexOf("\n\n");
620
- if (boundary === -1) break;
621
- const block = buffer.slice(0, boundary);
622
- buffer = buffer.slice(boundary + 2);
623
- const parsed = parseSseBlock(block);
624
- if (parsed) yield parsed;
625
- }
626
- }
627
- } finally {
628
- try {
629
- reader.releaseLock();
630
- } catch {
631
- }
632
- }
633
- }
634
- function parseSseBlock(block) {
635
- let event = "message";
636
- let data = "";
637
- for (const line of block.split("\n")) {
638
- if (!line) continue;
639
- if (line.startsWith("event: ")) event = line.slice(7).trim();
640
- else if (line.startsWith("event:")) event = line.slice(6).trim();
641
- else if (line.startsWith("data: ")) data += line.slice(6);
642
- else if (line.startsWith("data:")) data += line.slice(5);
643
- }
644
- if (!data && event === "message") return null;
645
- return { event, data };
646
- }
647
- function safeJson(raw) {
648
- try {
649
- return JSON.parse(raw);
650
- } catch {
651
- return null;
652
- }
653
- }
654
- function numberOrUndefined(value) {
655
- return typeof value === "number" && Number.isFinite(value) ? value : void 0;
656
- }
657
- function errorEvent(payload) {
658
- const event = {
659
- type: "error"
660
- };
661
- const status = numberOrUndefined(payload?.status);
662
- const retryAfter = numberOrUndefined(payload?.retryAfter);
663
- if (status !== void 0) event.status = status;
664
- if (retryAfter !== void 0) event.retry_after = retryAfter;
665
- return event;
666
- }
667
533
 
668
- // ../sdk/src/api/blobs.ts
669
- var enc = encodeURIComponent;
670
- var BlobsApi = class {
534
+ // ../sdk/src/api/automations.ts
535
+ var AutomationsApi = class {
671
536
  constructor(ctx) {
672
537
  this.ctx = ctx;
673
538
  }
674
- /** List objects in a namespace (prefix-filterable). */
675
- async list(namespace, opts = {}) {
676
- const q = new URLSearchParams();
677
- if (opts.prefix) q.set("prefix", opts.prefix);
678
- if (opts.cursor) q.set("cursor", opts.cursor);
679
- if (opts.limit) q.set("limit", String(opts.limit));
680
- const qs = q.toString() ? `?${q.toString()}` : "";
539
+ // ---------------------------------------------------------------------------
540
+ // CRUD
541
+ // ---------------------------------------------------------------------------
542
+ async list(query = {}, opts = {}) {
681
543
  const res = await request(this.ctx, {
682
544
  method: "GET",
683
- path: `/api/v1/blobs/${enc(namespace)}${qs}`,
545
+ path: "/api/v1/automations",
546
+ query,
684
547
  signal: opts.signal
685
548
  });
686
549
  return res.data;
687
550
  }
688
551
  /**
689
- * Upload (upsert) an object's bytes. Returns its metadata.
552
+ * Create an automation. `workspace_id` is passed in the request BODY
553
+ * alongside the flat automation definition — it is not a query param. The request
554
+ * body is flat: every scheduling field (`cron_expression`, …) and agent-run
555
+ * action field (`agent_id`, `prompt_template`, …) sits at the top level —
556
+ * there are no nested `trigger_config` / `action_config` objects.
690
557
  *
691
- * Sent as `multipart/form-data` (the bytes ride a `file` part, with an
692
- * optional `content_type` field) the same upload convention as
693
- * `client.files.upload`, so it flows through the one multipart transport and
694
- * is reachable identically via `client.call("blobs put", …)`. The SDK leaves
695
- * `Content-Type` unset so the runtime picks the multipart boundary.
558
+ * For a webhook automation the response additionally carries a one-time
559
+ * plaintext `secret` (use `AutomationWithSecret`); other automation types
560
+ * resolve to a plain `Automation`.
696
561
  */
697
- async put(namespace, key, content, contentType, opts = {}) {
698
- const ct = contentType ?? (content instanceof Blob && content.type ? content.type : "application/octet-stream");
699
- const blob = content instanceof Blob ? content : new Blob([content], { type: ct });
700
- const form = new FormData();
701
- form.set("file", blob, key);
702
- form.set("content_type", ct);
562
+ async create(workspaceId, input, opts = {}) {
703
563
  const res = await request(this.ctx, {
704
564
  method: "POST",
705
- path: `/api/v1/blobs/${enc(namespace)}/${enc(key)}`,
706
- // No explicit Content-Type the runtime sets the multipart boundary.
707
- bodyRaw: form,
565
+ path: "/api/v1/automations",
566
+ body: { workspace_id: workspaceId, ...input },
708
567
  signal: opts.signal
709
568
  });
710
569
  return res.data;
711
570
  }
712
- /**
713
- * Download an object's raw bytes (preserving its stored Content-Type).
714
- *
715
- * `GET /blobs/:ns/:key` returns JSON metadata + a signed URL by default (the
716
- * agent/CLI form); `?download=true` is the raw-bytes escape hatch this facade
717
- * uses. For the JSON reference instead, call `client.call("blobs get", …)`.
718
- */
719
- async get(namespace, key, opts = {}) {
720
- const res = await requestRaw(this.ctx, {
571
+ async get(id, opts = {}) {
572
+ const res = await request(this.ctx, {
721
573
  method: "GET",
722
- path: `/api/v1/blobs/${enc(namespace)}/${enc(key)}?download=true`,
723
- signal: opts.signal,
724
- expectJson: false
574
+ path: `/api/v1/automations/${id}`,
575
+ signal: opts.signal
725
576
  });
726
- const blob = await res.blob();
727
- return {
728
- blob,
729
- contentType: res.headers.get("content-type") ?? "application/octet-stream"
730
- };
577
+ return res.data;
731
578
  }
732
- /** Read an object's metadata (no bytes). */
733
- async head(namespace, key, opts = {}) {
579
+ async update(id, input, opts = {}) {
734
580
  const res = await request(this.ctx, {
735
- method: "GET",
736
- path: `/api/v1/blobs/${enc(namespace)}/${enc(key)}/meta`,
581
+ method: "PATCH",
582
+ path: `/api/v1/automations/${id}`,
583
+ body: input,
737
584
  signal: opts.signal
738
585
  });
739
586
  return res.data;
740
587
  }
741
- /** Delete an object (idempotent). */
742
- async delete(namespace, key, opts = {}) {
588
+ async delete(id, opts = {}) {
743
589
  return request(this.ctx, {
744
590
  method: "DELETE",
745
- path: `/api/v1/blobs/${enc(namespace)}/${enc(key)}`,
591
+ path: `/api/v1/automations/${id}`,
592
+ signal: opts.signal
593
+ });
594
+ }
595
+ async archive(id, opts = {}) {
596
+ const res = await request(this.ctx, {
597
+ method: "POST",
598
+ path: `/api/v1/automations/${id}/archive`,
746
599
  signal: opts.signal
747
600
  });
601
+ return res.data;
748
602
  }
749
- /** Mint a time-limited direct-download URL for an object. */
750
- async createSignedUrl(namespace, key, expiresIn, opts = {}) {
603
+ async unarchive(id, opts = {}) {
751
604
  const res = await request(this.ctx, {
752
605
  method: "POST",
753
- path: `/api/v1/blobs/${enc(namespace)}/${enc(key)}/signed-url`,
754
- body: { expires_in: expiresIn },
606
+ path: `/api/v1/automations/${id}/unarchive`,
607
+ signal: opts.signal
608
+ });
609
+ return res.data;
610
+ }
611
+ // ---------------------------------------------------------------------------
612
+ // Fire + rotate-secret + runs
613
+ // ---------------------------------------------------------------------------
614
+ /**
615
+ * Fire an automation via its webhook secret. This endpoint does NOT use the
616
+ * client's `ap_` key — the bearer is the automation's secret — so we build a
617
+ * one-off HttpContext for it rather than mutating the shared one.
618
+ *
619
+ * Responds HTTP 202. The response identifies the fired automation via `id`
620
+ * only.
621
+ */
622
+ async fire(id, input, opts = {}) {
623
+ const localCtx = {
624
+ apiUrl: this.ctx.apiUrl,
625
+ key: input.secret,
626
+ fetch: this.ctx.fetch
627
+ };
628
+ const res = await request(localCtx, {
629
+ method: "POST",
630
+ path: `/api/v1/automations/${id}/fire`,
631
+ body: input.body ?? {},
632
+ signal: opts.signal
633
+ });
634
+ return res.data;
635
+ }
636
+ /**
637
+ * Rotate the webhook secret. Returns the automation with a fresh one-time
638
+ * plaintext `secret` populated (`AutomationWithSecret`). The old secret
639
+ * immediately stops working.
640
+ */
641
+ async rotateSecret(id, opts = {}) {
642
+ const res = await request(this.ctx, {
643
+ method: "POST",
644
+ path: `/api/v1/automations/${id}/rotate-secret`,
645
+ signal: opts.signal
646
+ });
647
+ return res.data;
648
+ }
649
+ /** Recent fires + their success/error outcome. */
650
+ async listRuns(id, query = {}, opts = {}) {
651
+ const res = await request(this.ctx, {
652
+ method: "GET",
653
+ path: `/api/v1/automations/${id}/runs`,
654
+ query,
655
+ signal: opts.signal
656
+ });
657
+ return res.data;
658
+ }
659
+ async getCostStats(id, opts = {}) {
660
+ const res = await request(this.ctx, {
661
+ method: "GET",
662
+ path: `/api/v1/automations/${id}/cost-stats`,
755
663
  signal: opts.signal
756
664
  });
757
665
  return res.data;
758
666
  }
759
- /** List the blob namespaces in the workspace. */
760
- async listNamespaces(opts = {}) {
667
+ async getCostStatsMap(query = {}, opts = {}) {
761
668
  const res = await request(this.ctx, {
762
669
  method: "GET",
763
- path: "/api/v1/blobs",
670
+ path: "/api/v1/automations/cost-stats",
671
+ query,
764
672
  signal: opts.signal
765
673
  });
766
- return res.data.map((n) => n.namespace);
674
+ return res.data.by_id;
767
675
  }
768
676
  };
769
677
  function bindPath(binding, args) {
@@ -815,7 +723,7 @@ function buildRequest(binding, path, rest, signal) {
815
723
  return base;
816
724
  }
817
725
  }
818
- async function* parseSse2(response, signal) {
726
+ async function* parseSse(response, signal) {
819
727
  if (!response.body) return;
820
728
  const reader = response.body.getReader();
821
729
  const decoder = new TextDecoder();
@@ -831,7 +739,7 @@ async function* parseSse2(response, signal) {
831
739
  if (boundary === -1) break;
832
740
  const block = buffer.slice(0, boundary);
833
741
  buffer = buffer.slice(boundary + 2);
834
- const frame = parseSseBlock2(block);
742
+ const frame = parseSseBlock(block);
835
743
  if (frame) yield frame;
836
744
  }
837
745
  }
@@ -842,7 +750,7 @@ async function* parseSse2(response, signal) {
842
750
  }
843
751
  }
844
752
  }
845
- function parseSseBlock2(block) {
753
+ function parseSseBlock(block) {
846
754
  let event = "message";
847
755
  let data = "";
848
756
  for (const line of block.split("\n")) {
@@ -866,7 +774,7 @@ async function executeCommand(binding, args = {}, ctx, opts = {}) {
866
774
  {
867
775
  if (isSseBinding(binding) && !opts.bufferBinary) {
868
776
  const res = await requestRaw(ctx, { ...req, expectJson: false });
869
- return parseSse2(res, opts.signal);
777
+ return parseSse(res, opts.signal);
870
778
  }
871
779
  return await request(ctx, { ...req, expectBlob: true });
872
780
  }
@@ -1240,7 +1148,7 @@ var ComputersApi = class {
1240
1148
  return res.data;
1241
1149
  }
1242
1150
  // ---------------------------------------------------------------------------
1243
- // Exec & tmux
1151
+ // Exec & terminals
1244
1152
  // ---------------------------------------------------------------------------
1245
1153
  async exec(id, input, opts = {}) {
1246
1154
  const res = await request(this.ctx, {
@@ -1252,56 +1160,57 @@ var ComputersApi = class {
1252
1160
  return res.data;
1253
1161
  }
1254
1162
  /**
1255
- * tmux dispatcher. Each `op` returns a different shape — see the route
1256
- * docs for the per-op payload. Common case: `op: "run"` starts a window,
1163
+ * Persistent-terminal dispatcher. Each `op` returns a different shape — see
1164
+ * the route docs for the per-op payload. Common case: `op: "run"` runs a
1165
+ * command to completion in a named window (state persists across runs),
1257
1166
  * `op: "capture"` reads its output.
1258
1167
  */
1259
- async tmux(id, input, opts = {}) {
1168
+ async terminal(id, input, opts = {}) {
1260
1169
  const res = await request(
1261
1170
  this.ctx,
1262
1171
  {
1263
1172
  method: "POST",
1264
- path: `/api/v1/computers/${id}/tmux`,
1173
+ path: `/api/v1/computers/${id}/terminal`,
1265
1174
  body: input,
1266
1175
  signal: opts.signal
1267
1176
  }
1268
1177
  );
1269
1178
  return res.data;
1270
1179
  }
1271
- /** Convenience over `tmux({ op: "list" })`. */
1272
- async listTmuxWindows(id, opts = {}) {
1273
- const result = await this.tmux(id, { op: "list" }, opts);
1180
+ /** Convenience over `terminal({ op: "list" })`. */
1181
+ async listTerminals(id, opts = {}) {
1182
+ const result = await this.terminal(id, { op: "list" }, opts);
1274
1183
  return result.windows ?? [];
1275
1184
  }
1276
1185
  // ---------------------------------------------------------------------------
1277
- // SFTP
1186
+ // FS
1278
1187
  // ---------------------------------------------------------------------------
1279
1188
  /**
1280
- * Unified SFTP dispatcher. Returns op-shaped payload. For streaming
1281
- * uploads/downloads use `sftpUpload` / `sftpDownload`.
1189
+ * Unified FS dispatcher. Returns op-shaped payload. For streaming
1190
+ * uploads/downloads use `fsUpload` / `fsDownload`.
1282
1191
  */
1283
- async sftp(id, input, opts = {}) {
1192
+ async fs(id, input, opts = {}) {
1284
1193
  const res = await request(
1285
1194
  this.ctx,
1286
1195
  {
1287
1196
  method: "POST",
1288
- path: `/api/v1/computers/${id}/sftp`,
1197
+ path: `/api/v1/computers/${id}/fs`,
1289
1198
  body: input,
1290
1199
  signal: opts.signal
1291
1200
  }
1292
1201
  );
1293
1202
  return res.data;
1294
1203
  }
1295
- /** Convenience: `sftp({op:"list"})` returning the entries array directly. */
1296
- async sftpList(id, path, opts = {}) {
1297
- const result = await this.sftp(id, { op: "list", path }, opts);
1204
+ /** Convenience: `fs({op:"list"})` returning the entries array directly. */
1205
+ async fsList(id, path, opts = {}) {
1206
+ const result = await this.fs(id, { op: "list", path }, opts);
1298
1207
  return result;
1299
1208
  }
1300
1209
  /**
1301
1210
  * Multipart upload of a file/folder member. Falls back to single-file mode
1302
1211
  * when `relative_path` is omitted.
1303
1212
  */
1304
- async sftpUpload(id, input, opts = {}) {
1213
+ async fsUpload(id, input, opts = {}) {
1305
1214
  const form = new FormData();
1306
1215
  form.append("file", input.file);
1307
1216
  form.append("path", input.path);
@@ -1311,7 +1220,7 @@ var ComputersApi = class {
1311
1220
  this.ctx,
1312
1221
  {
1313
1222
  method: "POST",
1314
- path: `/api/v1/computers/${id}/sftp/upload`,
1223
+ path: `/api/v1/computers/${id}/fs/upload`,
1315
1224
  bodyRaw: form,
1316
1225
  signal: opts.signal
1317
1226
  }
@@ -1322,10 +1231,10 @@ var ComputersApi = class {
1322
1231
  * Stream a remote file (or a folder as `tar.gz`) as a `Blob`. The server
1323
1232
  * sends the real MIME type on `Content-Type`.
1324
1233
  */
1325
- async sftpDownload(id, remotePath, opts = {}) {
1234
+ async fsDownload(id, remotePath, opts = {}) {
1326
1235
  return request(this.ctx, {
1327
1236
  method: "GET",
1328
- path: `/api/v1/computers/${id}/sftp/download`,
1237
+ path: `/api/v1/computers/${id}/fs/download`,
1329
1238
  query: { path: remotePath },
1330
1239
  expectBlob: true,
1331
1240
  signal: opts.signal
@@ -1493,59 +1402,85 @@ var ComputersApi = class {
1493
1402
  return res.data;
1494
1403
  }
1495
1404
  // ---------------------------------------------------------------------------
1496
- // Workspace links (share LOCAL INFERENCE into other workspaces)
1405
+ // Workspace exposures (expose an actor-owned machine into a workspace) +
1406
+ // ownership transfer
1497
1407
  // ---------------------------------------------------------------------------
1498
1408
  /**
1499
- * List the workspaces a computer's LOCAL INFERENCE is shared into. The home
1500
- * workspace is never listed (it already has full access). The route returns
1501
- * the links under a `links` key (not a standard list envelope).
1409
+ * Expose an actor-owned machine INTO a workspace (Layer 2) with a
1410
+ * per-capability grant, so that workspace's members can use it. Requires
1411
+ * machine-admin and membership of the target workspace. Rejects a duplicate
1412
+ * exposure. (CLI verb: `computer add-exposure` — the bare `expose`/`unexpose`
1413
+ * verbs are the tunnel port commands.)
1502
1414
  */
1503
- async listWorkspaceLinks(id, opts = {}) {
1504
- const res = await request(this.ctx, {
1505
- method: "GET",
1506
- path: `/api/v1/computers/${id}/workspace-links`,
1507
- signal: opts.signal
1508
- });
1509
- return res.data.links;
1415
+ async expose(id, input, opts = {}) {
1416
+ const res = await request(
1417
+ this.ctx,
1418
+ {
1419
+ method: "POST",
1420
+ path: `/api/v1/computers/${id}/expose`,
1421
+ body: input,
1422
+ signal: opts.signal
1423
+ }
1424
+ );
1425
+ return res.data.exposure;
1510
1426
  }
1511
1427
  /**
1512
- * Share a computer's LOCAL INFERENCE into another workspace (never shell /
1513
- * files / tunnels). `workspaceId` is the target workspace's `ws_…`
1514
- * resourceId or slug. Requires EDIT on the computer's home workspace and
1515
- * membership of the target. Rejects the home workspace and duplicates.
1428
+ * Replace the capability grant on an existing exposure. `workspaceId` is the
1429
+ * exposed workspace's `ws_…` resourceId. Requires machine-admin.
1430
+ * (CLI verb: `computer update-exposure`.)
1516
1431
  */
1517
- async linkWorkspace(id, workspaceId, opts = {}) {
1432
+ async updateExposure(id, workspaceId, capabilities, opts = {}) {
1518
1433
  const res = await request(
1519
1434
  this.ctx,
1520
1435
  {
1521
- method: "POST",
1522
- path: `/api/v1/computers/${id}/workspace-links`,
1523
- body: { workspace_id: workspaceId },
1436
+ method: "PATCH",
1437
+ path: `/api/v1/computers/${id}/expose/${workspaceId}`,
1438
+ body: { capabilities },
1524
1439
  signal: opts.signal
1525
1440
  }
1526
1441
  );
1527
- return res.data.link;
1442
+ return res.data.exposure;
1528
1443
  }
1529
1444
  /**
1530
- * Stop sharing a computer's local inference into a workspace. `workspaceId`
1531
- * is the target workspace's `ws_…` resourceId. Idempotent unlinking a
1532
- * non-existent link still succeeds.
1445
+ * Stop exposing a machine into a workspace. `workspaceId` is the exposed
1446
+ * workspace's `ws_…` resourceId. Allowed for machine-admin OR an admin of the
1447
+ * exposed workspace. Idempotent. (CLI verb: `computer remove-exposure`.)
1533
1448
  */
1534
- async unlinkWorkspace(id, workspaceId, opts = {}) {
1535
- const res = await request(this.ctx, {
1536
- method: "DELETE",
1537
- path: `/api/v1/computers/${id}/workspace-links/${workspaceId}`,
1538
- signal: opts.signal
1539
- });
1449
+ async unexpose(id, workspaceId, opts = {}) {
1450
+ const res = await request(
1451
+ this.ctx,
1452
+ {
1453
+ method: "DELETE",
1454
+ path: `/api/v1/computers/${id}/expose/${workspaceId}`,
1455
+ signal: opts.signal
1456
+ }
1457
+ );
1540
1458
  return res.data;
1541
1459
  }
1460
+ /**
1461
+ * Transfer an actor-owned machine to a new owner (self, or an org the caller
1462
+ * administers). `owner` is the target profile's resourceId; existing workspace
1463
+ * exposures are kept. Requires machine-admin. (CLI verb: `computer transfer`.)
1464
+ */
1465
+ async transfer(id, owner, opts = {}) {
1466
+ const res = await request(
1467
+ this.ctx,
1468
+ {
1469
+ method: "POST",
1470
+ path: `/api/v1/computers/${id}/transfer`,
1471
+ body: { owner },
1472
+ signal: opts.signal
1473
+ }
1474
+ );
1475
+ return res.data.computer;
1476
+ }
1542
1477
  // ---------------------------------------------------------------------------
1543
1478
  // Pair-token redemption (daemon bootstrap)
1544
1479
  // ---------------------------------------------------------------------------
1545
1480
  /**
1546
1481
  * Redeem a one-time pair token for a long-lived computer identity. The
1547
1482
  * token itself is the auth — we swap the bearer for the token on this
1548
- * call only (same pattern as `triggers.fire`).
1483
+ * call only (same pattern as `automations.fire`).
1549
1484
  *
1550
1485
  * Used by `idapt up --token` to bootstrap a daemon. The request body is
1551
1486
  * snake_case; the response is wrapped in the standard `{data:{…}}`
@@ -1567,117 +1502,6 @@ var ComputersApi = class {
1567
1502
  }
1568
1503
  };
1569
1504
 
1570
- // ../sdk/src/api/datastore.ts
1571
- var enc2 = encodeURIComponent;
1572
- var DatastoreApi = class {
1573
- constructor(ctx) {
1574
- this.ctx = ctx;
1575
- }
1576
- /** List keys in a namespace (prefix-filterable). */
1577
- async list(namespace, opts = {}) {
1578
- const q = new URLSearchParams();
1579
- if (opts.prefix) q.set("prefix", opts.prefix);
1580
- if (opts.cursor) q.set("cursor", opts.cursor);
1581
- if (opts.limit) q.set("limit", String(opts.limit));
1582
- const qs = q.toString() ? `?${q.toString()}` : "";
1583
- const res = await request(this.ctx, {
1584
- method: "GET",
1585
- path: `/api/v1/datastore/${enc2(namespace)}${qs}`,
1586
- signal: opts.signal
1587
- });
1588
- return res.data;
1589
- }
1590
- /** Read a KV entry. */
1591
- async get(namespace, key, opts = {}) {
1592
- const res = await request(this.ctx, {
1593
- method: "GET",
1594
- path: `/api/v1/datastore/${enc2(namespace)}/${enc2(key)}`,
1595
- signal: opts.signal
1596
- });
1597
- return res.data;
1598
- }
1599
- /** Upsert a KV entry (optionally with a TTL). */
1600
- async set(namespace, key, value, opts = {}) {
1601
- const res = await request(this.ctx, {
1602
- method: "POST",
1603
- path: `/api/v1/datastore/${enc2(namespace)}/${enc2(key)}`,
1604
- body: { value, ttl_seconds: opts.ttlSeconds },
1605
- signal: opts.signal
1606
- });
1607
- return res.data;
1608
- }
1609
- /** Delete a KV entry (idempotent). */
1610
- async delete(namespace, key, opts = {}) {
1611
- return request(this.ctx, {
1612
- method: "DELETE",
1613
- path: `/api/v1/datastore/${enc2(namespace)}/${enc2(key)}`,
1614
- signal: opts.signal
1615
- });
1616
- }
1617
- /** Atomically add `by` (default 1) to a numeric counter. */
1618
- async increment(namespace, key, by = 1, opts = {}) {
1619
- const res = await request(
1620
- this.ctx,
1621
- {
1622
- method: "POST",
1623
- path: `/api/v1/datastore/${enc2(namespace)}/${enc2(key)}/increment`,
1624
- body: { by },
1625
- signal: opts.signal
1626
- }
1627
- );
1628
- return res.data;
1629
- }
1630
- /** List the namespaces in the workspace. */
1631
- async listNamespaces(opts = {}) {
1632
- const res = await request(this.ctx, {
1633
- method: "GET",
1634
- path: "/api/v1/datastore",
1635
- signal: opts.signal
1636
- });
1637
- return res.data.map((n) => n.namespace);
1638
- }
1639
- /** Read several keys at once. */
1640
- async batchGet(namespace, keys, opts = {}) {
1641
- const res = await request(
1642
- this.ctx,
1643
- {
1644
- method: "POST",
1645
- path: `/api/v1/datastore/${enc2(namespace)}`,
1646
- body: { op: "get", keys },
1647
- signal: opts.signal
1648
- }
1649
- );
1650
- return res.data.entries ?? [];
1651
- }
1652
- /** Upsert several entries at once. */
1653
- async batchSet(namespace, entries, opts = {}) {
1654
- const res = await request(this.ctx, {
1655
- method: "POST",
1656
- path: `/api/v1/datastore/${enc2(namespace)}`,
1657
- body: {
1658
- op: "set",
1659
- entries: entries.map((e) => ({
1660
- key: e.key,
1661
- value: e.value,
1662
- ttl_seconds: e.ttlSeconds
1663
- }))
1664
- },
1665
- signal: opts.signal
1666
- });
1667
- return res.data.count ?? 0;
1668
- }
1669
- /** Delete several keys at once; returns the count removed. */
1670
- async batchDelete(namespace, keys, opts = {}) {
1671
- const res = await request(this.ctx, {
1672
- method: "POST",
1673
- path: `/api/v1/datastore/${enc2(namespace)}`,
1674
- body: { op: "delete", keys },
1675
- signal: opts.signal
1676
- });
1677
- return res.data.count ?? 0;
1678
- }
1679
- };
1680
-
1681
1505
  // ../sdk/src/api/docs.ts
1682
1506
  var DocsApi = class {
1683
1507
  constructor(ctx) {
@@ -1745,7 +1569,7 @@ var FilesApi = class {
1745
1569
  return permanentDeleteFile(this.ctx, id, opts);
1746
1570
  }
1747
1571
  // ---------------------------------------------------------------------------
1748
- // Folder / move / run
1572
+ // Folder / move
1749
1573
  // ---------------------------------------------------------------------------
1750
1574
  /**
1751
1575
  * Idempotent create-or-get a folder. Returns the existing folder (with
@@ -1757,163 +1581,6 @@ var FilesApi = class {
1757
1581
  move(id, parentId, opts = {}) {
1758
1582
  return moveFile(this.ctx, id, parentId, opts);
1759
1583
  }
1760
- /**
1761
- * Execute a code file (js/ts/py/sh) in a sandboxed Lambda. Returns the
1762
- * full `ExecutionRun` record (status, stdout/stderr, exit code, timestamps).
1763
- */
1764
- run(id, input = {}, opts = {}) {
1765
- return runFile(this.ctx, id, input, opts);
1766
- }
1767
- };
1768
-
1769
- // ../sdk/src/api/functions.ts
1770
- var enc3 = encodeURIComponent;
1771
- var FunctionRunsApi = class {
1772
- constructor(ctx) {
1773
- this.ctx = ctx;
1774
- }
1775
- /** List one-off function runs (cursor-paginated). */
1776
- async list(query = {}, opts = {}) {
1777
- const res = await request(this.ctx, {
1778
- method: "GET",
1779
- path: "/api/v1/functions/runs",
1780
- query,
1781
- signal: opts.signal
1782
- });
1783
- return res.data;
1784
- }
1785
- /** Get a single one-off run by id. */
1786
- async get(id, opts = {}) {
1787
- const res = await request(this.ctx, {
1788
- method: "GET",
1789
- path: `/api/v1/functions/runs/${enc3(id)}`,
1790
- signal: opts.signal
1791
- });
1792
- return res.data;
1793
- }
1794
- /**
1795
- * Interrupt a running run. Only computer-backed runs can be interrupted;
1796
- * Lambda-backed runs return 409 (`ConflictError`).
1797
- */
1798
- async interrupt(id, opts = {}) {
1799
- const res = await request(this.ctx, {
1800
- method: "POST",
1801
- path: `/api/v1/functions/runs/${enc3(id)}/interrupt`,
1802
- body: {},
1803
- signal: opts.signal
1804
- });
1805
- return res.data;
1806
- }
1807
- };
1808
- var FunctionsApi = class {
1809
- constructor(ctx) {
1810
- this.ctx = ctx;
1811
- this.runs = new FunctionRunsApi(ctx);
1812
- }
1813
- /**
1814
- * Run a script ONCE in the sandbox. Pass EITHER inline `script` (+ optional
1815
- * `language`) OR an existing Drive `file_id`. Returns the full `FunctionRun`
1816
- * row — `id`, `status`, `stdout`, `stderr`, `exit_code`, the run timestamps,
1817
- * and any `output_files` the script wrote under `/tmp/output/`.
1818
- */
1819
- async run(input, opts = {}) {
1820
- const res = await request(this.ctx, {
1821
- method: "POST",
1822
- path: "/api/v1/functions/runs",
1823
- body: input,
1824
- signal: opts.signal
1825
- });
1826
- return res.data;
1827
- }
1828
- /** List deployed functions in the workspace. */
1829
- async list(query = {}, opts = {}) {
1830
- const res = await request(this.ctx, {
1831
- method: "GET",
1832
- path: "/api/v1/functions",
1833
- query,
1834
- signal: opts.signal
1835
- });
1836
- return res.data;
1837
- }
1838
- /** Get a deployed function by its resourceId. */
1839
- async get(id, opts = {}) {
1840
- const res = await request(this.ctx, {
1841
- method: "GET",
1842
- path: `/api/v1/functions/${enc3(id)}`,
1843
- signal: opts.signal
1844
- });
1845
- return res.data;
1846
- }
1847
- /** Create a deployed function (config only — `deploy` adds a bundle). */
1848
- async create(input, opts = {}) {
1849
- const res = await request(this.ctx, {
1850
- method: "POST",
1851
- path: "/api/v1/functions",
1852
- body: input,
1853
- signal: opts.signal
1854
- });
1855
- return res.data;
1856
- }
1857
- /** Update a deployed function's config. */
1858
- async update(id, patch, opts = {}) {
1859
- const res = await request(this.ctx, {
1860
- method: "PATCH",
1861
- path: `/api/v1/functions/${enc3(id)}`,
1862
- body: patch,
1863
- signal: opts.signal
1864
- });
1865
- return res.data;
1866
- }
1867
- /** Delete a deployed function + all its deployments. */
1868
- async delete(id, opts = {}) {
1869
- return request(this.ctx, {
1870
- method: "DELETE",
1871
- path: `/api/v1/functions/${enc3(id)}`,
1872
- signal: opts.signal
1873
- });
1874
- }
1875
- /**
1876
- * Deploy a new bundle (inline base64 files). Promotes the new deployment to
1877
- * live immediately unless `promote: false`. Returns the new deployment.
1878
- */
1879
- async deploy(id, input, opts = {}) {
1880
- const res = await request(this.ctx, {
1881
- method: "POST",
1882
- path: `/api/v1/functions/${enc3(id)}/deploy`,
1883
- body: input,
1884
- signal: opts.signal
1885
- });
1886
- return res.data;
1887
- }
1888
- /** List a function's deployments (newest-first). */
1889
- async deployments(id, opts = {}) {
1890
- const res = await request(this.ctx, {
1891
- method: "GET",
1892
- path: `/api/v1/functions/${enc3(id)}/deployments`,
1893
- signal: opts.signal
1894
- });
1895
- return res.data;
1896
- }
1897
- /** Promote (or roll back to) a deployment — flips the active one. */
1898
- async promote(id, input, opts = {}) {
1899
- const res = await request(this.ctx, {
1900
- method: "POST",
1901
- path: `/api/v1/functions/${enc3(id)}/promote`,
1902
- body: input,
1903
- signal: opts.signal
1904
- });
1905
- return res.data;
1906
- }
1907
- /** Invoke a deployed function synchronously; returns its response. */
1908
- async invoke(id, input = {}, opts = {}) {
1909
- const res = await request(this.ctx, {
1910
- method: "POST",
1911
- path: `/api/v1/functions/${enc3(id)}/invoke`,
1912
- body: input,
1913
- signal: opts.signal
1914
- });
1915
- return res.data;
1916
- }
1917
1584
  };
1918
1585
 
1919
1586
  // ../sdk/src/api/guide.ts
@@ -1940,20 +1607,11 @@ var ImagesApi = class {
1940
1607
  constructor(ctx) {
1941
1608
  this.ctx = ctx;
1942
1609
  }
1610
+ /** List the available image-generation models. */
1943
1611
  async listModels(opts = {}) {
1944
- const res = await request(this.ctx, {
1945
- method: "GET",
1946
- path: "/api/v1/images/models",
1947
- signal: opts.signal
1948
- });
1949
- return res.data;
1950
- }
1951
- /** Generate an image. Responds HTTP 201 with the written file ref under `data`. */
1952
- async generate(input, opts = {}) {
1953
- const res = await request(this.ctx, {
1954
- method: "POST",
1955
- path: "/api/v1/images/generations",
1956
- body: input,
1612
+ const res = await request(this.ctx, {
1613
+ method: "GET",
1614
+ path: "/api/v1/images/models",
1957
1615
  signal: opts.signal
1958
1616
  });
1959
1617
  return res.data;
@@ -2218,7 +1876,7 @@ var ProviderEndpointsApi = class {
2218
1876
  };
2219
1877
 
2220
1878
  // ../sdk/src/api/realtime.ts
2221
- var enc4 = encodeURIComponent;
1879
+ var enc = encodeURIComponent;
2222
1880
  var RECONNECT_MIN_MS = 1e3;
2223
1881
  var RECONNECT_MAX_MS = 3e4;
2224
1882
  var RealtimeApi = class {
@@ -2229,7 +1887,7 @@ var RealtimeApi = class {
2229
1887
  async broadcast(channel, message, opts = {}) {
2230
1888
  const res = await request(this.ctx, {
2231
1889
  method: "POST",
2232
- path: `/api/v1/realtime/${enc4(channel)}/broadcast`,
1890
+ path: `/api/v1/realtime/${enc(channel)}/broadcast`,
2233
1891
  body: { message },
2234
1892
  signal: opts.signal
2235
1893
  });
@@ -2239,7 +1897,7 @@ var RealtimeApi = class {
2239
1897
  async heartbeat(channel, opts = {}) {
2240
1898
  const res = await request(this.ctx, {
2241
1899
  method: "POST",
2242
- path: `/api/v1/realtime/${enc4(channel)}/presence`,
1900
+ path: `/api/v1/realtime/${enc(channel)}/presence`,
2243
1901
  body: { meta: opts.meta, ttl_seconds: opts.ttlSeconds },
2244
1902
  signal: opts.signal
2245
1903
  });
@@ -2249,7 +1907,7 @@ var RealtimeApi = class {
2249
1907
  async presence(channel, opts = {}) {
2250
1908
  const res = await request(this.ctx, {
2251
1909
  method: "GET",
2252
- path: `/api/v1/realtime/${enc4(channel)}/presence`,
1910
+ path: `/api/v1/realtime/${enc(channel)}/presence`,
2253
1911
  signal: opts.signal
2254
1912
  });
2255
1913
  return res.data;
@@ -2343,7 +2001,7 @@ async function* parseSseStream(response, signal) {
2343
2001
  if (boundary === -1) break;
2344
2002
  const block = buffer.slice(0, boundary);
2345
2003
  buffer = buffer.slice(boundary + 2);
2346
- const parsed = parseSseBlock3(block);
2004
+ const parsed = parseSseBlock2(block);
2347
2005
  if (parsed) yield parsed;
2348
2006
  }
2349
2007
  }
@@ -2354,7 +2012,7 @@ async function* parseSseStream(response, signal) {
2354
2012
  }
2355
2013
  }
2356
2014
  }
2357
- function parseSseBlock3(block) {
2015
+ function parseSseBlock2(block) {
2358
2016
  let id;
2359
2017
  let data = "";
2360
2018
  let isHeartbeat = false;
@@ -2604,42 +2262,6 @@ var SharingApi = class {
2604
2262
  }
2605
2263
  };
2606
2264
 
2607
- // ../sdk/src/api/store.ts
2608
- var StoreApi = class {
2609
- constructor(ctx) {
2610
- this.ctx = ctx;
2611
- }
2612
- /**
2613
- * Search the hub. Open envelope — items are heterogeneous (skills carry
2614
- * version/license, agents carry icons/prompts, computer templates carry
2615
- * sizing) so we surface them as `StoreItem` with an open index signature.
2616
- */
2617
- async search(query = {}, opts = {}) {
2618
- const res = await request(this.ctx, {
2619
- method: "GET",
2620
- path: "/api/v1/store/search",
2621
- query,
2622
- signal: opts.signal
2623
- });
2624
- return res.data;
2625
- }
2626
- /**
2627
- * Install a hub item into one of the caller's workspaces. Returns whatever
2628
- * the per-template installer produces (folder ids, agent ids, ...) —
2629
- * `StoreInstallResult` carries the common fields and leaves the rest
2630
- * open.
2631
- */
2632
- async install(resourceId, input, opts = {}) {
2633
- const res = await request(this.ctx, {
2634
- method: "POST",
2635
- path: `/api/v1/store/${resourceId}/install`,
2636
- body: input,
2637
- signal: opts.signal
2638
- });
2639
- return res.data;
2640
- }
2641
- };
2642
-
2643
2265
  // ../sdk/src/api/subscription.ts
2644
2266
  var SubscriptionApi = class {
2645
2267
  constructor(ctx) {
@@ -2655,271 +2277,6 @@ var SubscriptionApi = class {
2655
2277
  }
2656
2278
  };
2657
2279
 
2658
- // ../sdk/src/api/tables.ts
2659
- var enc5 = encodeURIComponent;
2660
- var TablesApi = class {
2661
- constructor(ctx) {
2662
- this.ctx = ctx;
2663
- }
2664
- async list(opts = {}) {
2665
- const q = new URLSearchParams();
2666
- if (opts.workspaceId) q.set("workspace_id", opts.workspaceId);
2667
- if (opts.cursor) q.set("cursor", opts.cursor);
2668
- if (opts.limit) q.set("limit", String(opts.limit));
2669
- const qs = q.toString() ? `?${q.toString()}` : "";
2670
- const res = await request(this.ctx, {
2671
- method: "GET",
2672
- path: `/api/v1/tables${qs}`,
2673
- signal: opts.signal
2674
- });
2675
- return res.data;
2676
- }
2677
- async get(id, opts = {}) {
2678
- const res = await request(this.ctx, {
2679
- method: "GET",
2680
- path: `/api/v1/tables/${enc5(id)}`,
2681
- signal: opts.signal
2682
- });
2683
- return res.data;
2684
- }
2685
- async create(input, opts = {}) {
2686
- const res = await request(this.ctx, {
2687
- method: "POST",
2688
- path: "/api/v1/tables",
2689
- body: input,
2690
- signal: opts.signal
2691
- });
2692
- return res.data;
2693
- }
2694
- async update(id, input, opts = {}) {
2695
- const res = await request(this.ctx, {
2696
- method: "PATCH",
2697
- path: `/api/v1/tables/${enc5(id)}`,
2698
- body: input,
2699
- signal: opts.signal
2700
- });
2701
- return res.data;
2702
- }
2703
- async delete(id, opts = {}) {
2704
- return request(this.ctx, {
2705
- method: "DELETE",
2706
- path: `/api/v1/tables/${enc5(id)}`,
2707
- signal: opts.signal
2708
- });
2709
- }
2710
- /** Query a collection's records with the filter/sort/paginate DSL. */
2711
- async query(id, query = {}, opts = {}) {
2712
- const res = await request(this.ctx, {
2713
- method: "POST",
2714
- path: `/api/v1/tables/${enc5(id)}/query`,
2715
- body: query,
2716
- signal: opts.signal
2717
- });
2718
- return res.data;
2719
- }
2720
- async createRecord(id, values, opts = {}) {
2721
- const res = await request(this.ctx, {
2722
- method: "POST",
2723
- path: `/api/v1/tables/${enc5(id)}/records`,
2724
- body: { values },
2725
- signal: opts.signal
2726
- });
2727
- return res.data;
2728
- }
2729
- async getRecord(id, recordId, opts = {}) {
2730
- const res = await request(this.ctx, {
2731
- method: "GET",
2732
- path: `/api/v1/tables/${enc5(id)}/records/${enc5(recordId)}`,
2733
- signal: opts.signal
2734
- });
2735
- return res.data;
2736
- }
2737
- async updateRecord(id, recordId, values, opts = {}) {
2738
- const res = await request(this.ctx, {
2739
- method: "PATCH",
2740
- path: `/api/v1/tables/${enc5(id)}/records/${enc5(recordId)}`,
2741
- body: { values },
2742
- signal: opts.signal
2743
- });
2744
- return res.data;
2745
- }
2746
- async deleteRecord(id, recordId, opts = {}) {
2747
- return request(this.ctx, {
2748
- method: "DELETE",
2749
- path: `/api/v1/tables/${enc5(id)}/records/${enc5(recordId)}`,
2750
- signal: opts.signal
2751
- });
2752
- }
2753
- /** Export a collection's records as a CSV string (header row = field keys). */
2754
- async exportCsv(id, opts = {}) {
2755
- const res = await requestRaw(this.ctx, {
2756
- method: "GET",
2757
- path: `/api/v1/tables/${enc5(id)}/export`,
2758
- signal: opts.signal,
2759
- expectJson: false
2760
- });
2761
- return res.text();
2762
- }
2763
- /** Import records into a collection from a CSV string. Returns the count. */
2764
- async importCsv(id, csv, opts = {}) {
2765
- const res = await request(this.ctx, {
2766
- method: "POST",
2767
- path: `/api/v1/tables/${enc5(id)}/import`,
2768
- body: { csv },
2769
- signal: opts.signal
2770
- });
2771
- return res.data;
2772
- }
2773
- };
2774
-
2775
- // ../sdk/src/api/triggers.ts
2776
- var TriggersApi = class {
2777
- constructor(ctx) {
2778
- this.ctx = ctx;
2779
- }
2780
- // ---------------------------------------------------------------------------
2781
- // CRUD
2782
- // ---------------------------------------------------------------------------
2783
- async list(query = {}, opts = {}) {
2784
- const res = await request(this.ctx, {
2785
- method: "GET",
2786
- path: "/api/v1/triggers",
2787
- query,
2788
- signal: opts.signal
2789
- });
2790
- return res.data;
2791
- }
2792
- /**
2793
- * Create a trigger. `workspace_id` is passed in the request BODY (alongside
2794
- * the flat trigger definition) — it is not a query param. The request
2795
- * body is flat: every scheduling field (`cron_expression`, …) and every
2796
- * action field (`agent_id`, `prompt_template`, `file_id`, …) sits at the
2797
- * top level — there are no nested `trigger_config` / `action_config`
2798
- * objects any more.
2799
- *
2800
- * For a `webhook` trigger the response additionally carries a one-time
2801
- * plaintext `secret` (use `TriggerWithSecret`); other trigger types
2802
- * resolve to a plain `Trigger`.
2803
- */
2804
- async create(workspaceId, input, opts = {}) {
2805
- const res = await request(
2806
- this.ctx,
2807
- {
2808
- method: "POST",
2809
- path: "/api/v1/triggers",
2810
- body: { workspace_id: workspaceId, ...input },
2811
- signal: opts.signal
2812
- }
2813
- );
2814
- return res.data;
2815
- }
2816
- async get(id, opts = {}) {
2817
- const res = await request(this.ctx, {
2818
- method: "GET",
2819
- path: `/api/v1/triggers/${id}`,
2820
- signal: opts.signal
2821
- });
2822
- return res.data;
2823
- }
2824
- async update(id, input, opts = {}) {
2825
- const res = await request(this.ctx, {
2826
- method: "PATCH",
2827
- path: `/api/v1/triggers/${id}`,
2828
- body: input,
2829
- signal: opts.signal
2830
- });
2831
- return res.data;
2832
- }
2833
- async delete(id, opts = {}) {
2834
- return request(this.ctx, {
2835
- method: "DELETE",
2836
- path: `/api/v1/triggers/${id}`,
2837
- signal: opts.signal
2838
- });
2839
- }
2840
- async archive(id, opts = {}) {
2841
- const res = await request(this.ctx, {
2842
- method: "POST",
2843
- path: `/api/v1/triggers/${id}/archive`,
2844
- signal: opts.signal
2845
- });
2846
- return res.data;
2847
- }
2848
- async unarchive(id, opts = {}) {
2849
- const res = await request(this.ctx, {
2850
- method: "POST",
2851
- path: `/api/v1/triggers/${id}/unarchive`,
2852
- signal: opts.signal
2853
- });
2854
- return res.data;
2855
- }
2856
- // ---------------------------------------------------------------------------
2857
- // Fire + rotate-secret + runs
2858
- // ---------------------------------------------------------------------------
2859
- /**
2860
- * Fire a trigger via its webhook secret. This endpoint does NOT use the
2861
- * client's `ap_` key — the bearer is the trigger's secret — so we build a
2862
- * one-off HttpContext for it rather than mutating the shared one.
2863
- *
2864
- * Responds HTTP 202. The response identifies the fired trigger via `id`
2865
- * only.
2866
- */
2867
- async fire(id, input, opts = {}) {
2868
- const localCtx = {
2869
- apiUrl: this.ctx.apiUrl,
2870
- key: input.secret,
2871
- fetch: this.ctx.fetch
2872
- };
2873
- const res = await request(localCtx, {
2874
- method: "POST",
2875
- path: `/api/v1/triggers/${id}/fire`,
2876
- body: input.body ?? {},
2877
- signal: opts.signal
2878
- });
2879
- return res.data;
2880
- }
2881
- /**
2882
- * Rotate the webhook secret. Returns the trigger with a fresh one-time
2883
- * plaintext `secret` populated (`TriggerWithSecret`). The old secret
2884
- * immediately stops working.
2885
- */
2886
- async rotateSecret(id, opts = {}) {
2887
- const res = await request(this.ctx, {
2888
- method: "POST",
2889
- path: `/api/v1/triggers/${id}/rotate-secret`,
2890
- signal: opts.signal
2891
- });
2892
- return res.data;
2893
- }
2894
- /** Recent fires + their success/error outcome. */
2895
- async listRuns(id, query = {}, opts = {}) {
2896
- const res = await request(this.ctx, {
2897
- method: "GET",
2898
- path: `/api/v1/triggers/${id}/runs`,
2899
- query,
2900
- signal: opts.signal
2901
- });
2902
- return res.data;
2903
- }
2904
- async getCostStats(id, opts = {}) {
2905
- const res = await request(this.ctx, {
2906
- method: "GET",
2907
- path: `/api/v1/triggers/${id}/cost-stats`,
2908
- signal: opts.signal
2909
- });
2910
- return res.data;
2911
- }
2912
- async getCostStatsMap(query = {}, opts = {}) {
2913
- const res = await request(this.ctx, {
2914
- method: "GET",
2915
- path: "/api/v1/triggers/cost-stats",
2916
- query,
2917
- signal: opts.signal
2918
- });
2919
- return res.data.by_id;
2920
- }
2921
- };
2922
-
2923
2280
  // ../sdk/src/api/user.ts
2924
2281
  var UserApi = class {
2925
2282
  constructor(ctx) {
@@ -3616,24 +2973,19 @@ var IdaptClient2 = class {
3616
2973
  this.agents = new AgentsApi(v1Ctx);
3617
2974
  this.chats = new ChatsApi(v1Ctx);
3618
2975
  this.workspaces = new WorkspacesApi(v1Ctx);
3619
- this.triggers = new TriggersApi(v1Ctx);
2976
+ this.automations = new AutomationsApi(v1Ctx);
3620
2977
  this.computers = new ComputersApi(v1Ctx);
3621
2978
  this.secrets = new SecretsApi(v1Ctx);
3622
- this.kv = new DatastoreApi(v1Ctx);
3623
- this.blobs = new BlobsApi(v1Ctx);
3624
- this.tables = new TablesApi(v1Ctx);
3625
2979
  this.realtime = new RealtimeApi(v1Ctx);
3626
2980
  this.apiKeys = new ApiKeysApi(v1Ctx);
3627
2981
  this.notifications = new NotificationsApi(v1Ctx);
3628
2982
  this.settings = new SettingsApi(v1Ctx);
3629
2983
  this.subscription = new SubscriptionApi(v1Ctx);
3630
2984
  this.sharing = new SharingApi(v1Ctx);
3631
- this.store = new StoreApi(v1Ctx);
3632
2985
  this.models = new ModelsApi(v1Ctx);
3633
2986
  this.providerEndpoints = new ProviderEndpointsApi(v1Ctx);
3634
2987
  this.images = new ImagesApi(v1Ctx);
3635
2988
  this.audio = new AudioApi(v1Ctx);
3636
- this.functions = new FunctionsApi(v1Ctx);
3637
2989
  this.search = new SearchApi(v1Ctx);
3638
2990
  this.web = new WebSearchApi(v1Ctx);
3639
2991
  this.guide = new GuideApi(v1Ctx);
@@ -4167,64 +3519,6 @@ function useDataFile(name, options = {}) {
4167
3519
  }, [client, load]);
4168
3520
  return { data, loading, error, save, refresh, remove };
4169
3521
  }
4170
- function useLiveQuery(collectionResId, dsl = {}) {
4171
- const client = useIdapt();
4172
- const [records, setRecords] = react.useState([]);
4173
- const [loading, setLoading] = react.useState(true);
4174
- const [error, setError] = react.useState(null);
4175
- const dslKey = JSON.stringify(dsl);
4176
- const dslRef = react.useRef(dsl);
4177
- dslRef.current = dsl;
4178
- const [nonce, setNonce] = react.useState(0);
4179
- react.useEffect(() => {
4180
- if (!client || !collectionResId) return;
4181
- let active = true;
4182
- let inflight = false;
4183
- let queued = false;
4184
- const runQuery = async () => {
4185
- if (inflight) {
4186
- queued = true;
4187
- return;
4188
- }
4189
- inflight = true;
4190
- try {
4191
- const rows = await client.tables.query(collectionResId, dslRef.current);
4192
- if (!active) return;
4193
- setRecords(rows);
4194
- setError(null);
4195
- } catch (err) {
4196
- if (!active) return;
4197
- setError(err instanceof Error ? err : new Error(String(err)));
4198
- } finally {
4199
- inflight = false;
4200
- if (active) setLoading(false);
4201
- if (active && queued) {
4202
- queued = false;
4203
- void runQuery();
4204
- }
4205
- }
4206
- };
4207
- setLoading(true);
4208
- void runQuery();
4209
- const unsubscribe = client.realtime.subscribe(
4210
- [`table:${collectionResId}`],
4211
- (event) => {
4212
- if (event.type !== "broadcast") void runQuery();
4213
- },
4214
- { onError: (err) => active && setError(err) }
4215
- );
4216
- return () => {
4217
- active = false;
4218
- unsubscribe();
4219
- };
4220
- }, [client, collectionResId, dslKey, nonce]);
4221
- return {
4222
- records,
4223
- loading,
4224
- error,
4225
- refresh: () => setNonce((n) => n + 1)
4226
- };
4227
- }
4228
3522
  var DEFAULT_INTERVAL_MS = 1e4;
4229
3523
  function usePresence(key, options = {}) {
4230
3524
  const client = useIdapt();
@@ -4271,7 +3565,6 @@ exports.useChannel = useChannel;
4271
3565
  exports.useDataFile = useDataFile;
4272
3566
  exports.useIdapt = useIdapt;
4273
3567
  exports.useIdaptError = useIdaptError;
4274
- exports.useLiveQuery = useLiveQuery;
4275
3568
  exports.usePresence = usePresence;
4276
3569
  //# sourceMappingURL=react.cjs.map
4277
3570
  //# sourceMappingURL=react.cjs.map