skydive-cli 0.4.0-beta.1174 → 0.4.0-beta.1319
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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { C as ensureActiveOrganization, D as setActiveWorkspace, E as listWorkspaces, O as name, T as getSessionIdentity, a as installCrashHandler, k as version, t as maybeStartProfiling, u as brandHelpArt, w as getActiveWorkspaceId, x as themes } from "./profiler-
|
|
2
|
+
import { C as ensureActiveOrganization, D as setActiveWorkspace, E as listWorkspaces, O as name, T as getSessionIdentity, a as installCrashHandler, k as version, t as maybeStartProfiling, u as brandHelpArt, w as getActiveWorkspaceId, x as themes } from "./profiler-C4l07OBf.mjs";
|
|
3
3
|
import { A as getStoredApiKeyWorkspaceName, C as getLastSeenVersion, F as resolveManagementAuth, I as resolveSession, M as resolveAppUrl, N as resolveChatAuth, O as getShareMachineDefault, P as resolveConfig, R as saveConfig, S as getConfigPath, T as getPromptHistoryPath, V as setLastSeenVersion, _ as API_KEY_PREFIX, b as PREFERENCES, g as API_KEY_FAMILY_PREFIX, h as API_KEYS_URL, i as resolveAgent, j as getUpdateCheckDisabled, k as getStoredApiKeyId, v as DEFAULT_API_URL, w as getPreference, x as deleteConfig, z as saveSession } from "./print-DA8WzgzH.mjs";
|
|
4
4
|
import { n as printError, r as printTable, t as output } from "./output-DYzzdXYV.mjs";
|
|
5
5
|
import { n as createRestClient, t as HttpError } from "./rest-CtEF_ZDf.mjs";
|
|
@@ -1514,7 +1514,7 @@ const importCommand = {
|
|
|
1514
1514
|
process.exit(1);
|
|
1515
1515
|
}
|
|
1516
1516
|
}
|
|
1517
|
-
const { runChat } = await import("./boot-
|
|
1517
|
+
const { runChat } = await import("./boot-COm0nT7p.mjs");
|
|
1518
1518
|
await runChat({
|
|
1519
1519
|
appUrl,
|
|
1520
1520
|
sessionToken: session.value.sessionToken,
|
|
@@ -1926,7 +1926,7 @@ const chatCommand = {
|
|
|
1926
1926
|
sessionToken: auth.value.token,
|
|
1927
1927
|
agentSelector: argv.agent ?? null
|
|
1928
1928
|
});
|
|
1929
|
-
const { runChat } = await import("./boot-
|
|
1929
|
+
const { runChat } = await import("./boot-COm0nT7p.mjs");
|
|
1930
1930
|
await runChat({
|
|
1931
1931
|
appUrl: auth.value.appUrl,
|
|
1932
1932
|
sessionToken: auth.value.token,
|
|
@@ -2285,7 +2285,7 @@ const switchCommand = {
|
|
|
2285
2285
|
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.");
|
|
2286
2286
|
process.exit(1);
|
|
2287
2287
|
}
|
|
2288
|
-
const { runWorkspacePicker } = await import("./boot-
|
|
2288
|
+
const { runWorkspacePicker } = await import("./boot-COm0nT7p.mjs");
|
|
2289
2289
|
await runWorkspacePicker(session);
|
|
2290
2290
|
return;
|
|
2291
2291
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { D as setActiveWorkspace, E as listWorkspaces, S as themesForMode, _ as themeForMode, a as installCrashHandler, b as themeVersion, c as MARK_CELLS, d as DEFAULT_THEME_ID, f as applyTheme, g as theme, h as noColorRequested, i as writeArtifact, l as WORDMARK, m as monoTheme, n as profilingEnabled, o as buildCrashReport, p as findTheme, r as record, s as writeCrashReport, v as themeMode, w as getActiveWorkspaceId, y as themeModeFromColorFgBg } from "./profiler-
|
|
2
|
+
import { D as setActiveWorkspace, E as listWorkspaces, S as themesForMode, _ as themeForMode, a as installCrashHandler, b as themeVersion, c as MARK_CELLS, d as DEFAULT_THEME_ID, f as applyTheme, g as theme, h as noColorRequested, i as writeArtifact, l as WORDMARK, m as monoTheme, n as profilingEnabled, o as buildCrashReport, p as findTheme, r as record, s as writeCrashReport, v as themeMode, w as getActiveWorkspaceId, y as themeModeFromColorFgBg } from "./profiler-C4l07OBf.mjs";
|
|
3
3
|
import { B as saveTheme, D as getSavedTheme, E as getReviewStateDir, L as resolveWebUrl, S as getConfigPath, c as cardActionErrorMessage, d as reconcileMaskedInput, f as resolveConnectUrl, i as resolveAgent, l as parseExternalOauthConnectParams, m as specKeyFor, p as parseConnectCard, s as MASK_CHAR, u as parseOauthConnectParams, v as DEFAULT_API_URL, y as DEFAULT_APP_URL } from "./print-DA8WzgzH.mjs";
|
|
4
4
|
import { a as errorMessage, i as sendErrorMessage, n as createRestClient, o as isRecord, r as errorDetail, t as HttpError } from "./rest-CtEF_ZDf.mjs";
|
|
5
5
|
import { i as billingBlockedOutcomeFromSendResponse } from "./billing-blocked-CwfG1BTR.mjs";
|
|
@@ -48,6 +48,58 @@ function toastColor(variant) {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/chat/tui/early-input.ts
|
|
53
|
+
/**
|
|
54
|
+
* Buffering for keystrokes typed BEFORE the chat composer exists.
|
|
55
|
+
*
|
|
56
|
+
* When the CLI boots straight into a conversation (`skydive chat --new`, or a
|
|
57
|
+
* seeded `skydive import`), it must resolve the agent roster over the network
|
|
58
|
+
* before the chat screen — and its composer — can mount. During that window
|
|
59
|
+
* the splash screen is up and there is no textarea to receive input, so a user
|
|
60
|
+
* who starts typing immediately would lose every character.
|
|
61
|
+
*
|
|
62
|
+
* These helpers accumulate that early input as plain text; the chat screen
|
|
63
|
+
* drains it into the composer on mount so nothing typed during the load is
|
|
64
|
+
* dropped. This is deliberately a text buffer, not a queue of key events: the
|
|
65
|
+
* composer is a plain single-field editor here, so replaying the resulting
|
|
66
|
+
* string (via `composer.setText`) reproduces exactly what the user meant to
|
|
67
|
+
* type, and stays trivially unit-testable without an OpenTUI renderer.
|
|
68
|
+
*/
|
|
69
|
+
/**
|
|
70
|
+
* Whether a key is an ordinary printable character we should buffer as text.
|
|
71
|
+
*
|
|
72
|
+
* Excludes anything with a modifier (ctrl/meta/super/hyper — those are
|
|
73
|
+
* shortcuts, not text) and any named non-character key (enter, arrows, tab,
|
|
74
|
+
* escape, function keys, …). A printable stroke arrives with its character in
|
|
75
|
+
* `sequence` and a `name` that is that same single character (or empty for
|
|
76
|
+
* some symbols), never a multi-letter key name like `return`/`backspace`.
|
|
77
|
+
*/
|
|
78
|
+
function isTextKey(key) {
|
|
79
|
+
if (key.ctrl || key.meta || key.super || key.hyper) return false;
|
|
80
|
+
const seq = key.sequence;
|
|
81
|
+
if (seq.length !== 1) return false;
|
|
82
|
+
const code = seq.codePointAt(0);
|
|
83
|
+
if (code === void 0) return false;
|
|
84
|
+
if (code < 32 || code === 127) return false;
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
/** Whether a key is Backspace/Delete-left (erase one buffered character). */
|
|
88
|
+
function isBackspaceKey(key) {
|
|
89
|
+
return !key.ctrl && !key.meta && key.name === "backspace";
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Fold one key into the early-input buffer. Printable characters append,
|
|
93
|
+
* backspace erases the last character, everything else (enter, arrows,
|
|
94
|
+
* shortcuts) is ignored — we only reconstruct the draft text, not caret moves
|
|
95
|
+
* or submission, which the real composer owns once it takes over.
|
|
96
|
+
*/
|
|
97
|
+
function reduceEarlyInput(buffer, key) {
|
|
98
|
+
if (isTextKey(key)) return buffer + key.sequence;
|
|
99
|
+
if (isBackspaceKey(key)) return buffer.slice(0, -1);
|
|
100
|
+
return buffer;
|
|
101
|
+
}
|
|
102
|
+
|
|
51
103
|
//#endregion
|
|
52
104
|
//#region src/chat/state/store.ts
|
|
53
105
|
const initialPortalUi = {
|
|
@@ -81,6 +133,7 @@ const useStore = create((set, get) => ({
|
|
|
81
133
|
seedPrompt: null,
|
|
82
134
|
autoGrantMachine: false,
|
|
83
135
|
newConversationIntent: false,
|
|
136
|
+
earlyInput: "",
|
|
84
137
|
goTo: (screen) => set({
|
|
85
138
|
screen,
|
|
86
139
|
chatTitle: initialChatTitle(screen)
|
|
@@ -138,7 +191,16 @@ const useStore = create((set, get) => ({
|
|
|
138
191
|
prompt
|
|
139
192
|
} })),
|
|
140
193
|
showToast: (input) => set({ toast: createToast(input) }),
|
|
141
|
-
dismissToast: (id) => set((state) => state.toast?.id === id ? { toast: null } : {})
|
|
194
|
+
dismissToast: (id) => set((state) => state.toast?.id === id ? { toast: null } : {}),
|
|
195
|
+
appendEarlyInput: (key) => set((state) => {
|
|
196
|
+
const next = reduceEarlyInput(state.earlyInput, key);
|
|
197
|
+
return next === state.earlyInput ? {} : { earlyInput: next };
|
|
198
|
+
}),
|
|
199
|
+
takeEarlyInput: () => {
|
|
200
|
+
const { earlyInput } = get();
|
|
201
|
+
if (earlyInput !== "") set({ earlyInput: "" });
|
|
202
|
+
return earlyInput;
|
|
203
|
+
}
|
|
142
204
|
}));
|
|
143
205
|
|
|
144
206
|
//#endregion
|
|
@@ -1472,7 +1534,7 @@ function StatusBar({ rightHint }) {
|
|
|
1472
1534
|
const portal = useStore((s) => s.portal);
|
|
1473
1535
|
const left = headerLeftLabel(appUrl, workspaceName);
|
|
1474
1536
|
const middle = screenLabel(screen, chatTitle);
|
|
1475
|
-
const share = portalIndicator(portal);
|
|
1537
|
+
const share = portalIndicator(portal, screenAgentId(screen));
|
|
1476
1538
|
return /* @__PURE__ */ jsxs("box", {
|
|
1477
1539
|
style: {
|
|
1478
1540
|
flexDirection: "row",
|
|
@@ -1504,23 +1566,40 @@ function StatusBar({ rightHint }) {
|
|
|
1504
1566
|
]
|
|
1505
1567
|
});
|
|
1506
1568
|
}
|
|
1507
|
-
|
|
1569
|
+
/**
|
|
1570
|
+
* The share indicator, which answers exactly one question: can the agent on
|
|
1571
|
+
* screen run commands on this machine right now? Not "is the portal
|
|
1572
|
+
* connected" — the connection is a per-machine fact, access is per agent, and
|
|
1573
|
+
* a badge that tracks the former tells a user who just declined that the agent
|
|
1574
|
+
* is in.
|
|
1575
|
+
*
|
|
1576
|
+
* So it is scoped to the current agent and shown only once that agent holds a
|
|
1577
|
+
* grant. Everything else — no agent on screen, portal off, connected but this
|
|
1578
|
+
* agent ungranted, still connecting — renders as the off state (nothing), which
|
|
1579
|
+
* is the truthful reading: this agent cannot reach the machine.
|
|
1580
|
+
*
|
|
1581
|
+
* The one exception is an error, and only for an agent that IS granted: its
|
|
1582
|
+
* access is supposed to be live and isn't, which the user needs to see.
|
|
1583
|
+
*/
|
|
1584
|
+
function portalIndicator(portal, agentId) {
|
|
1585
|
+
if (!agentId || !portal.grantedAgentIds.includes(agentId)) return null;
|
|
1508
1586
|
switch (portal.status) {
|
|
1509
|
-
case "off":
|
|
1510
|
-
case "connecting": return
|
|
1511
|
-
text: "◌ sharing…",
|
|
1512
|
-
color: theme.warning
|
|
1513
|
-
};
|
|
1587
|
+
case "off":
|
|
1588
|
+
case "connecting": return null;
|
|
1514
1589
|
case "connected": return {
|
|
1515
|
-
text: "● machine
|
|
1590
|
+
text: "● machine connected",
|
|
1516
1591
|
color: theme.success
|
|
1517
1592
|
};
|
|
1518
1593
|
case "error": return {
|
|
1519
|
-
text: "●
|
|
1594
|
+
text: "● machine error",
|
|
1520
1595
|
color: theme.error
|
|
1521
1596
|
};
|
|
1522
1597
|
}
|
|
1523
1598
|
}
|
|
1599
|
+
/** The agent whose access the indicator speaks for, if a screen names one. */
|
|
1600
|
+
function screenAgentId(screen) {
|
|
1601
|
+
return screen.kind === "chat" || screen.kind === "conversation-picker" ? screen.agent.id : null;
|
|
1602
|
+
}
|
|
1524
1603
|
/**
|
|
1525
1604
|
* The per-screen label, split into its parts: the screen's own `title` and,
|
|
1526
1605
|
* when the screen belongs to an agent, that `agentName`. Kept structured so the
|
|
@@ -10174,7 +10253,7 @@ function ChatScreen({ agent, conversation }) {
|
|
|
10174
10253
|
hadTodosRef.current = hasTodos;
|
|
10175
10254
|
}, [todos]);
|
|
10176
10255
|
const [historyLoaded, setHistoryLoaded] = useState(initialConversationId === null);
|
|
10177
|
-
const [input, setInput] = useState(
|
|
10256
|
+
const [input, setInput] = useState(() => useStore.getState().takeEarlyInput());
|
|
10178
10257
|
const [run, setRun] = useState({ kind: "idle" });
|
|
10179
10258
|
const [model, setModel] = useState(agent.model ?? null);
|
|
10180
10259
|
const [cardPickerOpen, setCardPickerOpen] = useState(false);
|
|
@@ -12445,7 +12524,12 @@ function App({ appUrl, sessionToken, authKind, shareMachine, promptHistoryPath,
|
|
|
12445
12524
|
setClients,
|
|
12446
12525
|
fail
|
|
12447
12526
|
]);
|
|
12527
|
+
const appendEarlyInput = useStore((s) => s.appendEarlyInput);
|
|
12448
12528
|
useKeyboard((key) => {
|
|
12529
|
+
if (screen.kind === "splash" && !(key.name === "c" && key.ctrl)) {
|
|
12530
|
+
appendEarlyInput(key);
|
|
12531
|
+
return;
|
|
12532
|
+
}
|
|
12449
12533
|
if (key.name === "c" && key.ctrl && screen.kind !== "chat") {
|
|
12450
12534
|
useStore.getState().portalClient?.dispose();
|
|
12451
12535
|
agentHost.dispose();
|