@kud/gh-ink 0.45.2 → 0.45.5
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 +40 -12
- package/dist/index.js +33 -7
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -279,24 +279,52 @@ declare const runInPaneHorizontal: (cmd: string) => Promise<void>;
|
|
|
279
279
|
declare const runHere: (cmd: string) => void;
|
|
280
280
|
declare const COLS: number;
|
|
281
281
|
/**
|
|
282
|
-
* What the tab badge and the header total both count
|
|
283
|
-
* work, at the top level.
|
|
282
|
+
* What the tab badge and the header total both count.
|
|
284
283
|
*
|
|
285
|
-
*
|
|
286
|
-
*
|
|
287
|
-
*
|
|
288
|
-
*
|
|
289
|
-
*
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
284
|
+
* ONE INVARIANT: a piece of work counts once, at whatever depth the board
|
|
285
|
+
* happens to file it. Everything below follows from that, and the name says so
|
|
286
|
+
* because the old one — `workCount` — read as a fact about the tree and so
|
|
287
|
+
* nobody re-asked whether the tree still meant what it had when it was written.
|
|
288
|
+
* It did not, and the count silently went to zero.
|
|
289
|
+
*
|
|
290
|
+
* Furniture never counts: headers and the show-more/show-less affordances are
|
|
291
|
+
* not entities at all, which is why the search and repo filters drop them too.
|
|
292
|
+
* `role: "container"` rows ARE entities, selectable and openable; they are
|
|
293
|
+
* simply not work. An epic is the case that forced the distinction — real,
|
|
294
|
+
* owned, on screen until it closes, but the work is the stories under it, and
|
|
293
295
|
* counting it as well reported five things to do where there were four.
|
|
294
296
|
*
|
|
297
|
+
* Everything else counts when it is a LEAF — when nothing hangs under it. That
|
|
298
|
+
* is the only predicate under which the invariant holds. A PR on a tab of its
|
|
299
|
+
* own counts one; the same PR after its ticket becomes parseable, so that it now
|
|
300
|
+
* hangs under a story, still counts one. Counting every non-container row would
|
|
301
|
+
* make that transition raise the total, which is the epic bug one level down:
|
|
302
|
+
* nothing was created, the board merely got tidier, and the header claims you
|
|
303
|
+
* have more to do.
|
|
304
|
+
*
|
|
305
|
+
* It also settles the 0-to-1 case in the right direction. A story with no PR is
|
|
306
|
+
* its own leaf and counts one — a ticket in review with nothing to show is real
|
|
307
|
+
* work, arguably the most actionable row on the board. It gains its first PR and
|
|
308
|
+
* still counts one: the story stops being the item and its PR becomes the item.
|
|
309
|
+
* A row earns container-hood by HAVING children, which is why this lives in the
|
|
310
|
+
* predicate rather than in a flag the host has to remember to set.
|
|
311
|
+
*
|
|
312
|
+
* A collapsed tail contributes what it HIDES, and that line is load-bearing:
|
|
313
|
+
* pressing return on a `show-more` splices its rows into `items` in place, so
|
|
314
|
+
* without it the badge would rise on expanding and fall on collapsing — a key
|
|
315
|
+
* that only changes what is drawn would change how much work you have. With it,
|
|
316
|
+
* collapsed contributes `hidden.length` and expanded contributes the same rows
|
|
317
|
+
* as leaves, and the number holds still.
|
|
318
|
+
*
|
|
319
|
+
* Leaf-ness is read off the RENDERED list, so a search that hides a story's PRs
|
|
320
|
+
* turns that story back into a leaf and it counts itself. That is deliberate:
|
|
321
|
+
* the badge describes what is on screen to act on.
|
|
322
|
+
*
|
|
295
323
|
* One function, both consumers, on purpose. The badge and the whole-board total
|
|
296
324
|
* are the same claim at two scales; computed apart they drift, and a header that
|
|
297
325
|
* disagrees with the sum of its own tabs is worse than either number alone.
|
|
298
326
|
*/
|
|
299
|
-
declare const
|
|
327
|
+
declare const workCount: (s: Section) => number;
|
|
300
328
|
declare const drillCmd: (item: AnyItem) => string | null;
|
|
301
329
|
declare const explainGhAction: (e: unknown) => string;
|
|
302
330
|
declare const buildActions: (item: AnyItem, login: string, showFlash: (msg: string) => void, jiraBase?: string, jiraKeyRe?: RegExp, jiraTransitions?: JiraTransition[], onRefresh?: () => void, onRemove?: (item: GHItem) => void, onOpenView?: (item: AnyItem) => boolean, ext?: {
|
|
@@ -418,4 +446,4 @@ declare const matchesFilter: (repo: string, filter: RepoFilter) => boolean;
|
|
|
418
446
|
*/
|
|
419
447
|
declare const parsePatterns: (value: string) => string[];
|
|
420
448
|
|
|
421
|
-
export { type Action, ActionMenu, App, COLS, CiStatusLine, type CiStatusState, CommentsPanel, type CommentsPanelProps, type DetailContext, type ExplainSection, type ExtensionTarget, HealthPanel, type HealthPanelProps, type InboxBudget, type InboxExtension, type JiraTransition, type RepoFilter, SIDEBAR_COLS, SidePanel, type Sidebar, type SidebarRow, budgetNotice, buildActions, buildCheckoutCmd, clipboard, counts, drillCmd, explainGhAction, explainItem, fitCount, gapsAbove, healthColor, healthDisplay, healthGlyph, healthLegend, itermRun, jumpToRepo, jumpToRepoPane, matchesFilter, maxViewStart, moveCursor, openInTab, parsePatterns, railCapacity, readCache, renderMarkdown, reposInSections, resolveRepoPath, runHere, runInPane, runInPaneHorizontal, sameCiStatusState, signatureOf, toCiStatusState,
|
|
449
|
+
export { type Action, ActionMenu, App, COLS, CiStatusLine, type CiStatusState, CommentsPanel, type CommentsPanelProps, type DetailContext, type ExplainSection, type ExtensionTarget, HealthPanel, type HealthPanelProps, type InboxBudget, type InboxExtension, type JiraTransition, type RepoFilter, SIDEBAR_COLS, SidePanel, type Sidebar, type SidebarRow, budgetNotice, buildActions, buildCheckoutCmd, clipboard, counts, drillCmd, explainGhAction, explainItem, fitCount, gapsAbove, healthColor, healthDisplay, healthGlyph, healthLegend, itermRun, jumpToRepo, jumpToRepoPane, matchesFilter, maxViewStart, moveCursor, openInTab, parsePatterns, railCapacity, readCache, renderMarkdown, reposInSections, resolveRepoPath, runHere, runInPane, runInPaneHorizontal, sameCiStatusState, signatureOf, toCiStatusState, truncate, useActionMenu, windowCount, withHeaders, withoutItem, workCount, writeCache };
|
package/dist/index.js
CHANGED
|
@@ -1352,9 +1352,23 @@ var Backdrop = ({
|
|
|
1352
1352
|
children
|
|
1353
1353
|
}
|
|
1354
1354
|
) : children });
|
|
1355
|
-
var
|
|
1356
|
-
|
|
1357
|
-
|
|
1355
|
+
var workCount = (s) => {
|
|
1356
|
+
let n = 0;
|
|
1357
|
+
for (let i = 0; i < s.items.length; i++) {
|
|
1358
|
+
const item = s.items[i];
|
|
1359
|
+
if (!item) continue;
|
|
1360
|
+
if (item.kind === "show-more") {
|
|
1361
|
+
n += item.hidden.length;
|
|
1362
|
+
continue;
|
|
1363
|
+
}
|
|
1364
|
+
if (item.kind === "repo-header" || item.kind === "subgroup-header" || item.kind === "show-less")
|
|
1365
|
+
continue;
|
|
1366
|
+
if ("role" in item && item.role === "container") continue;
|
|
1367
|
+
if (depthOf(s.items[i + 1]) > depthOf(item)) continue;
|
|
1368
|
+
n += 1;
|
|
1369
|
+
}
|
|
1370
|
+
return n;
|
|
1371
|
+
};
|
|
1358
1372
|
var drillCmd = (item) => {
|
|
1359
1373
|
if (item.kind === "task")
|
|
1360
1374
|
return item.ticket ? `jira issue view ${item.ticket}` : null;
|
|
@@ -1701,7 +1715,7 @@ var InboxHeader = ({
|
|
|
1701
1715
|
appliedSummary,
|
|
1702
1716
|
fetchedAt
|
|
1703
1717
|
}) => {
|
|
1704
|
-
const total = sections.reduce((n, s) => n +
|
|
1718
|
+
const total = sections.reduce((n, s) => n + workCount(s), 0);
|
|
1705
1719
|
const countSeg = loading ? " loading\u2026 " : quiet ? " " : ` ${String(total).padStart(3)} item${total !== 1 ? "s" : ""} \xB7 `;
|
|
1706
1720
|
const userSeg = loading || quiet ? "" : `@${login} `;
|
|
1707
1721
|
const workLabel = scopeLabel ? ` ${scopeLabel} ` : "";
|
|
@@ -1791,7 +1805,7 @@ var MERGED_FRAME_MS = 150;
|
|
|
1791
1805
|
var MERGED_FRAMES = ["\u2726", "\u2727", "\u2736", "\u2727"];
|
|
1792
1806
|
var MERGED_COLOUR = "#A371F7";
|
|
1793
1807
|
var TRANSIT_HOLD_MS = 7e3;
|
|
1794
|
-
var TRANSIT_FRAME_TICKS =
|
|
1808
|
+
var TRANSIT_FRAME_TICKS = 1;
|
|
1795
1809
|
var TRANSIT_FRAME_MS = MERGED_FRAME_MS * TRANSIT_FRAME_TICKS;
|
|
1796
1810
|
var rampFrame = (len, loopFrame, transitAt, now = Date.now()) => transitAt == null ? loopFrame % len : Math.max(
|
|
1797
1811
|
0,
|
|
@@ -2960,7 +2974,19 @@ var BrowseScreen = ({
|
|
|
2960
2974
|
items: localSections.map((s) => ({
|
|
2961
2975
|
value: s.id,
|
|
2962
2976
|
label: s.label,
|
|
2963
|
-
count:
|
|
2977
|
+
count: workCount(s),
|
|
2978
|
+
/*
|
|
2979
|
+
* The denominator, and only where it can still be true.
|
|
2980
|
+
*
|
|
2981
|
+
* `sampled.total` is what the SEARCHES matched; `count` is what this
|
|
2982
|
+
* frame draws. A filter moves the numerator and cannot move the
|
|
2983
|
+
* denominator, so `20/97` under an active search would be a fraction
|
|
2984
|
+
* of two different populations — worse than no fraction, because it
|
|
2985
|
+
* reads as precise. Dropping it here rather than upstream is the
|
|
2986
|
+
* whole reason the total arrives as a number instead of baked into
|
|
2987
|
+
* the label: this is the only layer that knows a filter is on.
|
|
2988
|
+
*/
|
|
2989
|
+
total: filterActive ? void 0 : s.sampled?.total,
|
|
2964
2990
|
// Its own cell, always two wide, so news arriving never slides the
|
|
2965
2991
|
// bar — and free to animate for exactly that reason.
|
|
2966
2992
|
// The ticker undivided — see TAB_PULSE. The row marks' /3 buys quiet
|
|
@@ -3514,4 +3540,4 @@ var matchesFilter = (repo, filter) => {
|
|
|
3514
3540
|
};
|
|
3515
3541
|
var parsePatterns = (value) => value.split(",").map((p) => p.trim()).filter(Boolean);
|
|
3516
3542
|
|
|
3517
|
-
export { ActionMenu, App, COLS, CiStatusLine, CommentsPanel, HealthPanel, SIDEBAR_COLS, SidePanel, budgetNotice, buildActions, buildCheckoutCmd, clipboard, counts, drillCmd, explainGhAction, explainItem, fitCount, gapsAbove, healthColor, healthDisplay, healthGlyph, healthLegend, itermRun, jumpToRepo, jumpToRepoPane, matchesFilter, maxViewStart, moveCursor, openInTab, parsePatterns, railCapacity, readCache, renderMarkdown, reposInSections, resolveRepoPath, runHere, runInPane, runInPaneHorizontal, sameCiStatusState, signatureOf, toCiStatusState,
|
|
3543
|
+
export { ActionMenu, App, COLS, CiStatusLine, CommentsPanel, HealthPanel, SIDEBAR_COLS, SidePanel, budgetNotice, buildActions, buildCheckoutCmd, clipboard, counts, drillCmd, explainGhAction, explainItem, fitCount, gapsAbove, healthColor, healthDisplay, healthGlyph, healthLegend, itermRun, jumpToRepo, jumpToRepoPane, matchesFilter, maxViewStart, moveCursor, openInTab, parsePatterns, railCapacity, readCache, renderMarkdown, reposInSections, resolveRepoPath, runHere, runInPane, runInPaneHorizontal, sameCiStatusState, signatureOf, toCiStatusState, truncate2 as truncate, useActionMenu, windowCount, withHeaders, withoutItem, workCount, writeCache };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kud/gh-ink",
|
|
3
|
-
"version": "0.45.
|
|
3
|
+
"version": "0.45.5",
|
|
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",
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
"react": ">=19"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@kud/gh": "0.12.
|
|
52
|
-
"@kud/
|
|
53
|
-
"
|
|
54
|
-
"
|
|
51
|
+
"@kud/gh": "0.12.1",
|
|
52
|
+
"@kud/gh-workflow": "0.3.1",
|
|
53
|
+
"@kud/ink-ui": "0.23.0",
|
|
54
|
+
"zx": "8.8.5"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/node": "22.20.1",
|