@kud/gh-ink 0.75.2 → 0.76.1
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.d.ts +5 -4
- package/dist/index.js +67 -27
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -426,9 +426,10 @@ type LayoutInput = Pick<PrRowProps, "item" | "login" | "cols" | "prefix" | "unif
|
|
|
426
426
|
};
|
|
427
427
|
/**
|
|
428
428
|
* Which trailing columns the section has to give up, so that every row gives up
|
|
429
|
-
* the same ones.
|
|
430
|
-
*
|
|
431
|
-
* for all of them
|
|
429
|
+
* the same ones. Drops come from two places: width pressure — each row is laid
|
|
430
|
+
* out alone and the drops are unioned, so if any row needs its size cell gone
|
|
431
|
+
* to keep a readable title, the size column goes for all of them — and
|
|
432
|
+
* emptiness, where no row in the section fills the column at all.
|
|
432
433
|
*
|
|
433
434
|
* Forcing a drop on a row that did not need it only ever hands that row more
|
|
434
435
|
* room, so it can never push the row further down the ladder than it went on
|
|
@@ -994,7 +995,7 @@ declare const ActionMenu: ({ item, actions, cursor, cols, }: {
|
|
|
994
995
|
cursor: number;
|
|
995
996
|
/**
|
|
996
997
|
* Content columns the menu may take. The width is fixed from the longest
|
|
997
|
-
* row
|
|
998
|
+
* row and the title — see `menuWidthFor` — so it never
|
|
998
999
|
* resizes as the cursor moves. A host beside a rail passes what the list
|
|
999
1000
|
* has; everywhere else the frame's own width is the right answer.
|
|
1000
1001
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React5, { createContext, useState, useRef, useContext, useEffect, useCallback, useMemo } from 'react';
|
|
2
2
|
import { useWindowSize, useInput, Text, Box } from 'ink';
|
|
3
3
|
import { colors, ScrollView, TextInput, Pill, getIconMode, FooterHints, useAppKeys, LoadingScreen, pillWidth, StatusMessage, useFilterMode, useListCursor, CommandPalette, Tabs, ProgressBar } from '@kud/ink-ui';
|
|
4
4
|
import { isPassCheck, isFailCheck, isInconclusiveCheck, resolveThread, unresolveThread, replyToThread, rerunFailedRun, mergePr, reRequestReviewer, parseRef, formatRef, fetchItemNode } from '@kud/gh';
|
|
@@ -444,7 +444,7 @@ var Summary = ({
|
|
|
444
444
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
445
445
|
/* @__PURE__ */ jsx(Text, { bold: true, children: label.padEnd(10) }),
|
|
446
446
|
/* @__PURE__ */ jsx(Text, { children: icon + " " }),
|
|
447
|
-
parts.map(([text, color], i) => /* @__PURE__ */ jsxs(
|
|
447
|
+
parts.map(([text, color], i) => /* @__PURE__ */ jsxs(React5.Fragment, { children: [
|
|
448
448
|
i > 0 && /* @__PURE__ */ jsx(Text, { dimColor: true, children: " \xB7 " }),
|
|
449
449
|
/* @__PURE__ */ jsx(Text, { color, children: text })
|
|
450
450
|
] }, text + i))
|
|
@@ -857,15 +857,28 @@ var trailingColumnsOf = (items) => items.reduce(
|
|
|
857
857
|
{ author: 0, threads: 0, size: 0, age: 0 }
|
|
858
858
|
);
|
|
859
859
|
var numberColumnsOf = (items) => items.reduce((w, item) => Math.max(w, cellsOf(`#${item.number}`)), 0) + 2;
|
|
860
|
-
var sectionShedOf = (rows, context) =>
|
|
861
|
-
const
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
860
|
+
var sectionShedOf = (rows, context) => {
|
|
861
|
+
const noAuthor = rows.every(
|
|
862
|
+
({ item }) => !item.author || item.author === context.login
|
|
863
|
+
);
|
|
864
|
+
const noThreads = rows.every(({ item }) => !threadsLabelOf(item));
|
|
865
|
+
const empty = {
|
|
866
|
+
...noAuthor ? { author: true } : {},
|
|
867
|
+
...noThreads ? { threads: true } : {}
|
|
867
868
|
};
|
|
868
|
-
|
|
869
|
+
return rows.reduce(
|
|
870
|
+
(shed, row) => {
|
|
871
|
+
const { givingUp } = layoutOf({ ...context, ...row });
|
|
872
|
+
return {
|
|
873
|
+
author: shed.author || givingUp.author,
|
|
874
|
+
threads: shed.threads || givingUp.threads,
|
|
875
|
+
size: shed.size || givingUp.size,
|
|
876
|
+
age: shed.age || givingUp.age
|
|
877
|
+
};
|
|
878
|
+
},
|
|
879
|
+
{ ...empty }
|
|
880
|
+
);
|
|
881
|
+
};
|
|
869
882
|
var layoutOf = ({
|
|
870
883
|
item,
|
|
871
884
|
login,
|
|
@@ -1068,7 +1081,7 @@ var PrRow = ({
|
|
|
1068
1081
|
/* @__PURE__ */ jsx(Text3, { color: colors.secondary, children: agePair.activity }),
|
|
1069
1082
|
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: ` (${agePair.lifetime})` })
|
|
1070
1083
|
] }) : ageLabel2 ? /* @__PURE__ */ jsx(Text3, { color: colors.secondary, children: ageLabel2 }) : null }) : null,
|
|
1071
|
-
backdropped ? null : announcements.map((a) => /* @__PURE__ */ jsxs(
|
|
1084
|
+
backdropped ? null : announcements.map((a) => /* @__PURE__ */ jsxs(React5.Fragment, { children: [
|
|
1072
1085
|
/* @__PURE__ */ jsx(Text3, { children: " " }),
|
|
1073
1086
|
/* @__PURE__ */ jsx(Pill, { color: a.color, children: a.label })
|
|
1074
1087
|
] }, a.label))
|
|
@@ -1102,12 +1115,14 @@ var ageLabel = (at, now = Date.now()) => {
|
|
|
1102
1115
|
if (m < 60) return `${m}m`;
|
|
1103
1116
|
return `${Math.round(m / 60)}h`;
|
|
1104
1117
|
};
|
|
1105
|
-
var itemText = (item) => `${stripGlyph(item.state)[0]}${item.alarm ? ` ${ALARM}` : ""} ${item.key}`;
|
|
1118
|
+
var itemText = (item) => item.state === "fail" ? `${stripGlyph("fail")[0]} ${item.key}` : `${stripGlyph(item.state)[0]}${item.alarm ? ` ${ALARM}` : ""} ${item.key}`;
|
|
1119
|
+
var itemWidth = (item) => item.state === "fail" ? pillWidth(itemText(item)) : itemText(item).length;
|
|
1106
1120
|
var stripLayout = (strip, width, now = Date.now()) => {
|
|
1107
1121
|
const age = ageLabel(strip.at, now);
|
|
1108
1122
|
const fixed = 2 + strip.title.length + 2 + (age ? age.length + 3 : 0);
|
|
1109
1123
|
const full = strip.items.map(itemText).join(" ");
|
|
1110
|
-
|
|
1124
|
+
const fullWidth = strip.items.reduce((n, item) => n + itemWidth(item), 0) + Math.max(0, strip.items.length - 1) * 2;
|
|
1125
|
+
if (fixed + fullWidth <= width)
|
|
1111
1126
|
return { parts: strip.items, summary: full, age };
|
|
1112
1127
|
const sorted = [...strip.items].sort(
|
|
1113
1128
|
(a, b) => SEVERITY[a.state] - SEVERITY[b.state]
|
|
@@ -1122,13 +1137,13 @@ var stripLayout = (strip, width, now = Date.now()) => {
|
|
|
1122
1137
|
const rest = bad.slice(n);
|
|
1123
1138
|
const counts2 = ["fail", "warn", "unknown"].map((s) => tally(rest.filter((i) => i.state === s).length, s)).filter(Boolean);
|
|
1124
1139
|
text = [tally(ok, "ok"), ...counts2, ...named.map(itemText)].filter(Boolean).join(" \xB7 ");
|
|
1125
|
-
|
|
1140
|
+
const textWidth = text.length + 2 * named.filter((i) => i.state === "fail").length;
|
|
1141
|
+
if (fixed + textWidth <= width) break;
|
|
1126
1142
|
}
|
|
1127
1143
|
return { parts: null, summary: text, age };
|
|
1128
1144
|
};
|
|
1129
1145
|
var nameStyle = (item) => {
|
|
1130
|
-
if (item.
|
|
1131
|
-
return { color: colors.error, bold: true };
|
|
1146
|
+
if (item.alarm) return { color: colors.error, bold: true };
|
|
1132
1147
|
if (item.state === "unknown") return { dimColor: true };
|
|
1133
1148
|
return {};
|
|
1134
1149
|
};
|
|
@@ -1152,9 +1167,14 @@ var StatusStripLine = ({
|
|
|
1152
1167
|
return /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
1153
1168
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ` ${strip.title} ` }),
|
|
1154
1169
|
parts ? parts.map((item, i) => {
|
|
1170
|
+
if (item.state === "fail")
|
|
1171
|
+
return /* @__PURE__ */ jsxs(React5.Fragment, { children: [
|
|
1172
|
+
i > 0 ? /* @__PURE__ */ jsx(Text, { children: " " }) : null,
|
|
1173
|
+
/* @__PURE__ */ jsx(Pill, { variant: "error", tone: "solid", children: itemText(item) })
|
|
1174
|
+
] }, item.key);
|
|
1155
1175
|
const [glyph, color] = stripGlyph(item.state);
|
|
1156
|
-
const asking = item.state === "
|
|
1157
|
-
return /* @__PURE__ */ jsxs(
|
|
1176
|
+
const asking = item.state === "warn";
|
|
1177
|
+
return /* @__PURE__ */ jsxs(React5.Fragment, { children: [
|
|
1158
1178
|
i > 0 ? /* @__PURE__ */ jsx(Text, { children: " " }) : null,
|
|
1159
1179
|
/* @__PURE__ */ jsx(
|
|
1160
1180
|
Text,
|
|
@@ -2809,6 +2829,8 @@ var buildActions = (item, login, showFlash, jiraBase, jiraKeyRe, jiraTransitions
|
|
|
2809
2829
|
actions.push(...closing);
|
|
2810
2830
|
return byGroup(actions);
|
|
2811
2831
|
};
|
|
2832
|
+
var TAB_STRIP_ROWS = 3;
|
|
2833
|
+
var FILTER_BAR_ROWS = 2;
|
|
2812
2834
|
var agoText = (ms) => {
|
|
2813
2835
|
const d = (Date.now() - ms) / 1e3;
|
|
2814
2836
|
if (d < 60) return "just now";
|
|
@@ -3168,6 +3190,13 @@ var useActionMenu = () => {
|
|
|
3168
3190
|
};
|
|
3169
3191
|
return { actions, cursor, open, close: () => setActions(null), handleKey };
|
|
3170
3192
|
};
|
|
3193
|
+
var TITLE_SLACK = 1;
|
|
3194
|
+
var MENU_MAX_WIDTH = 88;
|
|
3195
|
+
var menuWidthFor = (cols, contentWidth, titleWidth) => Math.min(
|
|
3196
|
+
Math.max(contentWidth + 4, titleWidth + 4, 40),
|
|
3197
|
+
MENU_MAX_WIDTH,
|
|
3198
|
+
Math.max(20, cols - 4)
|
|
3199
|
+
);
|
|
3171
3200
|
var ActionMenu = ({
|
|
3172
3201
|
item,
|
|
3173
3202
|
actions,
|
|
@@ -3189,19 +3218,16 @@ var ActionMenu = ({
|
|
|
3189
3218
|
]
|
|
3190
3219
|
)
|
|
3191
3220
|
);
|
|
3192
|
-
const width = Math.min(
|
|
3193
|
-
Math.max(contentWidth + 4, 40),
|
|
3194
|
-
56,
|
|
3195
|
-
Math.max(20, cols - 4)
|
|
3196
|
-
);
|
|
3197
|
-
const inner = Math.max(1, width - 4);
|
|
3198
3221
|
const confirming = isConfirmRows(actions);
|
|
3199
|
-
const isCloseRow = (row) => menuTone(row) === "error";
|
|
3200
3222
|
const number = item.kind === "pr" || item.kind === "issue" ? item.number : null;
|
|
3201
3223
|
const leadNum = item.kind === "task" ? item.key : number !== null ? `#${number}` : "";
|
|
3202
3224
|
const lead = leadNum ? `${leadNum} \xB7 ` : "";
|
|
3203
3225
|
const rest = confirming ? `Close #${number}?` : item.kind === "task" ? item.summary : item.kind === "pr" || item.kind === "issue" ? item.title : "";
|
|
3204
|
-
const
|
|
3226
|
+
const titleWidth = [...lead].length + [...rest].length + TITLE_SLACK;
|
|
3227
|
+
const width = menuWidthFor(cols, contentWidth, titleWidth);
|
|
3228
|
+
const inner = Math.max(1, width - 4);
|
|
3229
|
+
const restText = [...lead].length + [...rest].length + TITLE_SLACK <= inner ? rest : [...rest].slice(0, Math.max(0, inner - [...lead].length - 1 - TITLE_SLACK)).join("") + "\u2026";
|
|
3230
|
+
const isCloseRow = (row) => menuTone(row) === "error";
|
|
3205
3231
|
return /* @__PURE__ */ jsxs(
|
|
3206
3232
|
Box,
|
|
3207
3233
|
{
|
|
@@ -4580,7 +4606,21 @@ var BrowseScreen = ({
|
|
|
4580
4606
|
// and footer below, the body where the list was. Fixed to the list's
|
|
4581
4607
|
// own height so the frame holds still between browse and drill, and
|
|
4582
4608
|
// clipped rather than spilling past the footer on a long body.
|
|
4583
|
-
|
|
4609
|
+
//
|
|
4610
|
+
// Plus the rows the overlay hides: the tab strip and, when a filter
|
|
4611
|
+
// is on, its bar. `listHeight` already paid for both, so a band of
|
|
4612
|
+
// exactly `listHeight` left the frame three rows short of the
|
|
4613
|
+
// terminal under every drill and extension body, five with a filter
|
|
4614
|
+
// kept — the bottom border floating above the screen's edge.
|
|
4615
|
+
/* @__PURE__ */ jsx(
|
|
4616
|
+
Box,
|
|
4617
|
+
{
|
|
4618
|
+
flexDirection: "column",
|
|
4619
|
+
height: listHeight + TAB_STRIP_ROWS + (filterActive ? FILTER_BAR_ROWS : 0),
|
|
4620
|
+
overflow: "hidden",
|
|
4621
|
+
children: overlayBody
|
|
4622
|
+
}
|
|
4623
|
+
)
|
|
4584
4624
|
) : /* @__PURE__ */ jsxs(
|
|
4585
4625
|
Box,
|
|
4586
4626
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kud/gh-ink",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.76.1",
|
|
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",
|