skydive-cli 0.1.0-beta.50 → 0.1.0-beta.65
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
|
@@ -13,7 +13,7 @@ import fs from "node:fs";
|
|
|
13
13
|
import zlib from "node:zlib";
|
|
14
14
|
|
|
15
15
|
//#region package.json
|
|
16
|
-
var version$1 = "0.1.0-beta.
|
|
16
|
+
var version$1 = "0.1.0-beta.65";
|
|
17
17
|
|
|
18
18
|
//#endregion
|
|
19
19
|
//#region src/types.ts
|
|
@@ -447,7 +447,7 @@ async function getActiveWorkspaceId({ appUrl, sessionToken }) {
|
|
|
447
447
|
}
|
|
448
448
|
async function setActiveWorkspace({ appUrl, sessionToken, organizationId }) {
|
|
449
449
|
try {
|
|
450
|
-
const res = await fetch(`${appUrl}/api/
|
|
450
|
+
const res = await fetch(`${appUrl}/api/v1/workspaces/switch`, {
|
|
451
451
|
method: "POST",
|
|
452
452
|
headers: {
|
|
453
453
|
...authHeaders(sessionToken),
|
|
@@ -455,7 +455,7 @@ async function setActiveWorkspace({ appUrl, sessionToken, organizationId }) {
|
|
|
455
455
|
},
|
|
456
456
|
body: JSON.stringify({ organizationId })
|
|
457
457
|
});
|
|
458
|
-
if (!res.ok) return err({ message: `failed to
|
|
458
|
+
if (!res.ok) return err({ message: `failed to switch workspace (${res.status})` });
|
|
459
459
|
return ok(void 0);
|
|
460
460
|
} catch (e) {
|
|
461
461
|
return err({ message: e instanceof Error ? e.message : String(e) });
|
|
@@ -2046,7 +2046,7 @@ const chatCommand = {
|
|
|
2046
2046
|
printError(`Unknown theme "${themeId}". Valid themes: ${themes.map((t) => t.id).join(", ")}`);
|
|
2047
2047
|
process.exit(1);
|
|
2048
2048
|
}
|
|
2049
|
-
const { runChat } = await import("./boot-
|
|
2049
|
+
const { runChat } = await import("./boot-BUk9yMvA.mjs");
|
|
2050
2050
|
await runChat({
|
|
2051
2051
|
appUrl,
|
|
2052
2052
|
sessionToken: session.value.sessionToken,
|
|
@@ -2137,7 +2137,7 @@ async function runList(argv, { hint }) {
|
|
|
2137
2137
|
w.name,
|
|
2138
2138
|
w.slug
|
|
2139
2139
|
]));
|
|
2140
|
-
if (hint && !argv.quiet) console.log("\nRun `skydive workspace switch
|
|
2140
|
+
if (hint && !argv.quiet) console.log("\nRun `skydive workspace switch` to pick a workspace, or pass its slug directly.");
|
|
2141
2141
|
}
|
|
2142
2142
|
const listCommand = {
|
|
2143
2143
|
command: "list",
|
|
@@ -2145,15 +2145,28 @@ const listCommand = {
|
|
|
2145
2145
|
handler: (argv) => runList(argv, { hint: false })
|
|
2146
2146
|
};
|
|
2147
2147
|
const switchCommand = {
|
|
2148
|
-
command: "switch
|
|
2148
|
+
command: "switch [workspace]",
|
|
2149
2149
|
describe: "Switch which workspace `skydive chat` uses",
|
|
2150
2150
|
builder: (y) => y.positional("workspace", {
|
|
2151
2151
|
type: "string",
|
|
2152
|
-
demandOption:
|
|
2152
|
+
demandOption: false,
|
|
2153
2153
|
describe: "Workspace slug, name, or ID"
|
|
2154
2154
|
}),
|
|
2155
2155
|
handler: async (argv) => {
|
|
2156
2156
|
const session = requireSession(argv);
|
|
2157
|
+
if (!argv.workspace) {
|
|
2158
|
+
if (argv.json || argv.quiet || isNonInteractive()) {
|
|
2159
|
+
printError("Interactive workspace switching needs a terminal. Pass a workspace slug, name, or ID.");
|
|
2160
|
+
process.exit(1);
|
|
2161
|
+
}
|
|
2162
|
+
if (await ensureBunAndReexec((message) => process.stderr.write(`${message}\n`)) === "unavailable") {
|
|
2163
|
+
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.");
|
|
2164
|
+
process.exit(1);
|
|
2165
|
+
}
|
|
2166
|
+
const { runWorkspacePicker } = await import("./boot-BUk9yMvA.mjs");
|
|
2167
|
+
await runWorkspacePicker(session);
|
|
2168
|
+
return;
|
|
2169
|
+
}
|
|
2157
2170
|
const workspaces = await listWorkspaces(session);
|
|
2158
2171
|
if (workspaces.isErr()) {
|
|
2159
2172
|
printError(workspaces.error.message);
|
|
@@ -2277,4 +2290,4 @@ function resolveArgv(args, tty = {
|
|
|
2277
2290
|
createCli(resolveArgv(hideBin(process.argv))).parse();
|
|
2278
2291
|
|
|
2279
2292
|
//#endregion
|
|
2280
|
-
export {
|
|
2293
|
+
export { getSavedTheme as _, noColorRequested as a, themeMode as c, themesForMode as d, getActiveWorkspaceId as f, DEFAULT_APP_URL as g, DEFAULT_API_URL as h, monoTheme as i, themeModeFromColorFgBg as l, setActiveWorkspace as m, applyTheme as n, theme as o, listWorkspaces as p, findTheme as r, themeForMode as s, DEFAULT_THEME_ID as t, themeVersion as u, resolveWebUrl as v, saveTheme as y };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { i as createRestClient, n as resolveAgent, r as HttpError } from "./print-BtMdNPJR.mjs";
|
|
3
|
-
import { _ as
|
|
3
|
+
import { _ as getSavedTheme, a as noColorRequested, c as themeMode, d as themesForMode, f as getActiveWorkspaceId, g as DEFAULT_APP_URL, h as DEFAULT_API_URL, i as monoTheme, l as themeModeFromColorFgBg, m as setActiveWorkspace, n as applyTheme, o as theme, p as listWorkspaces, r as findTheme, s as themeForMode, t as DEFAULT_THEME_ID, u as themeVersion, v as resolveWebUrl, y as saveTheme } from "./bin.mjs";
|
|
4
4
|
import path, { basename, isAbsolute, join, win32 } from "node:path";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import open from "open";
|
|
@@ -1226,6 +1226,7 @@ function screenLabel(screen, chatTitle) {
|
|
|
1226
1226
|
case "error": return "";
|
|
1227
1227
|
case "agent-picker": return "pick an agent";
|
|
1228
1228
|
case "agent-create": return "create an agent";
|
|
1229
|
+
case "workspace-picker": return "switch workspace";
|
|
1229
1230
|
case "conversation-picker": return `${screen.agent.name} · pick a conversation`;
|
|
1230
1231
|
case "chat": {
|
|
1231
1232
|
const c = screen.conversation;
|
|
@@ -1258,7 +1259,8 @@ function AgentPickerScreen() {
|
|
|
1258
1259
|
const [cache, setCache] = useState({});
|
|
1259
1260
|
const [state, setState] = useState({ kind: "loading" });
|
|
1260
1261
|
useKeyboard((key) => {
|
|
1261
|
-
if (key.name === "
|
|
1262
|
+
if (key.name === "w" && key.ctrl) goTo({ kind: "workspace-picker" });
|
|
1263
|
+
else if (key.name === "n" && key.ctrl) goTo({ kind: "agent-create" });
|
|
1262
1264
|
else if (key.name === "tab") setScope((s) => s === "mine" ? "org" : "mine");
|
|
1263
1265
|
});
|
|
1264
1266
|
useEffect(() => {
|
|
@@ -1324,7 +1326,7 @@ function AgentPickerScreen() {
|
|
|
1324
1326
|
});
|
|
1325
1327
|
if (state.agents.length === 0) return /* @__PURE__ */ jsx("text", {
|
|
1326
1328
|
fg: theme.muted,
|
|
1327
|
-
children: scope === "mine" ? "no agents of yours yet. press tab to see all agents, or ctrl+n to create one." : "no agents in this workspace. press ctrl+n to create one."
|
|
1329
|
+
children: scope === "mine" ? "no agents of yours yet. press tab to see all agents, ctrl+w to switch workspace, or ctrl+n to create one." : "no agents in this workspace. press ctrl+w to switch workspace, or ctrl+n to create one."
|
|
1328
1330
|
});
|
|
1329
1331
|
return /* @__PURE__ */ jsx(FilterableAgentList, {
|
|
1330
1332
|
agents: state.agents,
|
|
@@ -1391,7 +1393,7 @@ function FilterableAgentList({ agents, scope, onPick }) {
|
|
|
1391
1393
|
" ",
|
|
1392
1394
|
"· tab ",
|
|
1393
1395
|
scope === "mine" ? "all" : "mine",
|
|
1394
|
-
" · ↑/↓ move · ↵ open · ctrl+n new"
|
|
1396
|
+
" · ↑/↓ move · ↵ open · ctrl+w workspace · ctrl+n new"
|
|
1395
1397
|
]
|
|
1396
1398
|
}),
|
|
1397
1399
|
/* @__PURE__ */ jsx("box", {
|
|
@@ -1568,6 +1570,146 @@ function AgentCreateScreen() {
|
|
|
1568
1570
|
});
|
|
1569
1571
|
}
|
|
1570
1572
|
|
|
1573
|
+
//#endregion
|
|
1574
|
+
//#region src/chat/tui/screens/workspace-picker.tsx
|
|
1575
|
+
function WorkspacePicker({ appUrl, sessionToken, onSelect, onCancel }) {
|
|
1576
|
+
const { height } = useTerminalDimensions();
|
|
1577
|
+
const [state, setState] = useState({ kind: "loading" });
|
|
1578
|
+
const [highlight, setHighlight] = useState(0);
|
|
1579
|
+
const [switching, setSwitching] = useState(false);
|
|
1580
|
+
useEffect(() => {
|
|
1581
|
+
let cancelled = false;
|
|
1582
|
+
(async () => {
|
|
1583
|
+
const [workspaces, activeId] = await Promise.all([listWorkspaces({
|
|
1584
|
+
appUrl,
|
|
1585
|
+
sessionToken
|
|
1586
|
+
}), getActiveWorkspaceId({
|
|
1587
|
+
appUrl,
|
|
1588
|
+
sessionToken
|
|
1589
|
+
})]);
|
|
1590
|
+
if (cancelled) return;
|
|
1591
|
+
if (workspaces.isErr()) {
|
|
1592
|
+
setState({
|
|
1593
|
+
kind: "error",
|
|
1594
|
+
message: workspaces.error.message
|
|
1595
|
+
});
|
|
1596
|
+
return;
|
|
1597
|
+
}
|
|
1598
|
+
if (activeId.isErr()) {
|
|
1599
|
+
setState({
|
|
1600
|
+
kind: "error",
|
|
1601
|
+
message: activeId.error.message
|
|
1602
|
+
});
|
|
1603
|
+
return;
|
|
1604
|
+
}
|
|
1605
|
+
setHighlight(Math.max(0, workspaces.value.findIndex((workspace) => workspace.id === activeId.value)));
|
|
1606
|
+
setState({
|
|
1607
|
+
kind: "ready",
|
|
1608
|
+
workspaces: workspaces.value,
|
|
1609
|
+
activeId: activeId.value
|
|
1610
|
+
});
|
|
1611
|
+
})();
|
|
1612
|
+
return () => {
|
|
1613
|
+
cancelled = true;
|
|
1614
|
+
};
|
|
1615
|
+
}, [appUrl, sessionToken]);
|
|
1616
|
+
const rows = state.kind === "ready" ? state.workspaces : [];
|
|
1617
|
+
const clamped = Math.min(highlight, Math.max(0, rows.length - 1));
|
|
1618
|
+
useKeyboard((key) => {
|
|
1619
|
+
if (switching) return;
|
|
1620
|
+
if (key.name === "escape" || key.name === "c" && key.ctrl) onCancel();
|
|
1621
|
+
else if (key.name === "up") setHighlight(Math.max(0, clamped - 1));
|
|
1622
|
+
else if (key.name === "down") setHighlight(Math.min(rows.length - 1, clamped + 1));
|
|
1623
|
+
else if (key.name === "return") {
|
|
1624
|
+
const workspace = rows[clamped];
|
|
1625
|
+
if (!workspace) return;
|
|
1626
|
+
setSwitching(true);
|
|
1627
|
+
(async () => {
|
|
1628
|
+
const result = await setActiveWorkspace({
|
|
1629
|
+
appUrl,
|
|
1630
|
+
sessionToken,
|
|
1631
|
+
organizationId: workspace.id
|
|
1632
|
+
});
|
|
1633
|
+
if (result.isErr()) {
|
|
1634
|
+
setState({
|
|
1635
|
+
kind: "error",
|
|
1636
|
+
message: result.error.message
|
|
1637
|
+
});
|
|
1638
|
+
setSwitching(false);
|
|
1639
|
+
return;
|
|
1640
|
+
}
|
|
1641
|
+
onSelect(workspace);
|
|
1642
|
+
})();
|
|
1643
|
+
}
|
|
1644
|
+
});
|
|
1645
|
+
if (state.kind === "loading") return /* @__PURE__ */ jsx("text", {
|
|
1646
|
+
fg: theme.muted,
|
|
1647
|
+
children: "loading workspaces…"
|
|
1648
|
+
});
|
|
1649
|
+
if (state.kind === "error") return /* @__PURE__ */ jsxs("box", {
|
|
1650
|
+
style: { flexDirection: "column" },
|
|
1651
|
+
children: [/* @__PURE__ */ jsxs("text", {
|
|
1652
|
+
fg: theme.error,
|
|
1653
|
+
children: ["error: ", state.message]
|
|
1654
|
+
}), /* @__PURE__ */ jsx("text", {
|
|
1655
|
+
fg: theme.dim,
|
|
1656
|
+
children: "esc cancel"
|
|
1657
|
+
})]
|
|
1658
|
+
});
|
|
1659
|
+
if (rows.length === 0) return /* @__PURE__ */ jsxs("box", {
|
|
1660
|
+
style: { flexDirection: "column" },
|
|
1661
|
+
children: [/* @__PURE__ */ jsx("text", {
|
|
1662
|
+
fg: theme.muted,
|
|
1663
|
+
children: "no workspaces available"
|
|
1664
|
+
}), /* @__PURE__ */ jsx("text", {
|
|
1665
|
+
fg: theme.dim,
|
|
1666
|
+
children: "esc cancel"
|
|
1667
|
+
})]
|
|
1668
|
+
});
|
|
1669
|
+
const visibleRows = Math.max(3, height - 6);
|
|
1670
|
+
const start = windowStart(clamped, rows.length, visibleRows);
|
|
1671
|
+
const windowed = rows.slice(start, start + visibleRows);
|
|
1672
|
+
return /* @__PURE__ */ jsxs("box", {
|
|
1673
|
+
style: {
|
|
1674
|
+
flexDirection: "column",
|
|
1675
|
+
flexGrow: 1
|
|
1676
|
+
},
|
|
1677
|
+
children: [
|
|
1678
|
+
/* @__PURE__ */ jsx("text", {
|
|
1679
|
+
fg: theme.accent,
|
|
1680
|
+
children: "switch workspace"
|
|
1681
|
+
}),
|
|
1682
|
+
/* @__PURE__ */ jsx("box", {
|
|
1683
|
+
style: {
|
|
1684
|
+
flexDirection: "column",
|
|
1685
|
+
flexGrow: 1,
|
|
1686
|
+
marginTop: 1
|
|
1687
|
+
},
|
|
1688
|
+
children: windowed.map((workspace, index) => {
|
|
1689
|
+
const selected = start + index === clamped;
|
|
1690
|
+
const active = workspace.id === state.activeId;
|
|
1691
|
+
return /* @__PURE__ */ jsxs("text", {
|
|
1692
|
+
fg: selected ? theme.accent : theme.fg,
|
|
1693
|
+
children: [
|
|
1694
|
+
selected ? "› " : " ",
|
|
1695
|
+
active ? "● " : " ",
|
|
1696
|
+
workspace.name,
|
|
1697
|
+
/* @__PURE__ */ jsxs("span", {
|
|
1698
|
+
fg: theme.dim,
|
|
1699
|
+
children: [" ", workspace.slug]
|
|
1700
|
+
})
|
|
1701
|
+
]
|
|
1702
|
+
}, workspace.id);
|
|
1703
|
+
})
|
|
1704
|
+
}),
|
|
1705
|
+
/* @__PURE__ */ jsx("text", {
|
|
1706
|
+
fg: theme.dim,
|
|
1707
|
+
children: switching ? "switching…" : "↑/↓ move · ↵ select · esc cancel"
|
|
1708
|
+
})
|
|
1709
|
+
]
|
|
1710
|
+
});
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1571
1713
|
//#endregion
|
|
1572
1714
|
//#region src/chat/tui/screens/conversation-picker.tsx
|
|
1573
1715
|
function ConversationPickerScreen({ agent }) {
|
|
@@ -5914,6 +6056,15 @@ function App({ appUrl, sessionToken, shareMachine, promptHistoryPath, notificati
|
|
|
5914
6056
|
screen.kind === "error" && /* @__PURE__ */ jsx(ErrorScreen, { message: screen.message }),
|
|
5915
6057
|
screen.kind === "agent-picker" && rest && /* @__PURE__ */ jsx(AgentPickerScreen, {}),
|
|
5916
6058
|
screen.kind === "agent-create" && rest && /* @__PURE__ */ jsx(AgentCreateScreen, {}),
|
|
6059
|
+
screen.kind === "workspace-picker" && /* @__PURE__ */ jsx(WorkspacePicker, {
|
|
6060
|
+
appUrl,
|
|
6061
|
+
sessionToken,
|
|
6062
|
+
onCancel: () => goTo({ kind: "agent-picker" }),
|
|
6063
|
+
onSelect: (workspace) => {
|
|
6064
|
+
setWorkspaceName(workspace.name);
|
|
6065
|
+
goTo({ kind: "agent-picker" });
|
|
6066
|
+
}
|
|
6067
|
+
}),
|
|
5917
6068
|
screen.kind === "conversation-picker" && rest && /* @__PURE__ */ jsx(ConversationPickerScreen, { agent: screen.agent }),
|
|
5918
6069
|
screen.kind === "chat" && rest && /* @__PURE__ */ jsx(ChatScreen, {
|
|
5919
6070
|
agent: screen.agent,
|
|
@@ -6202,6 +6353,27 @@ async function runChat({ appUrl, sessionToken, shareMachine, promptHistoryPath,
|
|
|
6202
6353
|
agentSelector: agentSelector ?? null
|
|
6203
6354
|
}));
|
|
6204
6355
|
}
|
|
6356
|
+
/** Open the same workspace picker used by the initial agent screen. */
|
|
6357
|
+
async function runWorkspacePicker({ appUrl, sessionToken }) {
|
|
6358
|
+
const renderer = await createCliRenderer({ exitOnCtrlC: false });
|
|
6359
|
+
const detected = await renderer.waitForThemeMode() ?? themeModeFromColorFgBg() ?? "dark";
|
|
6360
|
+
useStore.getState().setThemeMode(detected);
|
|
6361
|
+
const close = () => renderer.destroy();
|
|
6362
|
+
createRoot(renderer).render(/* @__PURE__ */ jsx("box", {
|
|
6363
|
+
style: {
|
|
6364
|
+
flexDirection: "column",
|
|
6365
|
+
flexGrow: 1,
|
|
6366
|
+
padding: 1,
|
|
6367
|
+
backgroundColor: theme.background
|
|
6368
|
+
},
|
|
6369
|
+
children: /* @__PURE__ */ jsx(WorkspacePicker, {
|
|
6370
|
+
appUrl,
|
|
6371
|
+
sessionToken,
|
|
6372
|
+
onSelect: close,
|
|
6373
|
+
onCancel: close
|
|
6374
|
+
})
|
|
6375
|
+
}));
|
|
6376
|
+
}
|
|
6205
6377
|
|
|
6206
6378
|
//#endregion
|
|
6207
|
-
export { runChat };
|
|
6379
|
+
export { runChat, runWorkspacePicker };
|