skydive-cli 0.1.0-beta.340 → 0.1.0-beta.341
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
|
@@ -16,7 +16,7 @@ import zlib from "node:zlib";
|
|
|
16
16
|
import os from "node:os";
|
|
17
17
|
|
|
18
18
|
//#region package.json
|
|
19
|
-
var version$1 = "0.1.0-beta.
|
|
19
|
+
var version$1 = "0.1.0-beta.341";
|
|
20
20
|
|
|
21
21
|
//#endregion
|
|
22
22
|
//#region src/types.ts
|
|
@@ -2618,7 +2618,7 @@ const chatCommand = {
|
|
|
2618
2618
|
printError(`Unknown theme "${themeId}". Valid themes: ${themes.map((t) => t.id).join(", ")}`);
|
|
2619
2619
|
process.exit(1);
|
|
2620
2620
|
}
|
|
2621
|
-
const { runChat } = await import("./boot-
|
|
2621
|
+
const { runChat } = await import("./boot-Dr7pEKqB.mjs");
|
|
2622
2622
|
await runChat({
|
|
2623
2623
|
appUrl,
|
|
2624
2624
|
sessionToken: session.value.sessionToken,
|
|
@@ -3411,7 +3411,7 @@ const switchCommand = {
|
|
|
3411
3411
|
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.");
|
|
3412
3412
|
process.exit(1);
|
|
3413
3413
|
}
|
|
3414
|
-
const { runWorkspacePicker } = await import("./boot-
|
|
3414
|
+
const { runWorkspacePicker } = await import("./boot-Dr7pEKqB.mjs");
|
|
3415
3415
|
await runWorkspacePicker(session);
|
|
3416
3416
|
return;
|
|
3417
3417
|
}
|
|
@@ -1329,6 +1329,132 @@ function WorkspacePicker({ appUrl, sessionToken, onSelect, onCancel }) {
|
|
|
1329
1329
|
});
|
|
1330
1330
|
}
|
|
1331
1331
|
|
|
1332
|
+
//#endregion
|
|
1333
|
+
//#region src/chat/tui/chunks/frame.tsx
|
|
1334
|
+
/** Status glyph + color for a tool's lifecycle state. */
|
|
1335
|
+
function toolGlyph(state) {
|
|
1336
|
+
switch (state) {
|
|
1337
|
+
case "streaming":
|
|
1338
|
+
case "input-ready": return {
|
|
1339
|
+
ch: "◐",
|
|
1340
|
+
color: theme.warning
|
|
1341
|
+
};
|
|
1342
|
+
case "output-ready": return {
|
|
1343
|
+
ch: "✓",
|
|
1344
|
+
color: theme.success
|
|
1345
|
+
};
|
|
1346
|
+
case "error": return {
|
|
1347
|
+
ch: "✗",
|
|
1348
|
+
color: theme.error
|
|
1349
|
+
};
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
/** Truncate a single line with an ellipsis. */
|
|
1353
|
+
function truncate(line, maxLen) {
|
|
1354
|
+
return line.length > maxLen ? `${line.slice(0, maxLen - 1)}…` : line;
|
|
1355
|
+
}
|
|
1356
|
+
/**
|
|
1357
|
+
* Compact a block of tool output for the transcript: truncate over-long
|
|
1358
|
+
* lines (so a giant single-line JSON blob doesn't wrap to a wall) and cap
|
|
1359
|
+
* the line count, with a "+N more" tail that doubles as the click-to-expand
|
|
1360
|
+
* affordance. Expanded blocks render through `ExpandedLines` instead —
|
|
1361
|
+
* full content, word-wrapped, nothing clipped.
|
|
1362
|
+
*/
|
|
1363
|
+
function clipLines(text, { maxLines, maxLineLen }) {
|
|
1364
|
+
const lines = text.replace(/\t/g, " ").split("\n");
|
|
1365
|
+
const out = lines.slice(0, maxLines).map((line) => truncate(line, maxLineLen));
|
|
1366
|
+
if (lines.length > maxLines) out.push(`… +${lines.length - maxLines} more lines · click to expand`);
|
|
1367
|
+
return out;
|
|
1368
|
+
}
|
|
1369
|
+
/**
|
|
1370
|
+
* Split a block for the expanded view: tabs normalised, no line cap, no
|
|
1371
|
+
* per-line truncation — rendering word-wraps instead. Blank lines become a
|
|
1372
|
+
* single space so they keep their row (an empty <text> collapses).
|
|
1373
|
+
*/
|
|
1374
|
+
function expandLines(text) {
|
|
1375
|
+
return text.replace(/\t/g, " ").split("\n").map((line) => line.length === 0 ? " " : line);
|
|
1376
|
+
}
|
|
1377
|
+
/**
|
|
1378
|
+
* Full, untruncated block content for an expanded view: every line kept and
|
|
1379
|
+
* word-wrapped by the terminal instead of ellipsis-clipped.
|
|
1380
|
+
*/
|
|
1381
|
+
function ExpandedLines({ text, fg }) {
|
|
1382
|
+
return /* @__PURE__ */ jsx("box", {
|
|
1383
|
+
style: { flexDirection: "column" },
|
|
1384
|
+
children: expandLines(text).map((line, idx) => /* @__PURE__ */ jsx("text", {
|
|
1385
|
+
fg,
|
|
1386
|
+
style: { wrapMode: "word" },
|
|
1387
|
+
children: line
|
|
1388
|
+
}, idx))
|
|
1389
|
+
});
|
|
1390
|
+
}
|
|
1391
|
+
/** Whether a block of text has lines hidden by the collapsed line cap. */
|
|
1392
|
+
function isClipped(text, maxLines) {
|
|
1393
|
+
let count = 1;
|
|
1394
|
+
for (let i = 0; i < text.length; i++) {
|
|
1395
|
+
if (text.charCodeAt(i) === 10) count++;
|
|
1396
|
+
if (count > maxLines) return true;
|
|
1397
|
+
}
|
|
1398
|
+
return false;
|
|
1399
|
+
}
|
|
1400
|
+
/** Dim tail line under an expanded block: click anywhere on it to fold. */
|
|
1401
|
+
function CollapseHint() {
|
|
1402
|
+
return /* @__PURE__ */ jsx("text", {
|
|
1403
|
+
fg: theme.dim,
|
|
1404
|
+
children: "· click to collapse"
|
|
1405
|
+
});
|
|
1406
|
+
}
|
|
1407
|
+
/** Indents tool output two columns under its header — no rule, just space. */
|
|
1408
|
+
function Indented({ children }) {
|
|
1409
|
+
return /* @__PURE__ */ jsx("box", {
|
|
1410
|
+
style: {
|
|
1411
|
+
flexDirection: "column",
|
|
1412
|
+
paddingLeft: 2
|
|
1413
|
+
},
|
|
1414
|
+
children
|
|
1415
|
+
});
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
//#endregion
|
|
1419
|
+
//#region src/chat/tui/list-line.ts
|
|
1420
|
+
/**
|
|
1421
|
+
* Fit a row's title and trailing detail into `width` columns. The title
|
|
1422
|
+
* identifies the row so it gets the space first; the detail takes what is
|
|
1423
|
+
* left and is dropped when nothing is.
|
|
1424
|
+
*/
|
|
1425
|
+
function fitRowText(title, detail, width) {
|
|
1426
|
+
if (width <= 0) return {
|
|
1427
|
+
title: "",
|
|
1428
|
+
detail: ""
|
|
1429
|
+
};
|
|
1430
|
+
if ((detail ? title.length + 1 + detail.length : title.length) <= width) return {
|
|
1431
|
+
title,
|
|
1432
|
+
detail
|
|
1433
|
+
};
|
|
1434
|
+
const room = width - title.length - 1;
|
|
1435
|
+
if (room < 2) return {
|
|
1436
|
+
title: truncate(title, width),
|
|
1437
|
+
detail: ""
|
|
1438
|
+
};
|
|
1439
|
+
return {
|
|
1440
|
+
title,
|
|
1441
|
+
detail: truncate(detail, room)
|
|
1442
|
+
};
|
|
1443
|
+
}
|
|
1444
|
+
/**
|
|
1445
|
+
* Join hint segments with " · ", dropping trailing segments that do not fit
|
|
1446
|
+
* rather than wrapping onto a second line — which would cost the list a row.
|
|
1447
|
+
* The first segment is always kept (truncated if it has to be).
|
|
1448
|
+
*/
|
|
1449
|
+
function fitHintLine(segments, width) {
|
|
1450
|
+
const kept = [];
|
|
1451
|
+
for (const segment of segments) {
|
|
1452
|
+
if (kept.length > 0 && [...kept, segment].join(" · ").length > width) break;
|
|
1453
|
+
kept.push(segment);
|
|
1454
|
+
}
|
|
1455
|
+
return truncate(kept.join(" · "), width);
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1332
1458
|
//#endregion
|
|
1333
1459
|
//#region src/chat/tui/screens/conversation-picker.tsx
|
|
1334
1460
|
const humanChannels = [
|
|
@@ -1432,6 +1558,27 @@ function ConversationList({ agent, conversations, complete, showAutomated, onTog
|
|
|
1432
1558
|
kind: "conv",
|
|
1433
1559
|
hit
|
|
1434
1560
|
}))];
|
|
1561
|
+
const innerWidth = Math.max(1, width - 2);
|
|
1562
|
+
const rowWidth = Math.max(1, innerWidth - 2);
|
|
1563
|
+
const confirmConv = confirmId !== null ? list.find((c) => c.id === confirmId) : void 0;
|
|
1564
|
+
const status = confirmConv ? {
|
|
1565
|
+
fg: theme.error,
|
|
1566
|
+
text: truncate(`delete “${confirmConv.title ?? "(untitled)"}”? y/n`, innerWidth)
|
|
1567
|
+
} : error ? {
|
|
1568
|
+
fg: theme.error,
|
|
1569
|
+
text: truncate(`delete failed: ${error}`, innerWidth)
|
|
1570
|
+
} : {
|
|
1571
|
+
fg: theme.dim,
|
|
1572
|
+
text: fitHintLine([
|
|
1573
|
+
`${hits.length}/${list.length}${complete ? "" : " (loading…)"}`,
|
|
1574
|
+
showAutomated ? "incl. agent runs" : "yours",
|
|
1575
|
+
`tab ${showAutomated ? "hide" : "show"} agent runs`,
|
|
1576
|
+
"↑/↓ move",
|
|
1577
|
+
"↵ open",
|
|
1578
|
+
"ctrl+d delete",
|
|
1579
|
+
"esc back"
|
|
1580
|
+
], innerWidth)
|
|
1581
|
+
};
|
|
1435
1582
|
const clamped = Math.min(highlight, Math.max(0, rows.length - 1));
|
|
1436
1583
|
const visibleRows = Math.max(3, height - 6);
|
|
1437
1584
|
const start = windowStart(clamped, rows.length, visibleRows);
|
|
@@ -1487,7 +1634,6 @@ function ConversationList({ agent, conversations, complete, showAutomated, onTog
|
|
|
1487
1634
|
if (row) open(row);
|
|
1488
1635
|
}
|
|
1489
1636
|
});
|
|
1490
|
-
const confirmConv = confirmId !== null ? list.find((c) => c.id === confirmId) : void 0;
|
|
1491
1637
|
return /* @__PURE__ */ jsxs("box", {
|
|
1492
1638
|
style: {
|
|
1493
1639
|
flexDirection: "column",
|
|
@@ -1512,31 +1658,9 @@ function ConversationList({ agent, conversations, complete, showAutomated, onTog
|
|
|
1512
1658
|
}
|
|
1513
1659
|
})]
|
|
1514
1660
|
}),
|
|
1515
|
-
|
|
1516
|
-
fg:
|
|
1517
|
-
children:
|
|
1518
|
-
"delete “",
|
|
1519
|
-
confirmConv.title ?? "(untitled)",
|
|
1520
|
-
"”? y/n"
|
|
1521
|
-
]
|
|
1522
|
-
}) : error ? /* @__PURE__ */ jsxs("text", {
|
|
1523
|
-
fg: theme.error,
|
|
1524
|
-
children: ["delete failed: ", error]
|
|
1525
|
-
}) : /* @__PURE__ */ jsxs("text", {
|
|
1526
|
-
fg: theme.dim,
|
|
1527
|
-
children: [
|
|
1528
|
-
hits.length,
|
|
1529
|
-
"/",
|
|
1530
|
-
list.length,
|
|
1531
|
-
complete ? "" : " (loading…)",
|
|
1532
|
-
" ·",
|
|
1533
|
-
" ",
|
|
1534
|
-
showAutomated ? "incl. agent runs" : "yours",
|
|
1535
|
-
" · tab",
|
|
1536
|
-
" ",
|
|
1537
|
-
showAutomated ? "hide" : "show",
|
|
1538
|
-
" agent runs · ↑/↓ move · ↵ open · ctrl+d delete · esc back"
|
|
1539
|
-
]
|
|
1661
|
+
/* @__PURE__ */ jsx("text", {
|
|
1662
|
+
fg: status.fg,
|
|
1663
|
+
children: status.text
|
|
1540
1664
|
}),
|
|
1541
1665
|
/* @__PURE__ */ jsx("box", {
|
|
1542
1666
|
style: {
|
|
@@ -1546,22 +1670,24 @@ function ConversationList({ agent, conversations, complete, showAutomated, onTog
|
|
|
1546
1670
|
children: windowed.map((row, i) => {
|
|
1547
1671
|
const selected = start + i === clamped;
|
|
1548
1672
|
const fg = selected ? theme.accent : theme.fg;
|
|
1673
|
+
const marker = selected ? "› " : " ";
|
|
1549
1674
|
if (row.kind === "new") return /* @__PURE__ */ jsxs("text", {
|
|
1550
1675
|
fg,
|
|
1551
|
-
children: [
|
|
1676
|
+
children: [marker, truncate("+ new conversation", rowWidth)]
|
|
1552
1677
|
}, "new");
|
|
1678
|
+
const { title, detail } = fitRowText(row.hit.item.title ?? "(untitled)", previewLine(row.hit.item), rowWidth);
|
|
1553
1679
|
return /* @__PURE__ */ jsxs("text", {
|
|
1554
1680
|
fg,
|
|
1555
1681
|
children: [
|
|
1556
|
-
|
|
1682
|
+
marker,
|
|
1557
1683
|
/* @__PURE__ */ jsx(FuzzyText, {
|
|
1558
|
-
text:
|
|
1684
|
+
text: title,
|
|
1559
1685
|
indexes: row.hit.item.title ? row.hit.highlights[0] : null
|
|
1560
1686
|
}),
|
|
1561
|
-
/* @__PURE__ */ jsxs("span", {
|
|
1687
|
+
detail ? /* @__PURE__ */ jsxs("span", {
|
|
1562
1688
|
fg: theme.dim,
|
|
1563
|
-
children: [" ",
|
|
1564
|
-
})
|
|
1689
|
+
children: [" ", detail]
|
|
1690
|
+
}) : null
|
|
1565
1691
|
]
|
|
1566
1692
|
}, row.hit.item.id);
|
|
1567
1693
|
})
|
|
@@ -1718,92 +1844,6 @@ async function resolveDroppedFiles(paths) {
|
|
|
1718
1844
|
}
|
|
1719
1845
|
}
|
|
1720
1846
|
|
|
1721
|
-
//#endregion
|
|
1722
|
-
//#region src/chat/tui/chunks/frame.tsx
|
|
1723
|
-
/** Status glyph + color for a tool's lifecycle state. */
|
|
1724
|
-
function toolGlyph(state) {
|
|
1725
|
-
switch (state) {
|
|
1726
|
-
case "streaming":
|
|
1727
|
-
case "input-ready": return {
|
|
1728
|
-
ch: "◐",
|
|
1729
|
-
color: theme.warning
|
|
1730
|
-
};
|
|
1731
|
-
case "output-ready": return {
|
|
1732
|
-
ch: "✓",
|
|
1733
|
-
color: theme.success
|
|
1734
|
-
};
|
|
1735
|
-
case "error": return {
|
|
1736
|
-
ch: "✗",
|
|
1737
|
-
color: theme.error
|
|
1738
|
-
};
|
|
1739
|
-
}
|
|
1740
|
-
}
|
|
1741
|
-
/** Truncate a single line with an ellipsis. */
|
|
1742
|
-
function truncate(line, maxLen) {
|
|
1743
|
-
return line.length > maxLen ? `${line.slice(0, maxLen - 1)}…` : line;
|
|
1744
|
-
}
|
|
1745
|
-
/**
|
|
1746
|
-
* Compact a block of tool output for the transcript: truncate over-long
|
|
1747
|
-
* lines (so a giant single-line JSON blob doesn't wrap to a wall) and cap
|
|
1748
|
-
* the line count, with a "+N more" tail that doubles as the click-to-expand
|
|
1749
|
-
* affordance. Expanded blocks render through `ExpandedLines` instead —
|
|
1750
|
-
* full content, word-wrapped, nothing clipped.
|
|
1751
|
-
*/
|
|
1752
|
-
function clipLines(text, { maxLines, maxLineLen }) {
|
|
1753
|
-
const lines = text.replace(/\t/g, " ").split("\n");
|
|
1754
|
-
const out = lines.slice(0, maxLines).map((line) => truncate(line, maxLineLen));
|
|
1755
|
-
if (lines.length > maxLines) out.push(`… +${lines.length - maxLines} more lines · click to expand`);
|
|
1756
|
-
return out;
|
|
1757
|
-
}
|
|
1758
|
-
/**
|
|
1759
|
-
* Split a block for the expanded view: tabs normalised, no line cap, no
|
|
1760
|
-
* per-line truncation — rendering word-wraps instead. Blank lines become a
|
|
1761
|
-
* single space so they keep their row (an empty <text> collapses).
|
|
1762
|
-
*/
|
|
1763
|
-
function expandLines(text) {
|
|
1764
|
-
return text.replace(/\t/g, " ").split("\n").map((line) => line.length === 0 ? " " : line);
|
|
1765
|
-
}
|
|
1766
|
-
/**
|
|
1767
|
-
* Full, untruncated block content for an expanded view: every line kept and
|
|
1768
|
-
* word-wrapped by the terminal instead of ellipsis-clipped.
|
|
1769
|
-
*/
|
|
1770
|
-
function ExpandedLines({ text, fg }) {
|
|
1771
|
-
return /* @__PURE__ */ jsx("box", {
|
|
1772
|
-
style: { flexDirection: "column" },
|
|
1773
|
-
children: expandLines(text).map((line, idx) => /* @__PURE__ */ jsx("text", {
|
|
1774
|
-
fg,
|
|
1775
|
-
style: { wrapMode: "word" },
|
|
1776
|
-
children: line
|
|
1777
|
-
}, idx))
|
|
1778
|
-
});
|
|
1779
|
-
}
|
|
1780
|
-
/** Whether a block of text has lines hidden by the collapsed line cap. */
|
|
1781
|
-
function isClipped(text, maxLines) {
|
|
1782
|
-
let count = 1;
|
|
1783
|
-
for (let i = 0; i < text.length; i++) {
|
|
1784
|
-
if (text.charCodeAt(i) === 10) count++;
|
|
1785
|
-
if (count > maxLines) return true;
|
|
1786
|
-
}
|
|
1787
|
-
return false;
|
|
1788
|
-
}
|
|
1789
|
-
/** Dim tail line under an expanded block: click anywhere on it to fold. */
|
|
1790
|
-
function CollapseHint() {
|
|
1791
|
-
return /* @__PURE__ */ jsx("text", {
|
|
1792
|
-
fg: theme.dim,
|
|
1793
|
-
children: "· click to collapse"
|
|
1794
|
-
});
|
|
1795
|
-
}
|
|
1796
|
-
/** Indents tool output two columns under its header — no rule, just space. */
|
|
1797
|
-
function Indented({ children }) {
|
|
1798
|
-
return /* @__PURE__ */ jsx("box", {
|
|
1799
|
-
style: {
|
|
1800
|
-
flexDirection: "column",
|
|
1801
|
-
paddingLeft: 2
|
|
1802
|
-
},
|
|
1803
|
-
children
|
|
1804
|
-
});
|
|
1805
|
-
}
|
|
1806
|
-
|
|
1807
1847
|
//#endregion
|
|
1808
1848
|
//#region src/chat/tui/chunks/syntax.ts
|
|
1809
1849
|
let cached = null;
|