@kud/gh-ink 0.75.1 → 0.76.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.d.ts +9 -4
- package/dist/index.js +68 -44
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -196,7 +196,11 @@ declare const SidePanel: ({ sidebar, liveLabel, width, height, focused, cursor,
|
|
|
196
196
|
type FocusSlot = {
|
|
197
197
|
/** The mark in front of the row, accent by default. */
|
|
198
198
|
mark?: string;
|
|
199
|
-
/**
|
|
199
|
+
/**
|
|
200
|
+
* The mark's colour in the list gutter (`focusCellFor`). Defaults to the
|
|
201
|
+
* accent. The ready row's pill takes its accent from its own
|
|
202
|
+
* `variant="accent"`, so this never reaches the pill.
|
|
203
|
+
*/
|
|
200
204
|
markColor?: string;
|
|
201
205
|
/** What the row is a slot OF, in the host's words: `focus`, say. */
|
|
202
206
|
label: string;
|
|
@@ -422,9 +426,10 @@ type LayoutInput = Pick<PrRowProps, "item" | "login" | "cols" | "prefix" | "unif
|
|
|
422
426
|
};
|
|
423
427
|
/**
|
|
424
428
|
* Which trailing columns the section has to give up, so that every row gives up
|
|
425
|
-
* the same ones.
|
|
426
|
-
*
|
|
427
|
-
* 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.
|
|
428
433
|
*
|
|
429
434
|
* Forcing a drop on a row that did not need it only ever hands that row more
|
|
430
435
|
* room, so it can never push the row further down the ladder than it went on
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React5, { createContext, useState, useRef, useContext, useEffect, useCallback, useMemo } from 'react';
|
|
2
2
|
import { useWindowSize, useInput, Text, Box } from 'ink';
|
|
3
|
-
import { colors, ScrollView, TextInput, Pill, getIconMode, FooterHints, useAppKeys, LoadingScreen, StatusMessage, useFilterMode, useListCursor, CommandPalette, Tabs, ProgressBar
|
|
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';
|
|
5
5
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
6
6
|
import { PIN_MARK, sizeOf, sizePartsOf, depthOf, impliedLabels, labelPriority, checkoutDirs, profileOf, inboxConfig, relativeTime, filterBySearch, filterByRepos, filterByOrigin, refCandidates, resolveRef } from '@kud/gh-workflow';
|
|
@@ -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,
|
|
@@ -1707,7 +1727,7 @@ var cells = (s) => [...s].length;
|
|
|
1707
1727
|
var titleBudgetOf = (focus, label, width, jumpKey) => {
|
|
1708
1728
|
const hint = jumpKey ? jumpKey : void 0;
|
|
1709
1729
|
const mark = focus.mark ?? FOCUS_MARK;
|
|
1710
|
-
const head = 2 +
|
|
1730
|
+
const head = 2 + pillWidth(`${mark} ${label}`) + 2 + (focus.marker ? cells(focus.marker) + 1 : 0) + cells(focus.ref) + 2;
|
|
1711
1731
|
const hintCells = hint ? 3 + cells(hint) + 5 : 0;
|
|
1712
1732
|
const tail = 3 + cells(focus.reason);
|
|
1713
1733
|
const titleMax = width - head - tail - hintCells;
|
|
@@ -1747,8 +1767,8 @@ var FocusSlotLine = ({
|
|
|
1747
1767
|
const { title, reason, hint } = titleBudgetOf(focus, label, width, jumpKey);
|
|
1748
1768
|
return /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
1749
1769
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
1750
|
-
/* @__PURE__ */ jsx(
|
|
1751
|
-
/* @__PURE__ */ jsx(Text, {
|
|
1770
|
+
/* @__PURE__ */ jsx(Pill, { variant: "accent", tone: "tonal", children: `${mark} ${label}` }),
|
|
1771
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
1752
1772
|
focus.marker ? /* @__PURE__ */ jsx(Text, { children: `${focus.marker} ` }) : null,
|
|
1753
1773
|
/* @__PURE__ */ jsx(Text, { color: focusRefColor(focus), bold: true, children: `${focus.ref} ` }),
|
|
1754
1774
|
/* @__PURE__ */ jsx(Text, { bold: true, children: title }),
|
|
@@ -4728,7 +4748,15 @@ var App = ({
|
|
|
4728
4748
|
onSettled
|
|
4729
4749
|
}) => {
|
|
4730
4750
|
const { rows } = useWindowSize();
|
|
4731
|
-
const [
|
|
4751
|
+
const [launchCache] = useState(() => cacheKey ? readCache(cacheKey) : null);
|
|
4752
|
+
const launchPainted = !!launchCache && launchCache.sections.length > 0;
|
|
4753
|
+
const [state, setState] = useState(
|
|
4754
|
+
() => launchPainted && launchCache ? {
|
|
4755
|
+
phase: "browse",
|
|
4756
|
+
sections: launchCache.sections,
|
|
4757
|
+
login: launchCache.login
|
|
4758
|
+
} : { phase: "loading" }
|
|
4759
|
+
);
|
|
4732
4760
|
const browsePeel = useRef(null);
|
|
4733
4761
|
const drillPeel = useRef(null);
|
|
4734
4762
|
const [typing, setTyping] = useState(false);
|
|
@@ -4758,7 +4786,9 @@ var App = ({
|
|
|
4758
4786
|
});
|
|
4759
4787
|
const [pending, setPending] = useState(null);
|
|
4760
4788
|
const [refreshing, setRefreshing] = useState(false);
|
|
4761
|
-
const [fetchedAt, setFetchedAt] = useState(
|
|
4789
|
+
const [fetchedAt, setFetchedAt] = useState(
|
|
4790
|
+
launchPainted && launchCache ? launchCache.at : null
|
|
4791
|
+
);
|
|
4762
4792
|
const [refreshError, setRefreshError] = useState(null);
|
|
4763
4793
|
const [ciStatusState, setCiStatusState] = useState({
|
|
4764
4794
|
kind: "loading"
|
|
@@ -4777,8 +4807,12 @@ var App = ({
|
|
|
4777
4807
|
if (prev.kind !== "ready") return next;
|
|
4778
4808
|
return stripSignature(prev.strip) === stripSignature(strip) ? prev : next;
|
|
4779
4809
|
});
|
|
4780
|
-
const displayedKey = useRef(
|
|
4781
|
-
|
|
4810
|
+
const displayedKey = useRef(
|
|
4811
|
+
launchPainted && launchCache ? signatureOf(launchCache.sections) : ""
|
|
4812
|
+
);
|
|
4813
|
+
const displayedSections = useRef(
|
|
4814
|
+
launchPainted && launchCache ? launchCache.sections : []
|
|
4815
|
+
);
|
|
4782
4816
|
const [transients, setTransients] = useState(NO_TRANSIENTS);
|
|
4783
4817
|
const transitTabs = useRef(/* @__PURE__ */ new Map());
|
|
4784
4818
|
const [heldSince, setHeldSince] = useState(NO_HOLDS);
|
|
@@ -5043,21 +5077,7 @@ var App = ({
|
|
|
5043
5077
|
setTimeout(() => applyOrRefresh(), 1500);
|
|
5044
5078
|
};
|
|
5045
5079
|
useEffect(() => {
|
|
5046
|
-
|
|
5047
|
-
const painted = !!cached && cached.sections.length > 0;
|
|
5048
|
-
if (painted && cached) {
|
|
5049
|
-
displayedKey.current = signatureOf(cached.sections);
|
|
5050
|
-
displayedSections.current = cached.sections;
|
|
5051
|
-
setFetchedAt(cached.at);
|
|
5052
|
-
if (cached.sidebar) setSidebar(cached.sidebar);
|
|
5053
|
-
if (cached.focus !== void 0) setFocus(cached.focus);
|
|
5054
|
-
setState({
|
|
5055
|
-
phase: "browse",
|
|
5056
|
-
sections: cached.sections,
|
|
5057
|
-
login: cached.login
|
|
5058
|
-
});
|
|
5059
|
-
}
|
|
5060
|
-
if (!painted || !isFresh(cached)) revalidate();
|
|
5080
|
+
if (!launchPainted || !isFresh(launchCache)) revalidate();
|
|
5061
5081
|
}, []);
|
|
5062
5082
|
useEffect(() => {
|
|
5063
5083
|
if (!hasCiStatus || !ciFetcher) return;
|
|
@@ -5133,8 +5153,12 @@ var App = ({
|
|
|
5133
5153
|
() => cacheKey ? readCache(cacheKey)?.budget ?? null : null
|
|
5134
5154
|
);
|
|
5135
5155
|
const [appliedSummary, setAppliedSummary] = useState("");
|
|
5136
|
-
const [sidebar, setSidebar] = useState(
|
|
5137
|
-
|
|
5156
|
+
const [sidebar, setSidebar] = useState(
|
|
5157
|
+
launchPainted ? launchCache?.sidebar : void 0
|
|
5158
|
+
);
|
|
5159
|
+
const [focus, setFocus] = useState(
|
|
5160
|
+
launchPainted ? launchCache?.focus : void 0
|
|
5161
|
+
);
|
|
5138
5162
|
const [skippedForBudget, setSkippedForBudget] = useState(false);
|
|
5139
5163
|
const [mergedUrls, setMergedUrls] = useState([]);
|
|
5140
5164
|
const [leavingUrls, setLeavingUrls] = useState([]);
|
|
@@ -5202,7 +5226,7 @@ var App = ({
|
|
|
5202
5226
|
flexDirection: "column",
|
|
5203
5227
|
minHeight: Math.max(
|
|
5204
5228
|
5,
|
|
5205
|
-
rows -
|
|
5229
|
+
rows - 5 - (hasCiStatus ? 2 : 0) - (hasStrip ? 2 : 0) - (hasFocusSlot ? 2 : 0)
|
|
5206
5230
|
),
|
|
5207
5231
|
children: state.phase === "loading" ? /* @__PURE__ */ jsx(LoadingScreen, { label: `Fetching ${title}\u2026` }) : /* @__PURE__ */ jsx(
|
|
5208
5232
|
NoRowsScreen,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kud/gh-ink",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.76.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",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"access": "public"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
|
-
"@kud/ink-ui": ">=0.
|
|
47
|
+
"@kud/ink-ui": ">=0.41.0 <1",
|
|
48
48
|
"ink": ">=7",
|
|
49
49
|
"react": ">=19"
|
|
50
50
|
},
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"zx": "8.8.5"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@kud/ink-ui": "0.
|
|
57
|
+
"@kud/ink-ui": "0.41.0",
|
|
58
58
|
"@types/node": "22.20.1",
|
|
59
59
|
"@types/react": "19.2.17",
|
|
60
60
|
"ink": "7.1.0",
|