skydive-cli 0.2.0-beta.577 → 0.2.0-beta.583

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
@@ -20,7 +20,7 @@ import semver from "semver";
20
20
 
21
21
  //#region package.json
22
22
  var name = "skydive-cli";
23
- var version = "0.2.0-beta.577";
23
+ var version = "0.2.0-beta.583";
24
24
 
25
25
  //#endregion
26
26
  //#region src/types.ts
@@ -1200,7 +1200,7 @@ const importCommand = {
1200
1200
  process.exit(1);
1201
1201
  }
1202
1202
  }
1203
- const { runChat } = await import("./boot--whEK1H-.mjs");
1203
+ const { runChat } = await import("./boot-Be4wXLr5.mjs");
1204
1204
  await runChat({
1205
1205
  appUrl,
1206
1206
  sessionToken: session.value.sessionToken,
@@ -1511,7 +1511,7 @@ const chatCommand = {
1511
1511
  printError(`Unknown theme "${themeId}". Valid themes: ${themes.map((t) => t.id).join(", ")}`);
1512
1512
  process.exit(1);
1513
1513
  }
1514
- const { runChat } = await import("./boot--whEK1H-.mjs");
1514
+ const { runChat } = await import("./boot-Be4wXLr5.mjs");
1515
1515
  await runChat({
1516
1516
  appUrl,
1517
1517
  sessionToken: session.value.sessionToken,
@@ -1810,7 +1810,7 @@ const switchCommand = {
1810
1810
  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.");
1811
1811
  process.exit(1);
1812
1812
  }
1813
- const { runWorkspacePicker } = await import("./boot--whEK1H-.mjs");
1813
+ const { runWorkspacePicker } = await import("./boot-Be4wXLr5.mjs");
1814
1814
  await runWorkspacePicker(session);
1815
1815
  return;
1816
1816
  }
@@ -4677,6 +4677,14 @@ const keybindGroups = [
4677
4677
  keys: "pgup / pgdn",
4678
4678
  action: "scroll transcript"
4679
4679
  },
4680
+ {
4681
+ keys: "end",
4682
+ action: "jump to latest (when scrolled up)"
4683
+ },
4684
+ {
4685
+ keys: "/plan [show|hide]",
4686
+ action: "show / hide the pinned plan card"
4687
+ },
4680
4688
  {
4681
4689
  keys: "/",
4682
4690
  action: "open the command menu (start of message)"
@@ -5143,6 +5151,16 @@ const slashCommands = [
5143
5151
  description: "show connection and session status",
5144
5152
  action: { kind: "status" }
5145
5153
  },
5154
+ {
5155
+ name: "plan",
5156
+ aliases: ["todos", "todo"],
5157
+ argsHint: "[show|hide]",
5158
+ description: "show or hide the pinned plan card",
5159
+ action: {
5160
+ kind: "plan",
5161
+ mode: "toggle"
5162
+ }
5163
+ },
5146
5164
  {
5147
5165
  name: "share",
5148
5166
  aliases: [],
@@ -5164,6 +5182,13 @@ const slashCommands = [
5164
5182
  description: "act on a waiting connect card (auth cards)",
5165
5183
  action: { kind: "connect" }
5166
5184
  },
5185
+ {
5186
+ name: "copy",
5187
+ aliases: ["cp"],
5188
+ argsHint: null,
5189
+ description: "copy the agent's last message to the clipboard",
5190
+ action: { kind: "copy" }
5191
+ },
5167
5192
  {
5168
5193
  name: "help",
5169
5194
  aliases: [],
@@ -8208,6 +8233,13 @@ function routeInput(raw) {
8208
8233
  kind: "open-conversation",
8209
8234
  ref: match.rest
8210
8235
  } : { kind: "conversation-picker" };
8236
+ case "plan": {
8237
+ const arg = match.rest.toLowerCase();
8238
+ return {
8239
+ kind: "plan",
8240
+ mode: arg === "show" ? "show" : arg === "hide" ? "hide" : "toggle"
8241
+ };
8242
+ }
8211
8243
  case "new-conversation":
8212
8244
  case "model-picker":
8213
8245
  case "theme-picker":
@@ -8215,6 +8247,7 @@ function routeInput(raw) {
8215
8247
  case "share":
8216
8248
  case "browser":
8217
8249
  case "connect":
8250
+ case "copy":
8218
8251
  case "help":
8219
8252
  case "quit": return { kind: action.kind };
8220
8253
  default: {
@@ -8409,6 +8442,14 @@ function ChatScreen({ agent, conversation }) {
8409
8442
  const [conversationId, setConversationId] = useState(initialConversationId);
8410
8443
  const [items, setItems] = useState([]);
8411
8444
  const [todos, setTodos] = useState(null);
8445
+ const [planHidden, setPlanHidden] = useState(false);
8446
+ const [scrolledUp, setScrolledUp] = useState(false);
8447
+ const hadTodosRef = useRef(false);
8448
+ useEffect(() => {
8449
+ const hasTodos = !!todos && todos.length > 0;
8450
+ if (hasTodos && !hadTodosRef.current) setPlanHidden(false);
8451
+ hadTodosRef.current = hasTodos;
8452
+ }, [todos]);
8412
8453
  const [historyLoaded, setHistoryLoaded] = useState(initialConversationId === null);
8413
8454
  const [input, setInput] = useState("");
8414
8455
  const [run, setRun] = useState({ kind: "idle" });
@@ -8475,6 +8516,25 @@ function ChatScreen({ agent, conversation }) {
8475
8516
  }, [agentHost, conversationId]);
8476
8517
  const scrollRef = useRef(null);
8477
8518
  const composerRef = useRef(null);
8519
+ const jumpToBottom = useCallback(() => {
8520
+ const box = scrollRef.current;
8521
+ if (!box) return;
8522
+ box.scrollTo({
8523
+ x: box.scrollLeft,
8524
+ y: box.scrollHeight
8525
+ });
8526
+ setScrolledUp(false);
8527
+ }, []);
8528
+ useEffect(() => {
8529
+ const id = setInterval(() => {
8530
+ const box = scrollRef.current;
8531
+ if (!box) return;
8532
+ const viewport = box.viewport.height;
8533
+ const atBottom = box.scrollTop + viewport >= box.scrollHeight - 1;
8534
+ setScrolledUp((prev) => prev === !atBottom ? prev : !atBottom);
8535
+ }, 150);
8536
+ return () => clearInterval(id);
8537
+ }, []);
8478
8538
  const reviewSideBoxRef = useRef(null);
8479
8539
  const reviewBelowBoxRef = useRef(null);
8480
8540
  const paneDragRef = useRef(null);
@@ -8498,9 +8558,11 @@ function ChatScreen({ agent, conversation }) {
8498
8558
  const chatHeight = bodyHeight;
8499
8559
  const inlineReviewHeight = reviewOpen && reviewPlacement === "below" ? reviewHeight : 0;
8500
8560
  const menuRows = menuOpen ? completionMenuHeight(menuCommands.length) : 0;
8501
- const todoCardVisible = !credPrompt && !!todos && todos.length > 0;
8561
+ const todoCardVisible = !credPrompt && !planHidden && !!todos && todos.length > 0;
8502
8562
  const todoRows = todoCardVisible ? todoCardHeight(todos) : 0;
8503
- const scrollHeight = Math.max(3, chatHeight - 2 - bottomBoxHeight - pendingRows - inlineReviewHeight - menuRows - todoRows);
8563
+ const jumpHintVisible = scrolledUp && !credPrompt;
8564
+ const jumpHintRows = jumpHintVisible ? 1 : 0;
8565
+ const scrollHeight = Math.max(3, chatHeight - 2 - bottomBoxHeight - pendingRows - inlineReviewHeight - menuRows - jumpHintRows - todoRows);
8504
8566
  useEffect(() => {
8505
8567
  if (reviewOpen && reviewFocused) {
8506
8568
  const composer = composerRef.current;
@@ -9208,6 +9270,17 @@ function ChatScreen({ agent, conversation }) {
9208
9270
  } : m));
9209
9271
  useStore.getState().showToast({ message: "run cancelled" });
9210
9272
  }, [rest]);
9273
+ const copyLastMessage = useCallback(() => {
9274
+ const last = [...items].reverse().find((m) => m.kind === "assistant-text" && m.done && m.text.trim() !== "");
9275
+ if (!last) {
9276
+ useStore.getState().showToast({ message: "no agent message to copy yet" });
9277
+ return;
9278
+ }
9279
+ writeClipboardText(last.text).then((ok) => useStore.getState().showToast(ok ? {
9280
+ variant: "success",
9281
+ message: "copied last message to clipboard"
9282
+ } : { message: "clipboard unavailable" }));
9283
+ }, [items]);
9211
9284
  const openInBrowser = useCallback(() => {
9212
9285
  if (!appUrl) return;
9213
9286
  if (!conversationId) {
@@ -9419,12 +9492,25 @@ function ChatScreen({ agent, conversation }) {
9419
9492
  })
9420
9493
  }]);
9421
9494
  break;
9495
+ case "plan": {
9496
+ if (!(!!todos && todos.length > 0)) {
9497
+ useStore.getState().showToast({ message: "no plan to show yet" });
9498
+ break;
9499
+ }
9500
+ const nextHidden = routed.mode === "toggle" ? !planHidden : routed.mode === "hide";
9501
+ setPlanHidden(nextHidden);
9502
+ useStore.getState().showToast({ message: nextHidden ? "plan hidden (/plan show)" : "plan shown" });
9503
+ break;
9504
+ }
9422
9505
  case "share":
9423
9506
  toggleShare();
9424
9507
  break;
9425
9508
  case "browser":
9426
9509
  openInBrowser();
9427
9510
  break;
9511
+ case "copy":
9512
+ copyLastMessage();
9513
+ break;
9428
9514
  case "connect":
9429
9515
  if (!promptForCards()) useStore.getState().showToast({ message: "no connect card waiting for action" });
9430
9516
  break;
@@ -9457,6 +9543,7 @@ function ChatScreen({ agent, conversation }) {
9457
9543
  openConversationRef,
9458
9544
  toggleShare,
9459
9545
  openInBrowser,
9546
+ copyLastMessage,
9460
9547
  quit,
9461
9548
  sendContent,
9462
9549
  goTo,
@@ -9467,7 +9554,9 @@ function ChatScreen({ agent, conversation }) {
9467
9554
  model,
9468
9555
  portal.status,
9469
9556
  portal.grantedAgentIds,
9470
- promptForCards
9557
+ promptForCards,
9558
+ todos,
9559
+ planHidden
9471
9560
  ]);
9472
9561
  const submit = useCallback(() => {
9473
9562
  const staged = attachments.filter((a) => a.status !== "error");
@@ -9659,6 +9748,10 @@ function ChatScreen({ agent, conversation }) {
9659
9748
  scrollRef.current?.scrollBy(pageScrollFraction, "viewport");
9660
9749
  return;
9661
9750
  }
9751
+ if (key.name === "end" && scrolledUp) {
9752
+ jumpToBottom();
9753
+ return;
9754
+ }
9662
9755
  if (key.name === "c" && key.ctrl) {
9663
9756
  if (runRef.current.kind === "streaming") {
9664
9757
  cancelRun();
@@ -9855,6 +9948,23 @@ function ChatScreen({ agent, conversation }) {
9855
9948
  }) : null]
9856
9949
  })
9857
9950
  }),
9951
+ jumpHintVisible ? /* @__PURE__ */ jsxs("box", {
9952
+ onMouseDown: jumpToBottom,
9953
+ style: {
9954
+ flexDirection: "row",
9955
+ paddingLeft: 1,
9956
+ paddingRight: 1,
9957
+ height: 1,
9958
+ flexShrink: 0
9959
+ },
9960
+ children: [/* @__PURE__ */ jsx("text", {
9961
+ fg: theme.accent,
9962
+ children: "↓ jump to latest"
9963
+ }), /* @__PURE__ */ jsxs("text", {
9964
+ fg: theme.dim,
9965
+ children: [" ", "end"]
9966
+ })]
9967
+ }) : null,
9858
9968
  todoCardVisible && todos ? /* @__PURE__ */ jsx(TodoCardView, {
9859
9969
  todos,
9860
9970
  isActive: run.kind !== "idle"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skydive-cli",
3
- "version": "0.2.0-beta.577",
3
+ "version": "0.2.0-beta.583",
4
4
  "description": "Skydive CLI — cloud agents from the command line",
5
5
  "homepage": "https://skydive.com",
6
6
  "license": "MIT",