skydive-cli 0.1.0-beta.122 → 0.1.0-beta.163

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/js/bin.mjs CHANGED
@@ -31,7 +31,7 @@ var __exportAll = (all, no_symbols) => {
31
31
 
32
32
  //#endregion
33
33
  //#region package.json
34
- var version$1 = "0.1.0-beta.122";
34
+ var version$1 = "0.1.0-beta.163";
35
35
 
36
36
  //#endregion
37
37
  //#region src/types.ts
@@ -2152,7 +2152,7 @@ const chatCommand = {
2152
2152
  printError(`Unknown theme "${themeId}". Valid themes: ${themes.map((t) => t.id).join(", ")}`);
2153
2153
  process.exit(1);
2154
2154
  }
2155
- const { runChat } = await import("./boot-BvkqTAxQ.mjs");
2155
+ const { runChat } = await import("./boot-B-eA8M6t.mjs");
2156
2156
  await runChat({
2157
2157
  appUrl,
2158
2158
  sessionToken: session.value.sessionToken,
@@ -2423,6 +2423,51 @@ function createRestClient({ appUrl, sessionToken }) {
2423
2423
  if (reconnects > MAX_STREAM_RECONNECTS) throw new Error("run stream ended unexpectedly");
2424
2424
  await sleep(Math.min(500 * 2 ** reconnects, 5e3));
2425
2425
  }
2426
+ },
2427
+ streamConversation: async ({ conversationId, signal, onEvent }) => {
2428
+ let reconnects = 0;
2429
+ for (;;) {
2430
+ if (signal.aborted) return;
2431
+ try {
2432
+ const res = await fetch(`${appUrl}/api/v1/chat/conversations/${encodeURIComponent(conversationId)}/stream`, {
2433
+ headers: {
2434
+ authorization: `Bearer ${sessionToken}`,
2435
+ accept: "text/event-stream"
2436
+ },
2437
+ signal
2438
+ });
2439
+ if (!res.ok || !res.body) throw new HttpError(res.status, await res.text().catch(() => ""));
2440
+ reconnects = 0;
2441
+ const parser = createParser({ onEvent: (message) => {
2442
+ const parsed = conversationStreamEventSchema.safeParse(JSON.parse(message.data));
2443
+ if (parsed.success) onEvent(parsed.data);
2444
+ } });
2445
+ const decoder = new TextDecoder();
2446
+ const reader = res.body.getReader();
2447
+ try {
2448
+ for (;;) {
2449
+ const { done, value } = await reader.read();
2450
+ if (done) break;
2451
+ parser.feed(decoder.decode(value, { stream: true }));
2452
+ }
2453
+ } finally {
2454
+ try {
2455
+ await reader.cancel();
2456
+ } catch (_error) {}
2457
+ }
2458
+ } catch (err) {
2459
+ if (signal.aborted) return;
2460
+ if (err instanceof HttpError && err.status >= 400 && err.status < 500) throw err;
2461
+ reconnects += 1;
2462
+ if (reconnects > MAX_STREAM_RECONNECTS) throw err;
2463
+ await sleep(Math.min(500 * 2 ** reconnects, 5e3));
2464
+ continue;
2465
+ }
2466
+ if (signal.aborted) return;
2467
+ reconnects += 1;
2468
+ if (reconnects > MAX_STREAM_RECONNECTS) throw new Error("conversation stream ended unexpectedly");
2469
+ await sleep(Math.min(500 * 2 ** reconnects, 5e3));
2470
+ }
2426
2471
  }
2427
2472
  };
2428
2473
  }
@@ -2537,6 +2582,11 @@ const runStreamEventSchema = z.union([z.object({
2537
2582
  error: z.string().nullish()
2538
2583
  })]);
2539
2584
  const streamErrorSchema = z.object({ error: z.string() });
2585
+ const conversationStreamEventSchema = z.object({
2586
+ kind: z.literal("conversation"),
2587
+ id: z.string(),
2588
+ title: z.string().nullable()
2589
+ });
2540
2590
 
2541
2591
  //#endregion
2542
2592
  //#region src/chat/util.ts
@@ -3129,7 +3179,7 @@ const switchCommand = {
3129
3179
  printError("The workspace picker needs the Bun runtime and it could not be set up automatically. Pass a workspace slug instead, or install Bun and retry.");
3130
3180
  process.exit(1);
3131
3181
  }
3132
- const { runWorkspacePicker } = await import("./boot-BvkqTAxQ.mjs");
3182
+ const { runWorkspacePicker } = await import("./boot-B-eA8M6t.mjs");
3133
3183
  await runWorkspacePicker(session);
3134
3184
  return;
3135
3185
  }
@@ -508,7 +508,7 @@ var PortalClient = class {
508
508
  this.setStatus("error", errorMessage(err));
509
509
  }
510
510
  if (!this.enabled || this.disposed) break;
511
- await sleep$1(backoff);
511
+ await sleep(backoff);
512
512
  backoff = Math.min(backoff * 2, MAX_BACKOFF_MS);
513
513
  }
514
514
  }
@@ -554,7 +554,7 @@ var PortalClient = class {
554
554
  for (let attempt = 0; attempt < 10; attempt += 1) {
555
555
  await this.refreshDevice();
556
556
  if (this.deviceId) return this.deviceId;
557
- await sleep$1(300);
557
+ await sleep(300);
558
558
  }
559
559
  throw new Error("this machine is not connected yet");
560
560
  }
@@ -590,7 +590,7 @@ function toBuffer(data) {
590
590
  function shortBody(res) {
591
591
  return res.text().then((text) => text.slice(0, 120)).catch(() => "");
592
592
  }
593
- function sleep$1(ms) {
593
+ function sleep(ms) {
594
594
  return new Promise((resolve) => setTimeout(resolve, ms));
595
595
  }
596
596
 
@@ -4639,9 +4639,6 @@ function ThemePicker({ onClose }) {
4639
4639
 
4640
4640
  //#endregion
4641
4641
  //#region src/chat/tui/screens/chat.tsx
4642
- function sleep(ms) {
4643
- return new Promise((resolve) => setTimeout(resolve, ms));
4644
- }
4645
4642
  /**
4646
4643
  * Composer key bindings: Enter sends the message (matching the rest of the
4647
4644
  * app), Shift+Enter inserts a hard newline. Everything else falls back to the
@@ -4858,41 +4855,18 @@ function ChatScreen({ agent, conversation }) {
4858
4855
  ]);
4859
4856
  useEffect(() => {
4860
4857
  if (!rest || !conversationId) return;
4861
- if (initialConversationId !== null) return;
4862
- let cancelled = false;
4863
- (async () => {
4864
- const delays = [
4865
- 0,
4866
- 800,
4867
- 1500,
4868
- 2500,
4869
- 4e3,
4870
- 6e3
4871
- ];
4872
- let last = null;
4873
- for (const delay of delays) {
4874
- if (delay) await sleep(delay);
4875
- if (cancelled) return;
4876
- let title;
4877
- try {
4878
- ({title} = await rest.getConversation({ conversationId }));
4879
- } catch (_error) {
4880
- continue;
4881
- }
4882
- if (cancelled) return;
4883
- if (title && title !== last) {
4884
- last = title;
4885
- setChatTitle(title);
4886
- }
4858
+ const abort = new AbortController();
4859
+ rest.streamConversation({
4860
+ conversationId,
4861
+ signal: abort.signal,
4862
+ onEvent: (event) => {
4863
+ if (event.title) setChatTitle(event.title);
4887
4864
  }
4888
- })();
4889
- return () => {
4890
- cancelled = true;
4891
- };
4865
+ }).catch(() => {});
4866
+ return () => abort.abort();
4892
4867
  }, [
4893
4868
  rest,
4894
4869
  conversationId,
4895
- initialConversationId,
4896
4870
  setChatTitle
4897
4871
  ]);
4898
4872
  useEffect(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skydive-cli",
3
- "version": "0.1.0-beta.122",
3
+ "version": "0.1.0-beta.163",
4
4
  "description": "Skydive CLI — manage AI agents from the command line",
5
5
  "homepage": "https://skydive.com",
6
6
  "license": "MIT",