skydive-cli 0.2.0-beta.482 → 0.2.0-beta.497
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.
|
|
23
|
+
var version = "0.2.0-beta.497";
|
|
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-
|
|
1203
|
+
const { runChat } = await import("./boot-DlptSLP6.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-
|
|
1514
|
+
const { runChat } = await import("./boot-DlptSLP6.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-
|
|
1813
|
+
const { runWorkspacePicker } = await import("./boot-DlptSLP6.mjs");
|
|
1814
1814
|
await runWorkspacePicker(session);
|
|
1815
1815
|
return;
|
|
1816
1816
|
}
|
|
@@ -4095,8 +4095,8 @@ function TodoCardView({ todos, isActive }) {
|
|
|
4095
4095
|
//#endregion
|
|
4096
4096
|
//#region src/chat/tui/chat/footer-hints.ts
|
|
4097
4097
|
/** Build the chat footer copy independently of its colors and layout. */
|
|
4098
|
-
function formatChatFooterStatus({ runKind, ctrlCArmed, isShared, hasPendingSteer,
|
|
4099
|
-
const connectHint =
|
|
4098
|
+
function formatChatFooterStatus({ runKind, ctrlCArmed, isShared, hasPendingSteer, actionableCardCount, nonWebChannel }) {
|
|
4099
|
+
const connectHint = actionableCardCount > 1 ? `ctrl+r connect (${actionableCardCount}) · ` : actionableCardCount === 1 ? "ctrl+r connect · " : "";
|
|
4100
4100
|
switch (runKind) {
|
|
4101
4101
|
case "idle":
|
|
4102
4102
|
if (ctrlCArmed) return "press ctrl+c again to quit";
|
|
@@ -4443,7 +4443,7 @@ const keybindGroups = [
|
|
|
4443
4443
|
},
|
|
4444
4444
|
{
|
|
4445
4445
|
keys: "ctrl+r",
|
|
4446
|
-
action: "
|
|
4446
|
+
action: "act on a waiting connect card (auth cards)"
|
|
4447
4447
|
},
|
|
4448
4448
|
{
|
|
4449
4449
|
keys: "pgup / pgdn",
|
|
@@ -4926,7 +4926,7 @@ const slashCommands = [
|
|
|
4926
4926
|
name: "connect",
|
|
4927
4927
|
aliases: [],
|
|
4928
4928
|
argsHint: null,
|
|
4929
|
-
description: "
|
|
4929
|
+
description: "act on a waiting connect card (auth cards)",
|
|
4930
4930
|
action: { kind: "connect" }
|
|
4931
4931
|
},
|
|
4932
4932
|
{
|
|
@@ -5024,6 +5024,93 @@ function printResumeHint(write = (text) => process.stdout.write(text)) {
|
|
|
5024
5024
|
lastConversationId = null;
|
|
5025
5025
|
}
|
|
5026
5026
|
|
|
5027
|
+
//#endregion
|
|
5028
|
+
//#region src/chat/tui/screens/card-picker.tsx
|
|
5029
|
+
/**
|
|
5030
|
+
* Asks which connect card ctrl+r should act on. A conversation can hold
|
|
5031
|
+
* several cards waiting at once (a batch of `platform auth configure` calls),
|
|
5032
|
+
* and the chord can't guess which one the user means — picking the newest
|
|
5033
|
+
* silently strands the rest, since a card left in `launched` or `error` stays
|
|
5034
|
+
* actionable forever. Rendered as an overlay in place of the transcript, like
|
|
5035
|
+
* the model and theme pickers, so the conversation and any live run survive.
|
|
5036
|
+
*/
|
|
5037
|
+
function CardPicker({ cards, onSelect, onCancel }) {
|
|
5038
|
+
const { height } = useTerminalDimensions();
|
|
5039
|
+
const [highlight, setHighlight] = useState(0);
|
|
5040
|
+
const clamped = Math.min(highlight, Math.max(0, cards.length - 1));
|
|
5041
|
+
const visibleRows = Math.max(3, height - 6);
|
|
5042
|
+
const start = windowStart(clamped, cards.length, visibleRows);
|
|
5043
|
+
const windowed = cards.slice(start, start + visibleRows);
|
|
5044
|
+
useKeyboard((key) => {
|
|
5045
|
+
if (key.name === "escape") {
|
|
5046
|
+
onCancel();
|
|
5047
|
+
return;
|
|
5048
|
+
}
|
|
5049
|
+
if (key.name === "up") setHighlight(Math.max(0, clamped - 1));
|
|
5050
|
+
else if (key.name === "down") setHighlight(Math.min(Math.max(0, cards.length - 1), clamped + 1));
|
|
5051
|
+
else if (key.name === "return") {
|
|
5052
|
+
const card = cards[clamped];
|
|
5053
|
+
if (card) onSelect(card);
|
|
5054
|
+
}
|
|
5055
|
+
});
|
|
5056
|
+
useEffect(() => {
|
|
5057
|
+
if (cards.length === 0) onCancel();
|
|
5058
|
+
}, [cards.length, onCancel]);
|
|
5059
|
+
if (cards.length === 0) return null;
|
|
5060
|
+
return /* @__PURE__ */ jsxs("box", {
|
|
5061
|
+
style: {
|
|
5062
|
+
flexDirection: "column",
|
|
5063
|
+
flexGrow: 1
|
|
5064
|
+
},
|
|
5065
|
+
children: [
|
|
5066
|
+
/* @__PURE__ */ jsx("text", {
|
|
5067
|
+
fg: theme.accent,
|
|
5068
|
+
children: "connect"
|
|
5069
|
+
}),
|
|
5070
|
+
/* @__PURE__ */ jsx("box", {
|
|
5071
|
+
style: {
|
|
5072
|
+
flexDirection: "column",
|
|
5073
|
+
flexGrow: 1,
|
|
5074
|
+
marginTop: 1
|
|
5075
|
+
},
|
|
5076
|
+
children: windowed.map((card, i) => {
|
|
5077
|
+
const selected = start + i === clamped;
|
|
5078
|
+
const waiting = waitingOn(card);
|
|
5079
|
+
const label = card.card.button?.label ?? "";
|
|
5080
|
+
return /* @__PURE__ */ jsxs("text", {
|
|
5081
|
+
fg: selected ? theme.accent : theme.fg,
|
|
5082
|
+
children: [
|
|
5083
|
+
selected ? "› " : " ",
|
|
5084
|
+
"⚿ ",
|
|
5085
|
+
card.card.title,
|
|
5086
|
+
label ? /* @__PURE__ */ jsxs("span", {
|
|
5087
|
+
fg: theme.muted,
|
|
5088
|
+
children: [" · ", label]
|
|
5089
|
+
}) : null,
|
|
5090
|
+
waiting ? /* @__PURE__ */ jsxs("span", {
|
|
5091
|
+
fg: theme.dim,
|
|
5092
|
+
children: [" · ", waiting]
|
|
5093
|
+
}) : null
|
|
5094
|
+
]
|
|
5095
|
+
}, card.id);
|
|
5096
|
+
})
|
|
5097
|
+
}),
|
|
5098
|
+
/* @__PURE__ */ jsxs("text", {
|
|
5099
|
+
fg: theme.dim,
|
|
5100
|
+
children: [cards.length, " waiting · ↑/↓ move · ↵ select · esc cancel"]
|
|
5101
|
+
})
|
|
5102
|
+
]
|
|
5103
|
+
});
|
|
5104
|
+
}
|
|
5105
|
+
/** Why a card is still on the list, for the rows that aren't simply untouched. */
|
|
5106
|
+
function waitingOn(card) {
|
|
5107
|
+
switch (card.status) {
|
|
5108
|
+
case "launched": return "finish in your browser";
|
|
5109
|
+
case "error": return card.detail ?? "failed";
|
|
5110
|
+
default: return null;
|
|
5111
|
+
}
|
|
5112
|
+
}
|
|
5113
|
+
|
|
5027
5114
|
//#endregion
|
|
5028
5115
|
//#region src/chat/tui/screens/model-picker.tsx
|
|
5029
5116
|
/**
|
|
@@ -8087,6 +8174,7 @@ function ChatScreen({ agent, conversation }) {
|
|
|
8087
8174
|
const [input, setInput] = useState("");
|
|
8088
8175
|
const [run, setRun] = useState({ kind: "idle" });
|
|
8089
8176
|
const [model, setModel] = useState(agent.model ?? null);
|
|
8177
|
+
const [cardPickerOpen, setCardPickerOpen] = useState(false);
|
|
8090
8178
|
const [modelPickerOpen, setModelPickerOpen] = useState(false);
|
|
8091
8179
|
const [themePickerOpen, setThemePickerOpen] = useState(false);
|
|
8092
8180
|
const [helpOpen, setHelpOpen] = useState(false);
|
|
@@ -8200,6 +8288,7 @@ function ChatScreen({ agent, conversation }) {
|
|
|
8200
8288
|
};
|
|
8201
8289
|
}, [
|
|
8202
8290
|
grantPrompt,
|
|
8291
|
+
cardPickerOpen,
|
|
8203
8292
|
modelPickerOpen,
|
|
8204
8293
|
themePickerOpen,
|
|
8205
8294
|
helpOpen,
|
|
@@ -8555,10 +8644,15 @@ function ChatScreen({ agent, conversation }) {
|
|
|
8555
8644
|
portalClient,
|
|
8556
8645
|
portal.status
|
|
8557
8646
|
]);
|
|
8558
|
-
const
|
|
8559
|
-
const
|
|
8560
|
-
|
|
8561
|
-
|
|
8647
|
+
const promptForCards = useCallback(() => {
|
|
8648
|
+
const targets = itemsRef.current.filter(isActionableCard);
|
|
8649
|
+
const [only] = targets;
|
|
8650
|
+
if (!only) return false;
|
|
8651
|
+
if (targets.length === 1) {
|
|
8652
|
+
runCardAction(only);
|
|
8653
|
+
return true;
|
|
8654
|
+
}
|
|
8655
|
+
setCardPickerOpen(true);
|
|
8562
8656
|
return true;
|
|
8563
8657
|
}, [runCardAction]);
|
|
8564
8658
|
const handleCredInput = useCallback((displayed) => {
|
|
@@ -8803,7 +8897,7 @@ function ChatScreen({ agent, conversation }) {
|
|
|
8803
8897
|
stageAttachment(image);
|
|
8804
8898
|
}, [stageAttachment]);
|
|
8805
8899
|
usePaste((event) => {
|
|
8806
|
-
if (modelPickerOpen || themePickerOpen || helpOpen || credPromptOpen || grantPrompt || nonWebChannel) return;
|
|
8900
|
+
if (cardPickerOpen || modelPickerOpen || themePickerOpen || helpOpen || credPromptOpen || grantPrompt || nonWebChannel) return;
|
|
8807
8901
|
const text = event.metadata?.kind === "binary" ? "" : decodePasteBytes(event.bytes);
|
|
8808
8902
|
const route = routePaste({
|
|
8809
8903
|
kind: event.metadata?.kind,
|
|
@@ -8852,6 +8946,7 @@ function ChatScreen({ agent, conversation }) {
|
|
|
8852
8946
|
if (composer.plainText === "" && inputRef.current !== "") applyComposerText(inputRef.current, "end");
|
|
8853
8947
|
}, [
|
|
8854
8948
|
grantPrompt,
|
|
8949
|
+
cardPickerOpen,
|
|
8855
8950
|
modelPickerOpen,
|
|
8856
8951
|
themePickerOpen,
|
|
8857
8952
|
helpOpen,
|
|
@@ -9024,7 +9119,7 @@ function ChatScreen({ agent, conversation }) {
|
|
|
9024
9119
|
openInBrowser();
|
|
9025
9120
|
break;
|
|
9026
9121
|
case "connect":
|
|
9027
|
-
if (!
|
|
9122
|
+
if (!promptForCards()) useStore.getState().showToast({ message: "no connect card waiting for action" });
|
|
9028
9123
|
break;
|
|
9029
9124
|
case "help":
|
|
9030
9125
|
setHelpOpen(true);
|
|
@@ -9063,7 +9158,7 @@ function ChatScreen({ agent, conversation }) {
|
|
|
9063
9158
|
model,
|
|
9064
9159
|
portal.status,
|
|
9065
9160
|
portal.grantedAgentIds,
|
|
9066
|
-
|
|
9161
|
+
promptForCards
|
|
9067
9162
|
]);
|
|
9068
9163
|
const submit = useCallback(() => {
|
|
9069
9164
|
const staged = attachments.filter((a) => a.status !== "error");
|
|
@@ -9118,7 +9213,7 @@ function ChatScreen({ agent, conversation }) {
|
|
|
9118
9213
|
}
|
|
9119
9214
|
if (reviewFocused) return;
|
|
9120
9215
|
}
|
|
9121
|
-
if (modelPickerOpen || themePickerOpen || helpOpen) return;
|
|
9216
|
+
if (cardPickerOpen || modelPickerOpen || themePickerOpen || helpOpen) return;
|
|
9122
9217
|
if (grantPrompt) {
|
|
9123
9218
|
if (key.name === "y") {
|
|
9124
9219
|
confirmGrant();
|
|
@@ -9210,7 +9305,7 @@ function ChatScreen({ agent, conversation }) {
|
|
|
9210
9305
|
return;
|
|
9211
9306
|
}
|
|
9212
9307
|
if (key.name === "r" && key.ctrl) {
|
|
9213
|
-
|
|
9308
|
+
promptForCards();
|
|
9214
9309
|
return;
|
|
9215
9310
|
}
|
|
9216
9311
|
if (key.name === "t" && key.ctrl) {
|
|
@@ -9286,23 +9381,31 @@ function ChatScreen({ agent, conversation }) {
|
|
|
9286
9381
|
}
|
|
9287
9382
|
});
|
|
9288
9383
|
const hasPendingSteer = items.some((m) => m.kind === "pending-steer");
|
|
9289
|
-
const
|
|
9384
|
+
const actionableCards = useMemo(() => items.filter(isActionableCard), [items]);
|
|
9290
9385
|
const statusText = useMemo(() => formatChatFooterStatus({
|
|
9291
9386
|
runKind: run.kind,
|
|
9292
9387
|
ctrlCArmed,
|
|
9293
9388
|
isShared,
|
|
9294
9389
|
hasPendingSteer,
|
|
9295
|
-
|
|
9390
|
+
actionableCardCount: actionableCards.length,
|
|
9296
9391
|
nonWebChannel: nonWebChannel !== null
|
|
9297
9392
|
}), [
|
|
9298
9393
|
run.kind,
|
|
9299
9394
|
ctrlCArmed,
|
|
9300
9395
|
isShared,
|
|
9301
9396
|
hasPendingSteer,
|
|
9302
|
-
|
|
9397
|
+
actionableCards.length,
|
|
9303
9398
|
nonWebChannel
|
|
9304
9399
|
]);
|
|
9305
9400
|
const modelHint = formatModelHint(model);
|
|
9401
|
+
if (cardPickerOpen) return /* @__PURE__ */ jsx(CardPicker, {
|
|
9402
|
+
cards: actionableCards,
|
|
9403
|
+
onSelect: (card) => {
|
|
9404
|
+
setCardPickerOpen(false);
|
|
9405
|
+
runCardAction(card);
|
|
9406
|
+
},
|
|
9407
|
+
onCancel: () => setCardPickerOpen(false)
|
|
9408
|
+
});
|
|
9306
9409
|
if (modelPickerOpen) return /* @__PURE__ */ jsx(ModelPicker, {
|
|
9307
9410
|
agentId: agent.id,
|
|
9308
9411
|
currentModel: model,
|