@kud/gh-ink 0.8.0 → 0.9.0
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/index.js +246 -188
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React2, { useState, useRef, useEffect } from 'react';
|
|
1
|
+
import React2, { createContext, useState, useRef, useEffect, useContext } from 'react';
|
|
2
2
|
import { useWindowSize, useInput, Text, Box } from 'ink';
|
|
3
3
|
import { colors, ScrollView, TextInput, LoadingScreen, Switch, useListCursor, Tabs, FooterHints } from '@kud/ink-ui';
|
|
4
4
|
import { isPassCheck, isFailCheck, resolveThread, unresolveThread, replyToThread, rerunFailedRun, mergePr, reRequestReviewer } from '@kud/gh';
|
|
@@ -1065,6 +1065,28 @@ var FRAME_COLOR = "gray";
|
|
|
1065
1065
|
var FRAME_PAD_X = 1;
|
|
1066
1066
|
var FRAME_CHROME_COLS = 2 + FRAME_PAD_X * 2;
|
|
1067
1067
|
var COLS = (process.stdout.columns ?? 120) - FRAME_CHROME_COLS;
|
|
1068
|
+
var MODAL_CHROME_COLS = 2 + 1 * 2;
|
|
1069
|
+
var OVERLAY_BG = "#22222e";
|
|
1070
|
+
var DimContext = createContext(false);
|
|
1071
|
+
var Text2 = ({ children, ...props }) => {
|
|
1072
|
+
const dimmed = useContext(DimContext);
|
|
1073
|
+
return dimmed ? /* @__PURE__ */ jsx(Text, { ...props, bold: false, dimColor: true, children }) : /* @__PURE__ */ jsx(Text, { ...props, children });
|
|
1074
|
+
};
|
|
1075
|
+
var Backdrop = ({
|
|
1076
|
+
dimmed,
|
|
1077
|
+
absolute,
|
|
1078
|
+
height,
|
|
1079
|
+
children
|
|
1080
|
+
}) => /* @__PURE__ */ jsx(DimContext.Provider, { value: dimmed, children: absolute ? /* @__PURE__ */ jsx(
|
|
1081
|
+
Box,
|
|
1082
|
+
{
|
|
1083
|
+
position: "absolute",
|
|
1084
|
+
flexDirection: "column",
|
|
1085
|
+
width: "100%",
|
|
1086
|
+
height,
|
|
1087
|
+
children
|
|
1088
|
+
}
|
|
1089
|
+
) : children });
|
|
1068
1090
|
var topLevelCount = (s) => s.items.filter(
|
|
1069
1091
|
(i) => i.kind !== "repo-header" && i.kind !== "subgroup-header" && !i.indent
|
|
1070
1092
|
).length;
|
|
@@ -1356,16 +1378,16 @@ var InboxHeader = ({
|
|
|
1356
1378
|
COLS - brand.length - countSeg.length - userSeg.length - workLabel.length - statusSeg.length
|
|
1357
1379
|
);
|
|
1358
1380
|
return /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
1359
|
-
/* @__PURE__ */ jsx(
|
|
1360
|
-
/* @__PURE__ */ jsx(
|
|
1361
|
-
userSeg ? /* @__PURE__ */ jsx(
|
|
1381
|
+
/* @__PURE__ */ jsx(Text2, { color: "#FF8700", bold: true, children: brand }),
|
|
1382
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: countSeg }),
|
|
1383
|
+
userSeg ? /* @__PURE__ */ jsx(Text2, { children: userSeg }) : null,
|
|
1362
1384
|
work !== void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1363
|
-
/* @__PURE__ */ jsx(
|
|
1385
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: " w " }),
|
|
1364
1386
|
/* @__PURE__ */ jsx(Switch, { left: "work", right: "home", value: work ? "left" : "right" }),
|
|
1365
|
-
/* @__PURE__ */ jsx(
|
|
1387
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: " " })
|
|
1366
1388
|
] }) : null,
|
|
1367
1389
|
statusText ? /* @__PURE__ */ jsx(
|
|
1368
|
-
|
|
1390
|
+
Text2,
|
|
1369
1391
|
{
|
|
1370
1392
|
color: statusColor,
|
|
1371
1393
|
dimColor: !statusColor,
|
|
@@ -1373,7 +1395,7 @@ var InboxHeader = ({
|
|
|
1373
1395
|
children: statusSeg
|
|
1374
1396
|
}
|
|
1375
1397
|
) : null,
|
|
1376
|
-
/* @__PURE__ */ jsx(
|
|
1398
|
+
/* @__PURE__ */ jsx(Text2, { color: "cyan", dimColor: true, children: "\u254C".repeat(fill) })
|
|
1377
1399
|
] });
|
|
1378
1400
|
};
|
|
1379
1401
|
var toCiStatusState = (status) => status ? { kind: "ready", status } : { kind: "error" };
|
|
@@ -1396,30 +1418,30 @@ var CiStatusLine = ({
|
|
|
1396
1418
|
const name = job ?? "ci";
|
|
1397
1419
|
if (state.kind === "loading")
|
|
1398
1420
|
return /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
1399
|
-
/* @__PURE__ */ jsx(
|
|
1400
|
-
/* @__PURE__ */ jsx(
|
|
1421
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: " \xB7 " }),
|
|
1422
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: `${name} loading\u2026` })
|
|
1401
1423
|
] });
|
|
1402
1424
|
if (state.kind === "error")
|
|
1403
1425
|
return /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
1404
|
-
/* @__PURE__ */ jsx(
|
|
1405
|
-
/* @__PURE__ */ jsx(
|
|
1426
|
+
/* @__PURE__ */ jsx(Text2, { color: "red", bold: true, children: " \u2717 " }),
|
|
1427
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: `${name} no build / not configured` })
|
|
1406
1428
|
] });
|
|
1407
1429
|
const { status } = state;
|
|
1408
1430
|
const [, color] = jenkinsResultDisplay(status.result, status.building);
|
|
1409
1431
|
const label = status.building ? "BUILDING" : status.result;
|
|
1410
1432
|
return /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
1411
|
-
/* @__PURE__ */ jsx(
|
|
1412
|
-
/* @__PURE__ */ jsx(
|
|
1413
|
-
/* @__PURE__ */ jsx(
|
|
1414
|
-
/* @__PURE__ */ jsx(
|
|
1415
|
-
/* @__PURE__ */ jsx(
|
|
1416
|
-
status.age ? /* @__PURE__ */ jsx(
|
|
1433
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: " " }),
|
|
1434
|
+
/* @__PURE__ */ jsx(Text2, { color, bold: true, children: "\u25CF " }),
|
|
1435
|
+
/* @__PURE__ */ jsx(Text2, { bold: true, children: status.job }),
|
|
1436
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: " " + label }),
|
|
1437
|
+
/* @__PURE__ */ jsx(Text2, { color: "#FF8700", children: " #" + status.buildNumber }),
|
|
1438
|
+
status.age ? /* @__PURE__ */ jsx(Text2, { dimColor: true, children: " " + status.age }) : null
|
|
1417
1439
|
] });
|
|
1418
1440
|
};
|
|
1419
1441
|
var RepoHeaderRow = ({ repo, gap }) => {
|
|
1420
1442
|
const label = `\u2500\u2500 ${repo} `;
|
|
1421
1443
|
const fill = Math.max(4, 46 - label.length);
|
|
1422
|
-
return /* @__PURE__ */ jsx(Box, { marginTop: gap ? 1 : 0, children: /* @__PURE__ */ jsx(
|
|
1444
|
+
return /* @__PURE__ */ jsx(Box, { marginTop: gap ? 1 : 0, children: /* @__PURE__ */ jsx(Text2, { dimColor: true, children: " " + label + "\u2500".repeat(fill) }) });
|
|
1423
1445
|
};
|
|
1424
1446
|
var ItemRow = ({
|
|
1425
1447
|
item,
|
|
@@ -1431,29 +1453,29 @@ var ItemRow = ({
|
|
|
1431
1453
|
return /* @__PURE__ */ jsx(RepoHeaderRow, { repo: item.repo, gap: gap ?? false });
|
|
1432
1454
|
if (item.kind === "subgroup-header")
|
|
1433
1455
|
return /* @__PURE__ */ jsxs(Box, { marginTop: gap ? 1 : 0, children: [
|
|
1434
|
-
/* @__PURE__ */ jsx(
|
|
1435
|
-
/* @__PURE__ */ jsx(
|
|
1456
|
+
/* @__PURE__ */ jsx(Text2, { color: "#FF8700", bold: true, children: " \xBB " }),
|
|
1457
|
+
/* @__PURE__ */ jsx(Text2, { bold: true, children: item.label })
|
|
1436
1458
|
] });
|
|
1437
1459
|
if (item.kind === "show-more")
|
|
1438
1460
|
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
1439
|
-
/* @__PURE__ */ jsx(
|
|
1440
|
-
/* @__PURE__ */ jsx(
|
|
1441
|
-
/* @__PURE__ */ jsx(
|
|
1442
|
-
/* @__PURE__ */ jsx(
|
|
1461
|
+
/* @__PURE__ */ jsx(Text2, { color: "cyan", children: active ? "\u276F " : " " }),
|
|
1462
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: "\u2514\u2500 " }),
|
|
1463
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: active ? "\u21B5 " : " " }),
|
|
1464
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: `+${item.hidden.length} more` })
|
|
1443
1465
|
] });
|
|
1444
1466
|
if (item.kind === "show-less")
|
|
1445
1467
|
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
1446
|
-
/* @__PURE__ */ jsx(
|
|
1447
|
-
/* @__PURE__ */ jsx(
|
|
1448
|
-
/* @__PURE__ */ jsx(
|
|
1449
|
-
/* @__PURE__ */ jsx(
|
|
1468
|
+
/* @__PURE__ */ jsx(Text2, { color: "cyan", children: active ? "\u276F " : " " }),
|
|
1469
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: "\u2514\u2500 " }),
|
|
1470
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: active ? "\u21B5 " : " " }),
|
|
1471
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: "show less" })
|
|
1450
1472
|
] });
|
|
1451
1473
|
if (item.kind === "jira") {
|
|
1452
1474
|
const titleMax2 = Math.max(20, COLS - item.key.length - 10);
|
|
1453
1475
|
return /* @__PURE__ */ jsxs(Box, { marginTop: gap ? 1 : 0, children: [
|
|
1454
|
-
/* @__PURE__ */ jsx(
|
|
1455
|
-
/* @__PURE__ */ jsx(
|
|
1456
|
-
/* @__PURE__ */ jsx(
|
|
1476
|
+
/* @__PURE__ */ jsx(Text2, { color: "cyan", children: active ? "\u276F " : " " }),
|
|
1477
|
+
/* @__PURE__ */ jsx(Text2, { color: "#FF8700", bold: active, children: item.key + " " }),
|
|
1478
|
+
/* @__PURE__ */ jsx(Text2, { bold: active, children: truncate(item.summary, titleMax2) })
|
|
1457
1479
|
] });
|
|
1458
1480
|
}
|
|
1459
1481
|
const { glyph: icon, color } = healthDisplay[item.health];
|
|
@@ -1470,16 +1492,16 @@ var ItemRow = ({
|
|
|
1470
1492
|
const fixedWidth = 2 + (item.indent ? 3 : 0) + 2 + 2 + 7 + repoLabel.length + suffix.length + 6;
|
|
1471
1493
|
const titleMax = Math.max(20, COLS - fixedWidth);
|
|
1472
1494
|
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
1473
|
-
/* @__PURE__ */ jsx(
|
|
1474
|
-
item.indent ? /* @__PURE__ */ jsx(
|
|
1475
|
-
/* @__PURE__ */ jsx(
|
|
1476
|
-
/* @__PURE__ */ jsx(
|
|
1477
|
-
/* @__PURE__ */ jsx(
|
|
1478
|
-
/* @__PURE__ */ jsx(
|
|
1479
|
-
repoLabel ? /* @__PURE__ */ jsx(
|
|
1480
|
-
unresolvedLabel ? /* @__PURE__ */ jsx(
|
|
1481
|
-
showAuthor ? /* @__PURE__ */ jsx(
|
|
1482
|
-
item.age ? /* @__PURE__ */ jsx(
|
|
1495
|
+
/* @__PURE__ */ jsx(Text2, { color: "cyan", children: active ? "\u276F " : " " }),
|
|
1496
|
+
item.indent ? /* @__PURE__ */ jsx(Text2, { dimColor: true, children: "\u2514\u2500 " }) : null,
|
|
1497
|
+
/* @__PURE__ */ jsx(Text2, { color, bold: true, children: icon + " " }),
|
|
1498
|
+
/* @__PURE__ */ jsx(Text2, { color: turnColor, bold: turnIcon === "\u2190", children: turnIcon + " " }),
|
|
1499
|
+
/* @__PURE__ */ jsx(Text2, { color: "#FF8700", children: numStr }),
|
|
1500
|
+
/* @__PURE__ */ jsx(Text2, { bold: active, children: truncate(item.title, titleMax) + " " }),
|
|
1501
|
+
repoLabel ? /* @__PURE__ */ jsx(Text2, { dimColor: true, children: repoLabel }) : null,
|
|
1502
|
+
unresolvedLabel ? /* @__PURE__ */ jsx(Text2, { bold: true, color: "#FF8700", children: " " + unresolvedLabel }) : null,
|
|
1503
|
+
showAuthor ? /* @__PURE__ */ jsx(Text2, { dimColor: true, italic: true, children: " by " + item.author }) : null,
|
|
1504
|
+
item.age ? /* @__PURE__ */ jsx(Text2, { dimColor: true, children: " " + item.age }) : null
|
|
1483
1505
|
] });
|
|
1484
1506
|
};
|
|
1485
1507
|
var useActionMenu = () => {
|
|
@@ -1521,18 +1543,19 @@ var ActionMenu = ({
|
|
|
1521
1543
|
flexDirection: "column",
|
|
1522
1544
|
borderStyle: "round",
|
|
1523
1545
|
borderColor: "cyan",
|
|
1546
|
+
backgroundColor: OVERLAY_BG,
|
|
1524
1547
|
paddingX: 1,
|
|
1525
1548
|
marginTop: 1,
|
|
1526
1549
|
children: [
|
|
1527
|
-
/* @__PURE__ */ jsx(
|
|
1528
|
-
/* @__PURE__ */ jsx(
|
|
1550
|
+
/* @__PURE__ */ jsx(Text2, { color: "cyan", bold: true, children: title }),
|
|
1551
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: "\u2500".repeat(32) }),
|
|
1529
1552
|
actions.map((a, i) => /* @__PURE__ */ jsxs(Box, { children: [
|
|
1530
|
-
/* @__PURE__ */ jsx(
|
|
1531
|
-
/* @__PURE__ */ jsx(
|
|
1532
|
-
/* @__PURE__ */ jsx(
|
|
1553
|
+
/* @__PURE__ */ jsx(Text2, { color: "cyan", children: i === cursor ? "\u276F " : " " }),
|
|
1554
|
+
/* @__PURE__ */ jsx(Text2, { bold: i === cursor, children: a.label }),
|
|
1555
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: " " + a.hint })
|
|
1533
1556
|
] }, a.label)),
|
|
1534
|
-
/* @__PURE__ */ jsx(
|
|
1535
|
-
/* @__PURE__ */ jsx(
|
|
1557
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: "\u2500".repeat(32) }),
|
|
1558
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: "\u2191\u2193 navigate \u21B5 confirm esc cancel" })
|
|
1536
1559
|
]
|
|
1537
1560
|
}
|
|
1538
1561
|
);
|
|
@@ -1541,12 +1564,55 @@ var TURN_LEGEND = [
|
|
|
1541
1564
|
["\u2190", "#FF8700", "They spoke last \xB7 your turn"],
|
|
1542
1565
|
["\u2192", "#888888", "You spoke last \xB7 waiting on them"]
|
|
1543
1566
|
];
|
|
1567
|
+
var CELL_GUTTER = 2;
|
|
1568
|
+
var COL_GAP = 3;
|
|
1569
|
+
var cellWidthOf = (col) => Math.max(0, ...col.rows.map((r) => r.cell.length)) + CELL_GUTTER;
|
|
1570
|
+
var widthOf = (col) => Math.max(
|
|
1571
|
+
col.title.length,
|
|
1572
|
+
...col.rows.map((r) => cellWidthOf(col) + r.label.length)
|
|
1573
|
+
);
|
|
1574
|
+
var groupWidth = (group) => Math.max(0, ...group.map(widthOf));
|
|
1575
|
+
var layoutWidth = (groups) => groups.reduce((total, g) => total + groupWidth(g), 0) + COL_GAP * Math.max(0, groups.length - 1);
|
|
1576
|
+
var legendLayout = (cols, available) => {
|
|
1577
|
+
const across = cols.map((c) => [c]);
|
|
1578
|
+
if (layoutWidth(across) <= available) return across;
|
|
1579
|
+
const stacked = [cols.slice(0, -1), cols.slice(-1)];
|
|
1580
|
+
if (layoutWidth(stacked) <= available) return stacked;
|
|
1581
|
+
return [cols];
|
|
1582
|
+
};
|
|
1583
|
+
var LegendGroup = ({
|
|
1584
|
+
group,
|
|
1585
|
+
width,
|
|
1586
|
+
marginRight
|
|
1587
|
+
}) => /* @__PURE__ */ jsx(Box, { flexDirection: "column", width, marginRight, children: group.map((col, index) => {
|
|
1588
|
+
const cellWidth = cellWidthOf(col);
|
|
1589
|
+
return /* @__PURE__ */ jsxs(
|
|
1590
|
+
Box,
|
|
1591
|
+
{
|
|
1592
|
+
flexDirection: "column",
|
|
1593
|
+
marginTop: index === 0 ? 0 : 1,
|
|
1594
|
+
children: [
|
|
1595
|
+
/* @__PURE__ */ jsx(Text2, { bold: true, dimColor: true, children: col.title }),
|
|
1596
|
+
col.rows.map((row) => /* @__PURE__ */ jsxs(Box, { children: [
|
|
1597
|
+
/* @__PURE__ */ jsx(Text2, { color: row.color, bold: row.bold, children: row.cell.padEnd(cellWidth) }),
|
|
1598
|
+
/* @__PURE__ */ jsx(Text2, { wrap: "truncate-end", children: row.label })
|
|
1599
|
+
] }, col.title + row.cell + row.label))
|
|
1600
|
+
]
|
|
1601
|
+
},
|
|
1602
|
+
col.title
|
|
1603
|
+
);
|
|
1604
|
+
}) });
|
|
1544
1605
|
var HelpModal = ({
|
|
1545
1606
|
workToggle,
|
|
1546
1607
|
extensions,
|
|
1547
1608
|
hasJira,
|
|
1548
1609
|
tabHelp
|
|
1549
1610
|
}) => {
|
|
1611
|
+
const { columns } = useWindowSize();
|
|
1612
|
+
const available = Math.max(
|
|
1613
|
+
20,
|
|
1614
|
+
columns - FRAME_CHROME_COLS - MODAL_CHROME_COLS
|
|
1615
|
+
);
|
|
1550
1616
|
const keys = [
|
|
1551
1617
|
["\u2191 \u2193", "navigate"],
|
|
1552
1618
|
["\u2190 \u2192 \xB7 tab", "switch tab"],
|
|
@@ -1568,51 +1634,71 @@ var HelpModal = ({
|
|
|
1568
1634
|
["?", "this help"],
|
|
1569
1635
|
["q", "quit"]
|
|
1570
1636
|
];
|
|
1637
|
+
const statusColumn = {
|
|
1638
|
+
title: "Status",
|
|
1639
|
+
rows: [
|
|
1640
|
+
...healthLegend.map(([health, label]) => ({
|
|
1641
|
+
cell: healthDisplay[health].glyph,
|
|
1642
|
+
color: healthDisplay[health].color,
|
|
1643
|
+
bold: true,
|
|
1644
|
+
label
|
|
1645
|
+
})),
|
|
1646
|
+
...TURN_LEGEND.map(([cell, color, label]) => ({
|
|
1647
|
+
cell,
|
|
1648
|
+
color,
|
|
1649
|
+
bold: true,
|
|
1650
|
+
label
|
|
1651
|
+
})),
|
|
1652
|
+
{
|
|
1653
|
+
cell: "\uF086",
|
|
1654
|
+
color: "#FF8700",
|
|
1655
|
+
bold: true,
|
|
1656
|
+
label: "Open-thread count"
|
|
1657
|
+
}
|
|
1658
|
+
]
|
|
1659
|
+
};
|
|
1660
|
+
const cols = [
|
|
1661
|
+
statusColumn,
|
|
1662
|
+
...tabHelp ? [
|
|
1663
|
+
{
|
|
1664
|
+
title: "Tabs",
|
|
1665
|
+
rows: tabHelp.map(([tab, meaning]) => ({
|
|
1666
|
+
cell: tab,
|
|
1667
|
+
color: "#FF8700",
|
|
1668
|
+
label: meaning
|
|
1669
|
+
}))
|
|
1670
|
+
}
|
|
1671
|
+
] : [],
|
|
1672
|
+
{
|
|
1673
|
+
title: "Keys",
|
|
1674
|
+
rows: keys.map(([key, label]) => ({ cell: key, color: "cyan", label }))
|
|
1675
|
+
}
|
|
1676
|
+
];
|
|
1677
|
+
const groups = legendLayout(cols, available);
|
|
1678
|
+
const widths = groups.map((g) => Math.min(groupWidth(g), available));
|
|
1679
|
+
const contentWidth = Math.min(available, layoutWidth(groups));
|
|
1571
1680
|
return /* @__PURE__ */ jsxs(
|
|
1572
1681
|
Box,
|
|
1573
1682
|
{
|
|
1574
1683
|
flexDirection: "column",
|
|
1575
1684
|
borderStyle: "round",
|
|
1576
1685
|
borderColor: "cyan",
|
|
1686
|
+
backgroundColor: OVERLAY_BG,
|
|
1577
1687
|
paddingX: 1,
|
|
1688
|
+
width: contentWidth + MODAL_CHROME_COLS,
|
|
1578
1689
|
children: [
|
|
1579
|
-
/* @__PURE__ */ jsx(
|
|
1580
|
-
/* @__PURE__ */
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
/* @__PURE__ */ jsx(Text, { color, bold: true, children: icon + " " }),
|
|
1592
|
-
/* @__PURE__ */ jsx(Text, { children: " " + label })
|
|
1593
|
-
] }, icon)),
|
|
1594
|
-
/* @__PURE__ */ jsxs(Box, { children: [
|
|
1595
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color: "#FF8700", children: "\uF086 " }),
|
|
1596
|
-
/* @__PURE__ */ jsx(Text, { children: " Open-thread count" })
|
|
1597
|
-
] })
|
|
1598
|
-
] }),
|
|
1599
|
-
tabHelp ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginRight: 3, minWidth: 30, children: [
|
|
1600
|
-
/* @__PURE__ */ jsx(Text, { bold: true, dimColor: true, children: "Tabs" }),
|
|
1601
|
-
tabHelp.map(([tab, meaning]) => /* @__PURE__ */ jsxs(Box, { children: [
|
|
1602
|
-
/* @__PURE__ */ jsx(Text, { color: "#FF8700", children: tab.padEnd(10) }),
|
|
1603
|
-
/* @__PURE__ */ jsx(Text, { children: meaning })
|
|
1604
|
-
] }, tab))
|
|
1605
|
-
] }) : null,
|
|
1606
|
-
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
1607
|
-
/* @__PURE__ */ jsx(Text, { bold: true, dimColor: true, children: "Keys" }),
|
|
1608
|
-
keys.map(([k, label]) => /* @__PURE__ */ jsxs(Box, { children: [
|
|
1609
|
-
/* @__PURE__ */ jsx(Text, { color: "cyan", children: k.padEnd(11) }),
|
|
1610
|
-
/* @__PURE__ */ jsx(Text, { children: label })
|
|
1611
|
-
] }, k))
|
|
1612
|
-
] })
|
|
1613
|
-
] }),
|
|
1614
|
-
tabHelp ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Each item lands in the FIRST tab that claims it, so counts are residuals rather than totals." }) : null,
|
|
1615
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "esc \xB7 ? close" })
|
|
1690
|
+
/* @__PURE__ */ jsx(Text2, { color: "cyan", bold: true, children: "Legend" }),
|
|
1691
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, width: contentWidth, children: groups.map((group, index) => /* @__PURE__ */ jsx(
|
|
1692
|
+
LegendGroup,
|
|
1693
|
+
{
|
|
1694
|
+
group,
|
|
1695
|
+
width: widths[index],
|
|
1696
|
+
marginRight: index === groups.length - 1 ? 0 : COL_GAP
|
|
1697
|
+
},
|
|
1698
|
+
group[0]?.title ?? index
|
|
1699
|
+
)) }),
|
|
1700
|
+
tabHelp ? /* @__PURE__ */ jsx(Text2, { dimColor: true, children: "Each item lands in the FIRST tab that claims it, so counts are residuals rather than totals." }) : null,
|
|
1701
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: "esc \xB7 ? close" })
|
|
1616
1702
|
]
|
|
1617
1703
|
}
|
|
1618
1704
|
);
|
|
@@ -1623,16 +1709,17 @@ var ExplainModal = ({ item, login }) => /* @__PURE__ */ jsxs(
|
|
|
1623
1709
|
flexDirection: "column",
|
|
1624
1710
|
borderStyle: "round",
|
|
1625
1711
|
borderColor: "cyan",
|
|
1712
|
+
backgroundColor: OVERLAY_BG,
|
|
1626
1713
|
paddingX: 1,
|
|
1627
1714
|
width: Math.min(COLS, 78),
|
|
1628
1715
|
children: [
|
|
1629
|
-
/* @__PURE__ */ jsx(
|
|
1630
|
-
/* @__PURE__ */ jsx(
|
|
1716
|
+
/* @__PURE__ */ jsx(Text2, { color: "#FF8700", bold: true, children: `#${item.number} \xB7 ${item.repo}` }),
|
|
1717
|
+
/* @__PURE__ */ jsx(Text2, { children: item.title }),
|
|
1631
1718
|
explainItem(item, login).map((section) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
1632
|
-
/* @__PURE__ */ jsx(
|
|
1633
|
-
section.lines.map((line, i) => /* @__PURE__ */ jsx(
|
|
1719
|
+
/* @__PURE__ */ jsx(Text2, { bold: true, dimColor: true, children: section.heading }),
|
|
1720
|
+
section.lines.map((line, i) => /* @__PURE__ */ jsx(Text2, { children: " " + line }, i))
|
|
1634
1721
|
] }, section.heading)),
|
|
1635
|
-
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(
|
|
1722
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text2, { dimColor: true, children: "esc \xB7 e close" }) })
|
|
1636
1723
|
]
|
|
1637
1724
|
}
|
|
1638
1725
|
);
|
|
@@ -1654,24 +1741,25 @@ var RepoPicker = ({
|
|
|
1654
1741
|
flexDirection: "column",
|
|
1655
1742
|
borderStyle: "round",
|
|
1656
1743
|
borderColor: "cyan",
|
|
1744
|
+
backgroundColor: OVERLAY_BG,
|
|
1657
1745
|
paddingX: 1,
|
|
1658
1746
|
minWidth: 42,
|
|
1659
1747
|
children: [
|
|
1660
|
-
/* @__PURE__ */ jsx(
|
|
1661
|
-
/* @__PURE__ */ jsx(
|
|
1748
|
+
/* @__PURE__ */ jsx(Text2, { color: "cyan", bold: true, children: `Filter by repo (${selected.size} on)` }),
|
|
1749
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: "\u2500".repeat(36) }),
|
|
1662
1750
|
visible.map((repo, i) => {
|
|
1663
1751
|
const idx = start + i;
|
|
1664
1752
|
const on = selected.has(repo);
|
|
1665
1753
|
const active = idx === cursor;
|
|
1666
1754
|
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
1667
|
-
/* @__PURE__ */ jsx(
|
|
1668
|
-
/* @__PURE__ */ jsx(
|
|
1669
|
-
/* @__PURE__ */ jsx(
|
|
1755
|
+
/* @__PURE__ */ jsx(Text2, { color: "cyan", children: active ? "\u276F " : " " }),
|
|
1756
|
+
/* @__PURE__ */ jsx(Text2, { color: on ? "green" : void 0, children: on ? "\u25C9 " : "\u25CB " }),
|
|
1757
|
+
/* @__PURE__ */ jsx(Text2, { bold: active, children: repo })
|
|
1670
1758
|
] }, repo);
|
|
1671
1759
|
}),
|
|
1672
|
-
repos.length > budget ? /* @__PURE__ */ jsx(
|
|
1673
|
-
/* @__PURE__ */ jsx(
|
|
1674
|
-
/* @__PURE__ */ jsx(
|
|
1760
|
+
repos.length > budget ? /* @__PURE__ */ jsx(Text2, { dimColor: true, children: ` \u2026 ${repos.length} repos total` }) : null,
|
|
1761
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: "\u2500".repeat(36) }),
|
|
1762
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: "space toggle \xB7 a clear all \xB7 \u21B5/esc done" })
|
|
1675
1763
|
]
|
|
1676
1764
|
}
|
|
1677
1765
|
);
|
|
@@ -2083,6 +2171,22 @@ var BrowseScreen = ({
|
|
|
2083
2171
|
(i) => i.kind !== "repo-header" && i.kind !== "subgroup-header"
|
|
2084
2172
|
).length;
|
|
2085
2173
|
if (hidden) return null;
|
|
2174
|
+
const overlay = help ? /* @__PURE__ */ jsx(
|
|
2175
|
+
HelpModal,
|
|
2176
|
+
{
|
|
2177
|
+
workToggle,
|
|
2178
|
+
extensions,
|
|
2179
|
+
hasJira: !!jiraBase,
|
|
2180
|
+
tabHelp
|
|
2181
|
+
}
|
|
2182
|
+
) : explain && activeItem && (activeItem.kind === "pr" || activeItem.kind === "issue") ? /* @__PURE__ */ jsx(ExplainModal, { item: activeItem, login }) : repoPicker ? /* @__PURE__ */ jsx(
|
|
2183
|
+
RepoPicker,
|
|
2184
|
+
{
|
|
2185
|
+
repos: allRepos,
|
|
2186
|
+
selected: repoFilter,
|
|
2187
|
+
cursor: Math.min(repoCursor, Math.max(0, allRepos.length - 1))
|
|
2188
|
+
}
|
|
2189
|
+
) : menu.actions && activeItem && activeItem.kind !== "repo-header" ? /* @__PURE__ */ jsx(ActionMenu, { item: activeItem, actions: menu.actions, cursor: menu.cursor }) : null;
|
|
2086
2190
|
return /* @__PURE__ */ jsxs(
|
|
2087
2191
|
Box,
|
|
2088
2192
|
{
|
|
@@ -2118,106 +2222,60 @@ var BrowseScreen = ({
|
|
|
2118
2222
|
}
|
|
2119
2223
|
) }),
|
|
2120
2224
|
search != null ? /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
2121
|
-
/* @__PURE__ */ jsx(
|
|
2122
|
-
/* @__PURE__ */ jsx(
|
|
2123
|
-
searchInput ? /* @__PURE__ */ jsx(
|
|
2225
|
+
/* @__PURE__ */ jsx(Text2, { color: "cyan", children: " / " }),
|
|
2226
|
+
/* @__PURE__ */ jsx(Text2, { children: search }),
|
|
2227
|
+
searchInput ? /* @__PURE__ */ jsx(Text2, { color: "cyan", children: "\u258F" }) : null,
|
|
2124
2228
|
/* @__PURE__ */ jsx(
|
|
2125
|
-
|
|
2229
|
+
Text2,
|
|
2126
2230
|
{
|
|
2127
2231
|
dimColor: true,
|
|
2128
2232
|
children: ` ${matchCount} match${matchCount !== 1 ? "es" : ""}${searchInput ? " \u21B5 accept \xB7 esc clear" : " esc clear"}`
|
|
2129
2233
|
}
|
|
2130
2234
|
)
|
|
2131
2235
|
] }) : repoFilter.size > 0 ? /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
2132
|
-
/* @__PURE__ */ jsx(
|
|
2133
|
-
/* @__PURE__ */ jsx(
|
|
2134
|
-
/* @__PURE__ */ jsx(
|
|
2236
|
+
/* @__PURE__ */ jsx(Text2, { color: "#FF8700", children: " \u25C9 " }),
|
|
2237
|
+
/* @__PURE__ */ jsx(Text2, { children: `${repoFilter.size} repo${repoFilter.size !== 1 ? "s" : ""}` }),
|
|
2238
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: " f edit \xB7 esc clear" })
|
|
2135
2239
|
] }) : null,
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
flexDirection: "column",
|
|
2141
|
-
justifyContent: "center",
|
|
2142
|
-
alignItems: "center",
|
|
2143
|
-
children: /* @__PURE__ */ jsx(
|
|
2144
|
-
HelpModal,
|
|
2145
|
-
{
|
|
2146
|
-
workToggle,
|
|
2147
|
-
extensions,
|
|
2148
|
-
hasJira: !!jiraBase,
|
|
2149
|
-
tabHelp
|
|
2150
|
-
}
|
|
2151
|
-
)
|
|
2152
|
-
}
|
|
2153
|
-
) : explain && activeItem && (activeItem.kind === "pr" || activeItem.kind === "issue") ? /* @__PURE__ */ jsx(
|
|
2154
|
-
Box,
|
|
2155
|
-
{
|
|
2156
|
-
minHeight: listHeight,
|
|
2157
|
-
flexDirection: "column",
|
|
2158
|
-
justifyContent: "center",
|
|
2159
|
-
alignItems: "center",
|
|
2160
|
-
children: /* @__PURE__ */ jsx(ExplainModal, { item: activeItem, login })
|
|
2161
|
-
}
|
|
2162
|
-
) : repoPicker ? /* @__PURE__ */ jsx(
|
|
2163
|
-
Box,
|
|
2164
|
-
{
|
|
2165
|
-
minHeight: listHeight,
|
|
2166
|
-
flexDirection: "column",
|
|
2167
|
-
justifyContent: "center",
|
|
2168
|
-
alignItems: "center",
|
|
2169
|
-
children: /* @__PURE__ */ jsx(
|
|
2170
|
-
RepoPicker,
|
|
2171
|
-
{
|
|
2172
|
-
repos: allRepos,
|
|
2173
|
-
selected: repoFilter,
|
|
2174
|
-
cursor: Math.min(repoCursor, Math.max(0, allRepos.length - 1))
|
|
2175
|
-
}
|
|
2176
|
-
)
|
|
2177
|
-
}
|
|
2178
|
-
) : menu.actions && activeItem && activeItem.kind !== "repo-header" ? /* @__PURE__ */ jsx(
|
|
2179
|
-
Box,
|
|
2180
|
-
{
|
|
2181
|
-
minHeight: listHeight,
|
|
2182
|
-
flexDirection: "column",
|
|
2183
|
-
justifyContent: "center",
|
|
2184
|
-
alignItems: "center",
|
|
2185
|
-
children: /* @__PURE__ */ jsx(
|
|
2186
|
-
ActionMenu,
|
|
2240
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", minHeight: listHeight, children: [
|
|
2241
|
+
/* @__PURE__ */ jsxs(Backdrop, { dimmed: !!overlay, absolute: !!overlay, height: listHeight, children: [
|
|
2242
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", flexGrow: 1, children: visibleItems.map((item, i) => /* @__PURE__ */ jsx(
|
|
2243
|
+
ItemRow,
|
|
2187
2244
|
{
|
|
2188
|
-
item
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2245
|
+
item,
|
|
2246
|
+
active: viewStart + i === cursor,
|
|
2247
|
+
login,
|
|
2248
|
+
gap: viewStart + i > 0 && (item.kind === "repo-header" || item.kind === "subgroup-header" || // A header is always followed by a blank line before its
|
|
2249
|
+
// first child — in Other PRs that's "free" because the
|
|
2250
|
+
// child is itself a repo-header (gap above). A jira row
|
|
2251
|
+
// has no such stand-in, so it needs this explicitly. Never
|
|
2252
|
+
// applies between two tickets/PRs — only right after a
|
|
2253
|
+
// header.
|
|
2254
|
+
item.kind === "jira" && ["repo-header", "subgroup-header"].includes(
|
|
2255
|
+
section.items[viewStart + i - 1]?.kind
|
|
2256
|
+
))
|
|
2257
|
+
},
|
|
2258
|
+
`${viewStart + i}:${item.kind === "jira" ? item.instanceKey ?? item.key : item.kind === "repo-header" ? `header:${item.repo}` : item.kind === "subgroup-header" ? `subgroup:${item.label}` : item.kind === "show-more" ? `show-more:${item.hidden[0]?.repo ?? i}` : item.kind === "show-less" ? `show-less:${item.toHide[0]?.repo ?? i}` : `${item.repo}/${item.number}`}`
|
|
2259
|
+
)) }),
|
|
2260
|
+
hasMore && /* @__PURE__ */ jsxs(Text2, { dimColor: true, children: [
|
|
2261
|
+
" ",
|
|
2262
|
+
"\u2193 ",
|
|
2263
|
+
section.items.length - viewStart - visibleCount,
|
|
2264
|
+
" more"
|
|
2265
|
+
] })
|
|
2266
|
+
] }),
|
|
2267
|
+
overlay ? /* @__PURE__ */ jsx(
|
|
2268
|
+
Box,
|
|
2197
2269
|
{
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
// applies between two tickets/PRs — only right after a
|
|
2206
|
-
// header.
|
|
2207
|
-
item.kind === "jira" && ["repo-header", "subgroup-header"].includes(
|
|
2208
|
-
section.items[viewStart + i - 1]?.kind
|
|
2209
|
-
))
|
|
2210
|
-
},
|
|
2211
|
-
`${viewStart + i}:${item.kind === "jira" ? item.instanceKey ?? item.key : item.kind === "repo-header" ? `header:${item.repo}` : item.kind === "subgroup-header" ? `subgroup:${item.label}` : item.kind === "show-more" ? `show-more:${item.hidden[0]?.repo ?? i}` : item.kind === "show-less" ? `show-less:${item.toHide[0]?.repo ?? i}` : `${item.repo}/${item.number}`}`
|
|
2212
|
-
)) }),
|
|
2213
|
-
hasMore && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
2214
|
-
" ",
|
|
2215
|
-
"\u2193 ",
|
|
2216
|
-
section.items.length - viewStart - visibleCount,
|
|
2217
|
-
" more"
|
|
2218
|
-
] })
|
|
2270
|
+
flexGrow: 1,
|
|
2271
|
+
flexDirection: "column",
|
|
2272
|
+
justifyContent: "center",
|
|
2273
|
+
alignItems: "center",
|
|
2274
|
+
children: overlay
|
|
2275
|
+
}
|
|
2276
|
+
) : null
|
|
2219
2277
|
] }),
|
|
2220
|
-
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: flash ? /* @__PURE__ */ jsx(
|
|
2278
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: flash ? /* @__PURE__ */ jsx(Text2, { color: "green", children: flash }) : /* @__PURE__ */ jsx(FooterHints, { hints }) })
|
|
2221
2279
|
]
|
|
2222
2280
|
}
|
|
2223
2281
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kud/gh-ink",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Ink components for rendering GitHub PR review comments and health — controlled, presentation-only, built on @kud/ink-ui and fed by @kud/gh.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|