@kud/gh-ink 0.59.1 → 0.61.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 +88 -4
- package/dist/index.js +355 -299
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React, { ReactNode } from 'react';
|
|
2
2
|
import { PrComments, PrHealthData, PrCheck, Health } from '@kud/gh';
|
|
3
|
-
import {
|
|
4
|
-
import { AnyItem, Section, CiStatus, GHItem, OriginSplit } from '@kud/gh-workflow';
|
|
3
|
+
import { GHItem, AnyItem, Section, CiStatus, OriginSplit } from '@kud/gh-workflow';
|
|
5
4
|
export { AnyItem, Band, CiStatus, GHDetail, GHItem, InboxConfig, Move, OriginSplit, PIN_MARK, RepoHeader, RepoProfile, Section, ShowLess, ShowMore, Standing, SubgroupHeader, TaskRow, bandOf, checkoutDirs, configureInbox, filterByOrigin, filterByRepos, filterBySearch, impliedLabels, inboxConfig, insertRepoHeaders, labelPriority, layoutGHItems, profileOf, relativeTime, repoPriority, resetInboxConfig, sortByRecency, sortItems, whoseMove } from '@kud/gh-workflow';
|
|
5
|
+
import { StyledLine } from '@kud/ink-ui';
|
|
6
6
|
|
|
7
7
|
type CommentsPanelProps = {
|
|
8
8
|
repo: string;
|
|
@@ -179,6 +179,82 @@ declare const SidePanel: ({ sidebar, liveLabel, width, height, focused, cursor,
|
|
|
179
179
|
cursor?: number;
|
|
180
180
|
}) => React.JSX.Element;
|
|
181
181
|
|
|
182
|
+
/**
|
|
183
|
+
* How this row is moving through the list right now.
|
|
184
|
+
*
|
|
185
|
+
* The row itself never works this out: whoever owns the list owns the
|
|
186
|
+
* choreography — what counts as an arrival, how long a departure is held, which
|
|
187
|
+
* frame of a ramp is on screen — and hands the row the conclusion. So this
|
|
188
|
+
* enumerates what the TITLE has to say, not what happened upstream to cause it.
|
|
189
|
+
*
|
|
190
|
+
* `withdrawn` is `departing` plus the strike: a row struck through is one that
|
|
191
|
+
* has been taken off the list rather than moved along it, and the two read
|
|
192
|
+
* differently on purpose.
|
|
193
|
+
*/
|
|
194
|
+
type RowMotion = "arriving" | "departing" | "withdrawn";
|
|
195
|
+
/**
|
|
196
|
+
* A solid pill at the end of the row, saying what just happened to it.
|
|
197
|
+
*
|
|
198
|
+
* Solid because it is an EVENT — `@kud/ink-ui`'s pill law in one line: the
|
|
199
|
+
* column says where it sits, soft says what it is, solid says something
|
|
200
|
+
* happened. The word and the colour are the caller's vocabulary; what the row
|
|
201
|
+
* owns is that the pill is charged against the width budget whether or not it
|
|
202
|
+
* is drawn.
|
|
203
|
+
*/
|
|
204
|
+
type RowAnnouncement = {
|
|
205
|
+
label: string;
|
|
206
|
+
color: string;
|
|
207
|
+
};
|
|
208
|
+
type PrRowProps = {
|
|
209
|
+
item: GHItem;
|
|
210
|
+
active: boolean;
|
|
211
|
+
login?: string;
|
|
212
|
+
/**
|
|
213
|
+
* Columns available to this row, which is NOT always the frame width: a rail
|
|
214
|
+
* beside the list takes its share, and a budget that does not know the rail is
|
|
215
|
+
* there overflows by exactly the rail.
|
|
216
|
+
*/
|
|
217
|
+
cols: number;
|
|
218
|
+
/** Overrides the health glyph — the inbox passes its transit/merge frame here. */
|
|
219
|
+
icon?: {
|
|
220
|
+
glyph: string;
|
|
221
|
+
color: string;
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* This row's tree glyphs, already assembled — see `treePrefix`. Empty for a
|
|
225
|
+
* top-level row.
|
|
226
|
+
*
|
|
227
|
+
* A row cannot work this out about itself: it is a fact about the rows BELOW
|
|
228
|
+
* it (is a sibling still to come?) and about its ANCESTORS (does a stem still
|
|
229
|
+
* need to run past this level?), so the list supplies it.
|
|
230
|
+
*/
|
|
231
|
+
prefix?: string;
|
|
232
|
+
/**
|
|
233
|
+
* Labels carried by EVERY label-bearing row in this section, measured once by
|
|
234
|
+
* the list. Suppressed here for the same reason `impliedLabels` suppresses a
|
|
235
|
+
* repo's conventional ones — a label on every row classifies nothing — but on
|
|
236
|
+
* the section axis, which catches uniformity that comes from the query rather
|
|
237
|
+
* than from a repo convention. Defaulted so a host that does not measure it
|
|
238
|
+
* keeps exactly the behaviour it had.
|
|
239
|
+
*/
|
|
240
|
+
uniformLabels?: readonly string[];
|
|
241
|
+
/** How the title reads while the row is coming or going. Still when absent. */
|
|
242
|
+
motion?: RowMotion;
|
|
243
|
+
/** In order, left to right. Charged against the width budget either way. */
|
|
244
|
+
announcements?: readonly RowAnnouncement[];
|
|
245
|
+
};
|
|
246
|
+
/**
|
|
247
|
+
* One pull request or issue, as a single line of a list.
|
|
248
|
+
*
|
|
249
|
+
* The shared renderer: the inbox draws its rows with it, and so does anything
|
|
250
|
+
* else that has a `GHItem` and a width. Everything it knows is in its props —
|
|
251
|
+
* it holds no timers, reads no clock, and has no opinion about whether the list
|
|
252
|
+
* is refreshing. That is deliberate and it is the seam: the choreography of
|
|
253
|
+
* arrival, merge and departure belongs to whoever owns the list, and reaches
|
|
254
|
+
* the row as `icon`, `motion` and `announcements` after the decisions are made.
|
|
255
|
+
*/
|
|
256
|
+
declare const PrRow: ({ item, active, login, cols, icon: iconOverride, prefix, uniformLabels, motion, announcements, }: PrRowProps) => React.JSX.Element;
|
|
257
|
+
|
|
182
258
|
/**
|
|
183
259
|
* One state per thing, from a closed set the strip knows how to draw. The host
|
|
184
260
|
* decides what "warn" means — an error-rate edge, a stale feed, a flaky build —
|
|
@@ -252,6 +328,15 @@ declare const healthGlyph: (h: Health) => string;
|
|
|
252
328
|
declare const healthColor: (h: Health) => string;
|
|
253
329
|
declare const healthLegend: [Health, string][];
|
|
254
330
|
|
|
331
|
+
/**
|
|
332
|
+
* Shorten a string to `max` columns, eliding the MIDDLE rather than the tail.
|
|
333
|
+
*
|
|
334
|
+
* Shared rather than local because both row renderers measure against the same
|
|
335
|
+
* budget arithmetic, and a second copy is a second place for the ellipsis rule
|
|
336
|
+
* to drift.
|
|
337
|
+
*/
|
|
338
|
+
declare const truncate: (str: string, max: number) => string;
|
|
339
|
+
|
|
255
340
|
type ExtensionTarget = {
|
|
256
341
|
item?: AnyItem;
|
|
257
342
|
ciJob?: string;
|
|
@@ -421,7 +506,6 @@ declare const fitCount: (items: AnyItem[], start: number, budget: number) => num
|
|
|
421
506
|
declare const windowCount: (items: AnyItem[], start: number, budget: number) => number;
|
|
422
507
|
declare const maxViewStart: (items: AnyItem[], budget: number) => number;
|
|
423
508
|
declare const withHeaders: (items: AnyItem[], idx: number) => number;
|
|
424
|
-
declare const truncate: (str: string, max: number) => string;
|
|
425
509
|
declare const clipboard: (text: string) => void;
|
|
426
510
|
declare const buildCheckoutCmd: (repoFull: string, branch: string, login: string) => Promise<string>;
|
|
427
511
|
declare const resolveRepoPath: (repoFull: string) => Promise<string | null>;
|
|
@@ -629,4 +713,4 @@ declare const matchesFilter: (repo: string, filter: RepoFilter) => boolean;
|
|
|
629
713
|
*/
|
|
630
714
|
declare const parsePatterns: (value: string) => string[];
|
|
631
715
|
|
|
632
|
-
export { type Action, ActionMenu, App, COLS, CiStatusLine, type CiStatusState, type Command, CommentsPanel, type CommentsPanelProps, type DetailContext, type ExplainSection, type ExtensionTarget, HealthPanel, type HealthPanelProps, type InboxBudget, type InboxExtension, type JiraTransition, type LiveLabel, MIN_SIDEBAR_COLS, type Rails, type RepoFilter, SIDEBAR_COLS, SidePanel, type Sidebar, type SidebarRow, type StatusStrip, StatusStripLine, type StripItem, type StripState, type StripStatusState, ageLabel, budgetNotice, buildActions, buildCheckoutCmd, clipboard, counts, drillCmd, explainGhAction, explainItem, fitCount, gapsAbove, healthColor, healthDisplay, healthGlyph, healthLegend, itermRun, jumpToRepo, jumpToRepoPane, matchesFilter, maxViewStart, moveCursor, openInTab, parsePatterns, railCapacity, railHeights, railRowsOf, railWidth, railsOf, readCache, renderMarkdown, reposInSections, resolveRepoPath, runHere, runInPane, runInPaneHorizontal, sameCiStatusState, signatureOf, stripGlyph, stripLayout, stripSignature, toCiStatusState, truncate, useActionMenu, windowCount, withHeaders, withoutItem, workCount, writeCache };
|
|
716
|
+
export { type Action, ActionMenu, App, COLS, CiStatusLine, type CiStatusState, type Command, CommentsPanel, type CommentsPanelProps, type DetailContext, type ExplainSection, type ExtensionTarget, HealthPanel, type HealthPanelProps, type InboxBudget, type InboxExtension, type JiraTransition, type LiveLabel, MIN_SIDEBAR_COLS, PrRow, type PrRowProps, type Rails, type RepoFilter, type RowAnnouncement, type RowMotion, SIDEBAR_COLS, SidePanel, type Sidebar, type SidebarRow, type StatusStrip, StatusStripLine, type StripItem, type StripState, type StripStatusState, ageLabel, budgetNotice, buildActions, buildCheckoutCmd, clipboard, counts, drillCmd, explainGhAction, explainItem, fitCount, gapsAbove, healthColor, healthDisplay, healthGlyph, healthLegend, itermRun, jumpToRepo, jumpToRepoPane, matchesFilter, maxViewStart, moveCursor, openInTab, parsePatterns, railCapacity, railHeights, railRowsOf, railWidth, railsOf, readCache, renderMarkdown, reposInSections, resolveRepoPath, runHere, runInPane, runInPaneHorizontal, sameCiStatusState, signatureOf, stripGlyph, stripLayout, stripSignature, toCiStatusState, truncate, useActionMenu, windowCount, withHeaders, withoutItem, workCount, writeCache };
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import React2, { createContext, useState, useRef, useEffect, useMemo, useContext } from 'react';
|
|
2
2
|
import { useWindowSize, useInput, Text, Box } from 'ink';
|
|
3
|
-
import { colors, ScrollView, TextInput, useAppKeys, LoadingScreen, StatusMessage, FooterHints, useListCursor, CommandPalette, Tabs, ProgressBar, pillWidth
|
|
3
|
+
import { colors, ScrollView, TextInput, Pill, useAppKeys, LoadingScreen, StatusMessage, FooterHints, useListCursor, CommandPalette, Tabs, ProgressBar, pillWidth } from '@kud/ink-ui';
|
|
4
4
|
import { isPassCheck, isFailCheck, isInconclusiveCheck, resolveThread, unresolveThread, replyToThread, rerunFailedRun, mergePr, reRequestReviewer } from '@kud/gh';
|
|
5
5
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
6
|
+
import { PIN_MARK, sizeOf, sizePartsOf, depthOf, impliedLabels, labelPriority, checkoutDirs, profileOf, inboxConfig, relativeTime, filterBySearch, filterByRepos, filterByOrigin } from '@kud/gh-workflow';
|
|
7
|
+
export { PIN_MARK, bandOf, checkoutDirs, configureInbox, filterByOrigin, filterByRepos, filterBySearch, impliedLabels, inboxConfig, insertRepoHeaders, labelPriority, layoutGHItems, profileOf, relativeTime, repoPriority, resetInboxConfig, sortByRecency, sortItems, whoseMove } from '@kud/gh-workflow';
|
|
6
8
|
import { $ } from 'zx';
|
|
7
9
|
import { spawn } from 'child_process';
|
|
8
10
|
import { readFileSync, mkdirSync, writeFileSync, existsSync, readdirSync, statSync, watch, rmSync } from 'fs';
|
|
9
11
|
import { join, dirname, basename } from 'path';
|
|
10
12
|
import { homedir } from 'os';
|
|
11
|
-
import { PIN_MARK, depthOf, checkoutDirs, profileOf, inboxConfig, relativeTime, filterBySearch, filterByRepos, filterByOrigin, sizeOf, sizePartsOf, impliedLabels, labelPriority } from '@kud/gh-workflow';
|
|
12
|
-
export { PIN_MARK, bandOf, checkoutDirs, configureInbox, filterByOrigin, filterByRepos, filterBySearch, impliedLabels, inboxConfig, insertRepoHeaders, labelPriority, layoutGHItems, profileOf, relativeTime, repoPriority, resetInboxConfig, sortByRecency, sortItems, whoseMove } from '@kud/gh-workflow';
|
|
13
13
|
|
|
14
14
|
// src/components/comments-panel.tsx
|
|
15
15
|
var ENTITIES = {
|
|
@@ -748,19 +748,226 @@ var SidePanel = ({
|
|
|
748
748
|
)
|
|
749
749
|
);
|
|
750
750
|
};
|
|
751
|
+
var healthDisplay = {
|
|
752
|
+
none: { glyph: " ", color: colors.muted },
|
|
753
|
+
draft: { glyph: "~", color: colors.muted },
|
|
754
|
+
"ci-fail": { glyph: "\u2717", color: colors.error },
|
|
755
|
+
conflict: { glyph: "!", color: colors.accent },
|
|
756
|
+
"changes-req": { glyph: "\xB1", color: colors.warning },
|
|
757
|
+
threads: { glyph: "\u25C6", color: colors.accent },
|
|
758
|
+
pending: { glyph: "*", color: colors.warning },
|
|
759
|
+
approved: { glyph: "\u2713", color: colors.success },
|
|
760
|
+
waiting: { glyph: "\xB7", color: colors.muted },
|
|
761
|
+
// The one glyph here that MEANS its state rather than merely differing from
|
|
762
|
+
// the others. `✓` and `✗` you never have to think about; `»` you did — it was
|
|
763
|
+
// chosen to suggest "moved through", which is a stretch nobody reads at a
|
|
764
|
+
// glance. This is Nerd Font's git-merge icon, written as an escape because raw
|
|
765
|
+
// PUA bytes get mangled by editors and diffs.
|
|
766
|
+
//
|
|
767
|
+
// The cost, stated rather than discovered: a terminal without a Nerd Font
|
|
768
|
+
// draws a box here where it used to draw a chevron. That is a trade this
|
|
769
|
+
// package has already made once — the inbox hardcodes the comment glyph at
|
|
770
|
+
// \u{f086} — and one state degrading to tofu is cheaper than ten states none
|
|
771
|
+
// of which say what they mean.
|
|
772
|
+
merged: { glyph: "\uE727", color: colors.muted },
|
|
773
|
+
// Nerd Font's closed-pull-request icon, for the same reason as `merged` above
|
|
774
|
+
// and with the same caveat about a font that lacks it. `×` had a second problem
|
|
775
|
+
// beyond being arbitrary: it is one stroke away from `✗` (ci failing) two rows
|
|
776
|
+
// up in this very map, and the shape-distinctness this file turns on is a
|
|
777
|
+
// silhouette test, not a codepoint one.
|
|
778
|
+
closed: { glyph: "\uEBDA", color: colors.muted }
|
|
779
|
+
};
|
|
780
|
+
var healthGlyph = (h) => healthDisplay[h].glyph;
|
|
781
|
+
var healthColor = (h) => healthDisplay[h].color;
|
|
782
|
+
var healthLegend = [
|
|
783
|
+
["approved", "Approved \xB7 ready to merge"],
|
|
784
|
+
["pending", "Checks running"],
|
|
785
|
+
["ci-fail", "CI failing"],
|
|
786
|
+
["conflict", "Merge conflict"],
|
|
787
|
+
["changes-req", "Changes requested"],
|
|
788
|
+
["threads", "Open threads \xB7 your reply"],
|
|
789
|
+
["waiting", "Awaiting review"],
|
|
790
|
+
["draft", "Draft"],
|
|
791
|
+
["merged", "Merged"],
|
|
792
|
+
["closed", "Closed"]
|
|
793
|
+
];
|
|
794
|
+
var UNREAD_DISPLAY = { glyph: "\u25CB", color: colors.muted };
|
|
795
|
+
var displayFor = (h) => h ? healthDisplay[h] : UNREAD_DISPLAY;
|
|
796
|
+
|
|
797
|
+
// src/lib/truncate.ts
|
|
798
|
+
var truncate = (str, max) => {
|
|
799
|
+
if (str.length <= max) return str;
|
|
800
|
+
const half = Math.floor((max - 1) / 2);
|
|
801
|
+
return `${str.slice(0, half)}\u2026${str.slice(-half)}`;
|
|
802
|
+
};
|
|
803
|
+
var DimContext = createContext(false);
|
|
804
|
+
var BACKDROP_FG = "#5a5a68";
|
|
805
|
+
var BACKDROP_FG_RECESSED = "#3a3a46";
|
|
806
|
+
var backdropStyle = (props) => ({
|
|
807
|
+
color: props.dimColor ? BACKDROP_FG_RECESSED : BACKDROP_FG,
|
|
808
|
+
dimColor: false,
|
|
809
|
+
bold: false,
|
|
810
|
+
italic: false,
|
|
811
|
+
inverse: false,
|
|
812
|
+
backgroundColor: void 0
|
|
813
|
+
});
|
|
814
|
+
var Text3 = ({ children, ...props }) => {
|
|
815
|
+
const dimmed = useContext(DimContext);
|
|
816
|
+
return dimmed ? /* @__PURE__ */ jsx(Text, { ...props, ...backdropStyle(props), children }) : /* @__PURE__ */ jsx(Text, { ...props, children });
|
|
817
|
+
};
|
|
818
|
+
var useBackdropped = () => useContext(DimContext);
|
|
819
|
+
var Backdrop = ({
|
|
820
|
+
dimmed,
|
|
821
|
+
absolute,
|
|
822
|
+
height,
|
|
823
|
+
children
|
|
824
|
+
}) => /* @__PURE__ */ jsx(DimContext.Provider, { value: dimmed, children: absolute ? /* @__PURE__ */ jsx(
|
|
825
|
+
Box,
|
|
826
|
+
{
|
|
827
|
+
position: "absolute",
|
|
828
|
+
flexDirection: "column",
|
|
829
|
+
width: "100%",
|
|
830
|
+
height,
|
|
831
|
+
children
|
|
832
|
+
}
|
|
833
|
+
) : children });
|
|
834
|
+
var PrRow = ({
|
|
835
|
+
item,
|
|
836
|
+
active,
|
|
837
|
+
login,
|
|
838
|
+
cols,
|
|
839
|
+
icon: iconOverride,
|
|
840
|
+
prefix = "",
|
|
841
|
+
uniformLabels = [],
|
|
842
|
+
motion,
|
|
843
|
+
announcements = []
|
|
844
|
+
}) => {
|
|
845
|
+
const backdropped = useBackdropped();
|
|
846
|
+
const { glyph: healthIcon, color: healthColor2 } = displayFor(item.health);
|
|
847
|
+
const { glyph: icon, color } = iconOverride ?? {
|
|
848
|
+
glyph: healthIcon,
|
|
849
|
+
color: healthColor2
|
|
850
|
+
};
|
|
851
|
+
const spokeLast = !!login && !!item.lastActor && item.lastActor === login;
|
|
852
|
+
const [turnIcon, turnColor] = item.pinned ? [PIN_MARK, colors.accent] : !login || !item.lastActor || spokeLast ? [" ", colors.muted] : ["\u2190", colors.accent];
|
|
853
|
+
const numStr = `#${item.number}`.padEnd(7);
|
|
854
|
+
const showAuthor = !!item.author && item.author !== login;
|
|
855
|
+
const sizeLabel = sizeOf(item);
|
|
856
|
+
const sizeParts = sizePartsOf(item);
|
|
857
|
+
const unresolvedLabel = item.unresolved > 0 ? `\uF086 ${item.unresolved}` : "";
|
|
858
|
+
const agePair = item.activityAge && item.activityAge !== item.age ? { activity: item.activityAge, lifetime: item.age } : null;
|
|
859
|
+
const ageLabel2 = agePair ? `${agePair.activity} (${agePair.lifetime})` : item.age;
|
|
860
|
+
const pillCaps = announcements.length * 2;
|
|
861
|
+
const repoLabel = depthOf(item) > 0 ? item.repo : "";
|
|
862
|
+
const implied = [...impliedLabels(item.repo), ...uniformLabels];
|
|
863
|
+
const labelNames = (item.labels ?? []).filter((l) => !implied.includes(l)).sort((a, b) => labelPriority(a) - labelPriority(b) || a.localeCompare(b)).slice(0, 2);
|
|
864
|
+
const givingUp = {
|
|
865
|
+
author: false,
|
|
866
|
+
size: false,
|
|
867
|
+
threads: false,
|
|
868
|
+
age: false,
|
|
869
|
+
repo: false,
|
|
870
|
+
labels: 0
|
|
871
|
+
};
|
|
872
|
+
const LABEL_CELL_MAX = 24;
|
|
873
|
+
const labelCell = () => {
|
|
874
|
+
const shown = labelNames.slice(
|
|
875
|
+
0,
|
|
876
|
+
Math.max(0, labelNames.length - givingUp.labels)
|
|
877
|
+
);
|
|
878
|
+
if (shown.length === 0) return "";
|
|
879
|
+
const fitted = [];
|
|
880
|
+
for (const name of shown) {
|
|
881
|
+
const next = [...fitted, name].join(", ");
|
|
882
|
+
if (next.length <= LABEL_CELL_MAX) fitted.push(name);
|
|
883
|
+
}
|
|
884
|
+
if (fitted.length === 0) {
|
|
885
|
+
return `\uF02B ${truncate(shown[0], LABEL_CELL_MAX)}`;
|
|
886
|
+
}
|
|
887
|
+
return `\uF02B ${fitted.join(", ")}`;
|
|
888
|
+
};
|
|
889
|
+
const widthOf2 = () => {
|
|
890
|
+
const suffix = [
|
|
891
|
+
givingUp.age ? "" : ageLabel2 || "",
|
|
892
|
+
// ASCII only, so no PUA double-width correction — see the label cell.
|
|
893
|
+
givingUp.size ? "" : sizeLabel || "",
|
|
894
|
+
givingUp.threads ? "" : unresolvedLabel,
|
|
895
|
+
showAuthor && !givingUp.author ? `by ${item.author}` : "",
|
|
896
|
+
...announcements.map((a) => a.label)
|
|
897
|
+
].filter(Boolean).join(" ");
|
|
898
|
+
const cell = labelCell();
|
|
899
|
+
return 2 + prefix.length + 2 + 2 + 7 + (cell ? 2 + cell.length + 1 : 0) + (givingUp.repo ? 0 : repoLabel.length) + suffix.length + pillCaps + 6;
|
|
900
|
+
};
|
|
901
|
+
const MIN_TITLE = 24;
|
|
902
|
+
for (const give of [
|
|
903
|
+
() => givingUp.author = true,
|
|
904
|
+
() => givingUp.labels = 1,
|
|
905
|
+
() => givingUp.size = true,
|
|
906
|
+
() => givingUp.threads = true,
|
|
907
|
+
() => givingUp.labels = 2,
|
|
908
|
+
() => givingUp.repo = true,
|
|
909
|
+
() => givingUp.age = true
|
|
910
|
+
]) {
|
|
911
|
+
if (cols - widthOf2() >= MIN_TITLE) break;
|
|
912
|
+
give();
|
|
913
|
+
}
|
|
914
|
+
const labelLabel = labelCell();
|
|
915
|
+
const titleMax = Math.max(1, cols - widthOf2());
|
|
916
|
+
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
917
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.info, children: active ? "\u276F " : " " }),
|
|
918
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: prefix }),
|
|
919
|
+
/* @__PURE__ */ jsx(Text3, { color, bold: true, children: icon + " " }),
|
|
920
|
+
/* @__PURE__ */ jsx(Text3, { color: turnColor, bold: turnIcon === "\u2190", children: turnIcon + " " }),
|
|
921
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.accent, children: numStr }),
|
|
922
|
+
/* @__PURE__ */ jsx(
|
|
923
|
+
Text3,
|
|
924
|
+
{
|
|
925
|
+
bold: active || motion === "arriving",
|
|
926
|
+
dimColor: motion === "departing" || motion === "withdrawn",
|
|
927
|
+
strikethrough: motion === "withdrawn",
|
|
928
|
+
children: truncate(item.title, titleMax) + " "
|
|
929
|
+
}
|
|
930
|
+
),
|
|
931
|
+
labelLabel ? /* @__PURE__ */ jsx(Text3, { color: colors.secondary, children: labelLabel + " " }) : null,
|
|
932
|
+
repoLabel && !givingUp.repo ? /* @__PURE__ */ jsx(Text3, { dimColor: true, children: repoLabel }) : null,
|
|
933
|
+
sizeParts && !givingUp.size ? /* @__PURE__ */ jsxs(Text3, { children: [
|
|
934
|
+
" ",
|
|
935
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.success, children: sizeParts.added }),
|
|
936
|
+
" ",
|
|
937
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.error, children: sizeParts.removed })
|
|
938
|
+
] }) : null,
|
|
939
|
+
unresolvedLabel && !givingUp.threads ? /* @__PURE__ */ jsx(
|
|
940
|
+
Text3,
|
|
941
|
+
{
|
|
942
|
+
bold: !spokeLast,
|
|
943
|
+
color: spokeLast ? colors.secondary : colors.accent,
|
|
944
|
+
children: " " + unresolvedLabel
|
|
945
|
+
}
|
|
946
|
+
) : null,
|
|
947
|
+
showAuthor && !givingUp.author ? /* @__PURE__ */ jsx(Text3, { dimColor: true, italic: true, children: " by " + item.author }) : null,
|
|
948
|
+
ageLabel2 && !givingUp.age ? agePair ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
949
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.secondary, children: " " + agePair.activity }),
|
|
950
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: ` (${agePair.lifetime})` })
|
|
951
|
+
] }) : /* @__PURE__ */ jsx(Text3, { color: colors.secondary, children: " " + ageLabel2 }) : null,
|
|
952
|
+
backdropped ? null : announcements.map((a) => /* @__PURE__ */ jsxs(React2.Fragment, { children: [
|
|
953
|
+
/* @__PURE__ */ jsx(Text3, { children: " " }),
|
|
954
|
+
/* @__PURE__ */ jsx(Pill, { color: a.color, children: a.label })
|
|
955
|
+
] }, a.label))
|
|
956
|
+
] });
|
|
957
|
+
};
|
|
751
958
|
var stripGlyph = (state) => {
|
|
752
959
|
switch (state) {
|
|
753
960
|
case "ok":
|
|
754
|
-
return ["\
|
|
961
|
+
return ["\uF00C", colors.success];
|
|
755
962
|
case "warn":
|
|
756
|
-
return ["
|
|
963
|
+
return ["\uF071", colors.warning];
|
|
757
964
|
case "fail":
|
|
758
|
-
return ["\
|
|
965
|
+
return ["\uF00D", colors.error];
|
|
759
966
|
case "unknown":
|
|
760
|
-
return ["
|
|
967
|
+
return ["?", colors.muted];
|
|
761
968
|
}
|
|
762
969
|
};
|
|
763
|
-
var ALARM = "\
|
|
970
|
+
var ALARM = "\uF06D";
|
|
764
971
|
var SEVERITY = {
|
|
765
972
|
fail: 0,
|
|
766
973
|
warn: 1,
|
|
@@ -775,7 +982,7 @@ var ageLabel = (at, now = Date.now()) => {
|
|
|
775
982
|
if (m < 60) return `${m}m`;
|
|
776
983
|
return `${Math.round(m / 60)}h`;
|
|
777
984
|
};
|
|
778
|
-
var itemText = (item) => `${stripGlyph(item.state)[0]}
|
|
985
|
+
var itemText = (item) => `${stripGlyph(item.state)[0]}${item.alarm ? ` ${ALARM}` : ""} ${item.key}`;
|
|
779
986
|
var stripLayout = (strip, width, now = Date.now()) => {
|
|
780
987
|
const age = ageLabel(strip.at, now);
|
|
781
988
|
const fixed = 2 + strip.title.length + 2 + (age ? age.length + 3 : 0);
|
|
@@ -799,6 +1006,12 @@ var stripLayout = (strip, width, now = Date.now()) => {
|
|
|
799
1006
|
}
|
|
800
1007
|
return { parts: null, summary: text, age };
|
|
801
1008
|
};
|
|
1009
|
+
var nameStyle = (item) => {
|
|
1010
|
+
if (item.state === "fail" || item.alarm)
|
|
1011
|
+
return { color: colors.error, bold: true };
|
|
1012
|
+
if (item.state === "unknown") return { dimColor: true };
|
|
1013
|
+
return {};
|
|
1014
|
+
};
|
|
802
1015
|
var StatusStripLine = ({
|
|
803
1016
|
strip,
|
|
804
1017
|
label = "status",
|
|
@@ -812,7 +1025,7 @@ var StatusStripLine = ({
|
|
|
812
1025
|
] });
|
|
813
1026
|
if (strip === null)
|
|
814
1027
|
return /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
815
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children:
|
|
1028
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ` ${stripGlyph("unknown")[0]} ` }),
|
|
816
1029
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: `${label} no signal / not configured` })
|
|
817
1030
|
] });
|
|
818
1031
|
const { parts, summary, age } = stripLayout(strip, width, now);
|
|
@@ -820,64 +1033,28 @@ var StatusStripLine = ({
|
|
|
820
1033
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ` ${strip.title} ` }),
|
|
821
1034
|
parts ? parts.map((item, i) => {
|
|
822
1035
|
const [glyph, color] = stripGlyph(item.state);
|
|
1036
|
+
const asking = item.state === "fail" || item.state === "warn";
|
|
823
1037
|
return /* @__PURE__ */ jsxs(React2.Fragment, { children: [
|
|
824
1038
|
i > 0 ? /* @__PURE__ */ jsx(Text, { children: " " }) : null,
|
|
825
|
-
/* @__PURE__ */ jsx(
|
|
826
|
-
|
|
1039
|
+
/* @__PURE__ */ jsx(
|
|
1040
|
+
Text,
|
|
1041
|
+
{
|
|
1042
|
+
color: item.state === "unknown" ? void 0 : color,
|
|
1043
|
+
dimColor: item.state === "unknown",
|
|
1044
|
+
bold: asking,
|
|
1045
|
+
children: glyph
|
|
1046
|
+
}
|
|
1047
|
+
),
|
|
1048
|
+
item.alarm ? /* @__PURE__ */ jsx(Text, { color: colors.error, bold: true, children: ` ${ALARM}` }) : null,
|
|
1049
|
+
/* @__PURE__ */ jsxs(Text, { ...nameStyle(item), children: [
|
|
827
1050
|
" ",
|
|
828
1051
|
item.key
|
|
829
|
-
] })
|
|
830
|
-
item.alarm ? /* @__PURE__ */ jsx(Text, { color: colors.error, bold: true, children: ALARM }) : null
|
|
1052
|
+
] })
|
|
831
1053
|
] }, item.key);
|
|
832
1054
|
}) : /* @__PURE__ */ jsx(Text, { children: summary }),
|
|
833
1055
|
age ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` ${age}` }) : null
|
|
834
1056
|
] });
|
|
835
1057
|
};
|
|
836
|
-
var healthDisplay = {
|
|
837
|
-
none: { glyph: " ", color: colors.muted },
|
|
838
|
-
draft: { glyph: "~", color: colors.muted },
|
|
839
|
-
"ci-fail": { glyph: "\u2717", color: colors.error },
|
|
840
|
-
conflict: { glyph: "!", color: colors.accent },
|
|
841
|
-
"changes-req": { glyph: "\xB1", color: colors.warning },
|
|
842
|
-
threads: { glyph: "\u25C6", color: colors.accent },
|
|
843
|
-
pending: { glyph: "*", color: colors.warning },
|
|
844
|
-
approved: { glyph: "\u2713", color: colors.success },
|
|
845
|
-
waiting: { glyph: "\xB7", color: colors.muted },
|
|
846
|
-
// The one glyph here that MEANS its state rather than merely differing from
|
|
847
|
-
// the others. `✓` and `✗` you never have to think about; `»` you did — it was
|
|
848
|
-
// chosen to suggest "moved through", which is a stretch nobody reads at a
|
|
849
|
-
// glance. This is Nerd Font's git-merge icon, written as an escape because raw
|
|
850
|
-
// PUA bytes get mangled by editors and diffs.
|
|
851
|
-
//
|
|
852
|
-
// The cost, stated rather than discovered: a terminal without a Nerd Font
|
|
853
|
-
// draws a box here where it used to draw a chevron. That is a trade this
|
|
854
|
-
// package has already made once — the inbox hardcodes the comment glyph at
|
|
855
|
-
// \u{f086} — and one state degrading to tofu is cheaper than ten states none
|
|
856
|
-
// of which say what they mean.
|
|
857
|
-
merged: { glyph: "\uE727", color: colors.muted },
|
|
858
|
-
// Nerd Font's closed-pull-request icon, for the same reason as `merged` above
|
|
859
|
-
// and with the same caveat about a font that lacks it. `×` had a second problem
|
|
860
|
-
// beyond being arbitrary: it is one stroke away from `✗` (ci failing) two rows
|
|
861
|
-
// up in this very map, and the shape-distinctness this file turns on is a
|
|
862
|
-
// silhouette test, not a codepoint one.
|
|
863
|
-
closed: { glyph: "\uEBDA", color: colors.muted }
|
|
864
|
-
};
|
|
865
|
-
var healthGlyph = (h) => healthDisplay[h].glyph;
|
|
866
|
-
var healthColor = (h) => healthDisplay[h].color;
|
|
867
|
-
var healthLegend = [
|
|
868
|
-
["approved", "Approved \xB7 ready to merge"],
|
|
869
|
-
["pending", "Checks running"],
|
|
870
|
-
["ci-fail", "CI failing"],
|
|
871
|
-
["conflict", "Merge conflict"],
|
|
872
|
-
["changes-req", "Changes requested"],
|
|
873
|
-
["threads", "Open threads \xB7 your reply"],
|
|
874
|
-
["waiting", "Awaiting review"],
|
|
875
|
-
["draft", "Draft"],
|
|
876
|
-
["merged", "Merged"],
|
|
877
|
-
["closed", "Closed"]
|
|
878
|
-
];
|
|
879
|
-
var UNREAD_DISPLAY = { glyph: "\u25CB", color: colors.muted };
|
|
880
|
-
var displayFor = (h) => h ? healthDisplay[h] : UNREAD_DISPLAY;
|
|
881
1058
|
|
|
882
1059
|
// src/inbox/cache.ts
|
|
883
1060
|
var cacheTtlMs = () => inboxConfig().cacheTtlMs;
|
|
@@ -1370,11 +1547,6 @@ var withHeaders = (items, idx) => {
|
|
|
1370
1547
|
start--;
|
|
1371
1548
|
return start;
|
|
1372
1549
|
};
|
|
1373
|
-
var truncate = (str, max) => {
|
|
1374
|
-
if (str.length <= max) return str;
|
|
1375
|
-
const half = Math.floor((max - 1) / 2);
|
|
1376
|
-
return `${str.slice(0, half)}\u2026${str.slice(-half)}`;
|
|
1377
|
-
};
|
|
1378
1550
|
var clipboard = (text) => {
|
|
1379
1551
|
const p = spawn("pbcopy", [], { stdio: "pipe" });
|
|
1380
1552
|
p.stdin.write(text);
|
|
@@ -1559,37 +1731,6 @@ var FRAME_CHROME_COLS = 2 + FRAME_PAD_X * 2;
|
|
|
1559
1731
|
var COLS = (process.stdout.columns ?? 120) - FRAME_CHROME_COLS;
|
|
1560
1732
|
var MODAL_CHROME_COLS = 2 + 1 * 2;
|
|
1561
1733
|
var OVERLAY_BG = "#22222e";
|
|
1562
|
-
var DimContext = createContext(false);
|
|
1563
|
-
var BACKDROP_FG = "#5a5a68";
|
|
1564
|
-
var BACKDROP_FG_RECESSED = "#3a3a46";
|
|
1565
|
-
var backdropStyle = (props) => ({
|
|
1566
|
-
color: props.dimColor ? BACKDROP_FG_RECESSED : BACKDROP_FG,
|
|
1567
|
-
dimColor: false,
|
|
1568
|
-
bold: false,
|
|
1569
|
-
italic: false,
|
|
1570
|
-
inverse: false,
|
|
1571
|
-
backgroundColor: void 0
|
|
1572
|
-
});
|
|
1573
|
-
var Text4 = ({ children, ...props }) => {
|
|
1574
|
-
const dimmed = useContext(DimContext);
|
|
1575
|
-
return dimmed ? /* @__PURE__ */ jsx(Text, { ...props, ...backdropStyle(props), children }) : /* @__PURE__ */ jsx(Text, { ...props, children });
|
|
1576
|
-
};
|
|
1577
|
-
var useBackdropped = () => useContext(DimContext);
|
|
1578
|
-
var Backdrop = ({
|
|
1579
|
-
dimmed,
|
|
1580
|
-
absolute,
|
|
1581
|
-
height,
|
|
1582
|
-
children
|
|
1583
|
-
}) => /* @__PURE__ */ jsx(DimContext.Provider, { value: dimmed, children: absolute ? /* @__PURE__ */ jsx(
|
|
1584
|
-
Box,
|
|
1585
|
-
{
|
|
1586
|
-
position: "absolute",
|
|
1587
|
-
flexDirection: "column",
|
|
1588
|
-
width: "100%",
|
|
1589
|
-
height,
|
|
1590
|
-
children
|
|
1591
|
-
}
|
|
1592
|
-
) : children });
|
|
1593
1734
|
var workCount = (s) => {
|
|
1594
1735
|
let n = 0;
|
|
1595
1736
|
for (let i = 0; i < s.items.length; i++) {
|
|
@@ -1966,13 +2107,13 @@ var InboxHeader = ({
|
|
|
1966
2107
|
COLS - brand.length - countSeg.length - userSeg.length - workLabel.length - budgetSeg.length - statusSeg.length
|
|
1967
2108
|
);
|
|
1968
2109
|
return /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
1969
|
-
/* @__PURE__ */ jsx(
|
|
1970
|
-
/* @__PURE__ */ jsx(
|
|
1971
|
-
userSeg ? /* @__PURE__ */ jsx(
|
|
1972
|
-
scopeLabel ? /* @__PURE__ */ jsx(
|
|
1973
|
-
budgetLabel ? /* @__PURE__ */ jsx(
|
|
2110
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.accent, bold: true, children: brand }),
|
|
2111
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: countSeg }),
|
|
2112
|
+
userSeg ? /* @__PURE__ */ jsx(Text3, { children: userSeg }) : null,
|
|
2113
|
+
scopeLabel ? /* @__PURE__ */ jsx(Text3, { dimColor: true, children: workLabel }) : null,
|
|
2114
|
+
budgetLabel ? /* @__PURE__ */ jsx(Text3, { bold: true, color: budgetCritical ? "#FF5F5F" : colors.accent, children: budgetSeg }) : null,
|
|
1974
2115
|
statusText ? /* @__PURE__ */ jsx(
|
|
1975
|
-
|
|
2116
|
+
Text3,
|
|
1976
2117
|
{
|
|
1977
2118
|
color: statusColor,
|
|
1978
2119
|
dimColor: !statusColor,
|
|
@@ -1980,7 +2121,7 @@ var InboxHeader = ({
|
|
|
1980
2121
|
children: statusSeg
|
|
1981
2122
|
}
|
|
1982
2123
|
) : null,
|
|
1983
|
-
/* @__PURE__ */ jsx(
|
|
2124
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.info, dimColor: true, children: "\u254C".repeat(fill) })
|
|
1984
2125
|
] });
|
|
1985
2126
|
};
|
|
1986
2127
|
var stripSignature = (strip) => strip === null ? "\u2205" : strip.items.map((i) => `${i.key}=${i.state}${i.alarm ? "\u25B2" : ""}`).join(",");
|
|
@@ -2004,24 +2145,24 @@ var CiStatusLine = ({
|
|
|
2004
2145
|
const name = job ?? "ci";
|
|
2005
2146
|
if (state.kind === "loading")
|
|
2006
2147
|
return /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
2007
|
-
/* @__PURE__ */ jsx(
|
|
2008
|
-
/* @__PURE__ */ jsx(
|
|
2148
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: " \xB7 " }),
|
|
2149
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: `${name} loading\u2026` })
|
|
2009
2150
|
] });
|
|
2010
2151
|
if (state.kind === "error")
|
|
2011
2152
|
return /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
2012
|
-
/* @__PURE__ */ jsx(
|
|
2013
|
-
/* @__PURE__ */ jsx(
|
|
2153
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.error, bold: true, children: " \u2717 " }),
|
|
2154
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: `${name} no build / not configured` })
|
|
2014
2155
|
] });
|
|
2015
2156
|
const { status } = state;
|
|
2016
2157
|
const [, color] = jenkinsResultDisplay(status.result, status.building);
|
|
2017
2158
|
const label = status.building ? "BUILDING" : status.result;
|
|
2018
2159
|
return /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
2019
|
-
/* @__PURE__ */ jsx(
|
|
2020
|
-
/* @__PURE__ */ jsx(
|
|
2021
|
-
/* @__PURE__ */ jsx(
|
|
2022
|
-
/* @__PURE__ */ jsx(
|
|
2023
|
-
/* @__PURE__ */ jsx(
|
|
2024
|
-
status.age ? /* @__PURE__ */ jsx(
|
|
2160
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: " " }),
|
|
2161
|
+
/* @__PURE__ */ jsx(Text3, { color, bold: true, children: "\u25CF " }),
|
|
2162
|
+
/* @__PURE__ */ jsx(Text3, { bold: true, children: status.job }),
|
|
2163
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: " " + label }),
|
|
2164
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.accent, children: " #" + status.buildNumber }),
|
|
2165
|
+
status.age ? /* @__PURE__ */ jsx(Text3, { dimColor: true, children: " " + status.age }) : null
|
|
2025
2166
|
] });
|
|
2026
2167
|
};
|
|
2027
2168
|
var FENCE_COLS = 46;
|
|
@@ -2034,10 +2175,10 @@ var RepoHeaderRow = ({
|
|
|
2034
2175
|
const fill = Math.max(4, FENCE_COLS - label.length);
|
|
2035
2176
|
const rule = "\u2500".repeat(fill);
|
|
2036
2177
|
return /* @__PURE__ */ jsxs(Box, { marginTop: gap ? 1 : 0, children: [
|
|
2037
|
-
/* @__PURE__ */ jsx(
|
|
2038
|
-
/* @__PURE__ */ jsx(
|
|
2178
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.info, children: active ? "\u276F " : " " }),
|
|
2179
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: !active, children: "\u2500\u2500 " }),
|
|
2039
2180
|
/* @__PURE__ */ jsx(
|
|
2040
|
-
|
|
2181
|
+
Text3,
|
|
2041
2182
|
{
|
|
2042
2183
|
dimColor: false,
|
|
2043
2184
|
color: active ? void 0 : colors.secondary,
|
|
@@ -2045,7 +2186,7 @@ var RepoHeaderRow = ({
|
|
|
2045
2186
|
children: repo
|
|
2046
2187
|
}
|
|
2047
2188
|
),
|
|
2048
|
-
/* @__PURE__ */ jsx(
|
|
2189
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: !active, children: " " + rule })
|
|
2049
2190
|
] });
|
|
2050
2191
|
};
|
|
2051
2192
|
var MERGED_HOLD_MS = 3e3;
|
|
@@ -2110,48 +2251,48 @@ var ItemRow = ({
|
|
|
2110
2251
|
return /* @__PURE__ */ jsx(RepoHeaderRow, { repo: item.repo, gap: gap ?? false, active });
|
|
2111
2252
|
if (item.kind === "subgroup-header")
|
|
2112
2253
|
return /* @__PURE__ */ jsxs(Box, { marginTop: gap ? 1 : 0, children: [
|
|
2113
|
-
/* @__PURE__ */ jsx(
|
|
2114
|
-
/* @__PURE__ */ jsx(
|
|
2254
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.accent, bold: true, children: " \xBB " }),
|
|
2255
|
+
/* @__PURE__ */ jsx(Text3, { bold: true, children: item.label })
|
|
2115
2256
|
] });
|
|
2116
2257
|
if (item.kind === "show-more")
|
|
2117
2258
|
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
2118
|
-
/* @__PURE__ */ jsx(
|
|
2119
|
-
/* @__PURE__ */ jsx(
|
|
2120
|
-
/* @__PURE__ */ jsx(
|
|
2121
|
-
/* @__PURE__ */ jsx(
|
|
2259
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.info, children: active ? "\u276F " : " " }),
|
|
2260
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: prefix }),
|
|
2261
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: active ? "\u21B5 " : " " }),
|
|
2262
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: `+${item.hidden.length} more` })
|
|
2122
2263
|
] });
|
|
2123
2264
|
if (item.kind === "show-less")
|
|
2124
2265
|
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
2125
|
-
/* @__PURE__ */ jsx(
|
|
2126
|
-
/* @__PURE__ */ jsx(
|
|
2127
|
-
/* @__PURE__ */ jsx(
|
|
2128
|
-
/* @__PURE__ */ jsx(
|
|
2266
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.info, children: active ? "\u276F " : " " }),
|
|
2267
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: prefix }),
|
|
2268
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: active ? "\u21B5 " : " " }),
|
|
2269
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: "show less" })
|
|
2129
2270
|
] });
|
|
2130
2271
|
if (item.kind === "task") {
|
|
2131
2272
|
const note = item.note ?? "";
|
|
2132
2273
|
const transitIcon = !transient ? " " : isDeparture(transient) ? TRANSIT_OUT_FRAMES[rampAt(TRANSIT_OUT_FRAMES.length)] : isArrival(transient) ? TRANSIT_IN_FRAMES[rampAt(TRANSIT_IN_FRAMES.length)] : "\u25C9";
|
|
2133
|
-
const
|
|
2274
|
+
const titleMax = Math.max(
|
|
2134
2275
|
1,
|
|
2135
2276
|
cols - item.key.length - note.length - (item.pill ? pillWidth(item.pill) + 1 : 0) - (farewellLabel ? pillWidth(farewellLabel) + 2 : 0) - prefix.length - (markerCols > 0 ? markerCols + 1 : 0) - 12
|
|
2136
2277
|
);
|
|
2137
2278
|
return /* @__PURE__ */ jsxs(Box, { marginTop: gap ? 1 : 0, children: [
|
|
2138
|
-
/* @__PURE__ */ jsx(
|
|
2139
|
-
/* @__PURE__ */ jsx(
|
|
2140
|
-
/* @__PURE__ */ jsx(
|
|
2141
|
-
/* @__PURE__ */ jsx(
|
|
2142
|
-
markerCols > 0 ? /* @__PURE__ */ jsx(
|
|
2143
|
-
/* @__PURE__ */ jsx(
|
|
2279
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.info, children: active ? "\u276F " : " " }),
|
|
2280
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: prefix }),
|
|
2281
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: parent ? "\u252C " : " " }),
|
|
2282
|
+
/* @__PURE__ */ jsx(Text3, { bold: true, color: transient ? TRANSIT_COLOUR[transient] : void 0, children: transitIcon + " " }),
|
|
2283
|
+
markerCols > 0 ? /* @__PURE__ */ jsx(Text3, { color: item.markerColor, children: (item.marker ?? "").padEnd(markerCols) + " " }) : null,
|
|
2284
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.accent, bold: active, children: item.key + " " }),
|
|
2144
2285
|
/* @__PURE__ */ jsx(
|
|
2145
|
-
|
|
2286
|
+
Text3,
|
|
2146
2287
|
{
|
|
2147
2288
|
bold: active || !!transient && isArrival(transient),
|
|
2148
2289
|
dimColor: !!transient && isDeparture(transient),
|
|
2149
2290
|
strikethrough: transient === "out",
|
|
2150
|
-
children: truncate(item.summary,
|
|
2291
|
+
children: truncate(item.summary, titleMax)
|
|
2151
2292
|
}
|
|
2152
2293
|
),
|
|
2153
2294
|
item.pill && !backdropped ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2154
|
-
/* @__PURE__ */ jsx(
|
|
2295
|
+
/* @__PURE__ */ jsx(Text3, { children: " " }),
|
|
2155
2296
|
/* @__PURE__ */ jsx(
|
|
2156
2297
|
Pill,
|
|
2157
2298
|
{
|
|
@@ -2162,127 +2303,39 @@ var ItemRow = ({
|
|
|
2162
2303
|
}
|
|
2163
2304
|
)
|
|
2164
2305
|
] }) : null,
|
|
2165
|
-
note ? /* @__PURE__ */ jsx(
|
|
2306
|
+
note ? /* @__PURE__ */ jsx(Text3, { dimColor: true, children: ` ${note}` }) : null,
|
|
2166
2307
|
farewellLabel && !backdropped ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2167
|
-
/* @__PURE__ */ jsx(
|
|
2308
|
+
/* @__PURE__ */ jsx(Text3, { children: " " }),
|
|
2168
2309
|
/* @__PURE__ */ jsx(Pill, { color: TRANSIT_COLOUR.out, children: farewellLabel })
|
|
2169
2310
|
] }) : null
|
|
2170
2311
|
] });
|
|
2171
2312
|
}
|
|
2172
|
-
const
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
const
|
|
2180
|
-
const
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
};
|
|
2197
|
-
const LABEL_CELL_MAX = 24;
|
|
2198
|
-
const labelCell = () => {
|
|
2199
|
-
const shown = labelNames.slice(
|
|
2200
|
-
0,
|
|
2201
|
-
Math.max(0, labelNames.length - givingUp.labels)
|
|
2202
|
-
);
|
|
2203
|
-
if (shown.length === 0) return "";
|
|
2204
|
-
const fitted = [];
|
|
2205
|
-
for (const name of shown) {
|
|
2206
|
-
const next = [...fitted, name].join(", ");
|
|
2207
|
-
if (next.length <= LABEL_CELL_MAX) fitted.push(name);
|
|
2208
|
-
}
|
|
2209
|
-
if (fitted.length === 0) {
|
|
2210
|
-
return `\uF02B ${truncate(shown[0], LABEL_CELL_MAX)}`;
|
|
2313
|
+
const icon = merged ? {
|
|
2314
|
+
glyph: MERGED_FRAMES[sparkFrame % MERGED_FRAMES.length],
|
|
2315
|
+
color: MERGED_COLOUR
|
|
2316
|
+
} : transient ? {
|
|
2317
|
+
glyph: isDeparture(transient) ? TRANSIT_OUT_FRAMES[rampAt(TRANSIT_OUT_FRAMES.length)] : isArrival(transient) ? TRANSIT_IN_FRAMES[rampAt(TRANSIT_IN_FRAMES.length)] : displayFor(item.health).glyph,
|
|
2318
|
+
color: TRANSIT_COLOUR[transient]
|
|
2319
|
+
} : void 0;
|
|
2320
|
+
const motion = transient === "out" ? "withdrawn" : transient && isDeparture(transient) ? "departing" : transient && isArrival(transient) ? "arriving" : void 0;
|
|
2321
|
+
const announcements = [
|
|
2322
|
+
...merged ? [{ label: "merged", color: MERGED_COLOUR }] : [],
|
|
2323
|
+
...farewellLabel ? [{ label: farewellLabel, color: TRANSIT_COLOUR.out }] : []
|
|
2324
|
+
];
|
|
2325
|
+
return /* @__PURE__ */ jsx(
|
|
2326
|
+
PrRow,
|
|
2327
|
+
{
|
|
2328
|
+
item,
|
|
2329
|
+
active,
|
|
2330
|
+
login,
|
|
2331
|
+
cols,
|
|
2332
|
+
prefix,
|
|
2333
|
+
uniformLabels,
|
|
2334
|
+
icon,
|
|
2335
|
+
motion,
|
|
2336
|
+
announcements
|
|
2211
2337
|
}
|
|
2212
|
-
|
|
2213
|
-
};
|
|
2214
|
-
const widthOf2 = () => {
|
|
2215
|
-
const suffix = [
|
|
2216
|
-
givingUp.age ? "" : ageLabel2 || "",
|
|
2217
|
-
// ASCII only, so no PUA double-width correction — see the label cell.
|
|
2218
|
-
givingUp.size ? "" : sizeLabel || "",
|
|
2219
|
-
givingUp.threads ? "" : unresolvedLabel,
|
|
2220
|
-
showAuthor && !givingUp.author ? `by ${item.author}` : "",
|
|
2221
|
-
mergedLabel
|
|
2222
|
-
].filter(Boolean).join(" ");
|
|
2223
|
-
const cell = labelCell();
|
|
2224
|
-
return 2 + prefix.length + 2 + 2 + 7 + (cell ? 2 + cell.length + 1 : 0) + (givingUp.repo ? 0 : repoLabel.length) + suffix.length + pillCaps + 6;
|
|
2225
|
-
};
|
|
2226
|
-
const MIN_TITLE = 24;
|
|
2227
|
-
for (const give of [
|
|
2228
|
-
() => givingUp.author = true,
|
|
2229
|
-
() => givingUp.labels = 1,
|
|
2230
|
-
() => givingUp.size = true,
|
|
2231
|
-
() => givingUp.threads = true,
|
|
2232
|
-
() => givingUp.labels = 2,
|
|
2233
|
-
() => givingUp.repo = true,
|
|
2234
|
-
() => givingUp.age = true
|
|
2235
|
-
]) {
|
|
2236
|
-
if (cols - widthOf2() >= MIN_TITLE) break;
|
|
2237
|
-
give();
|
|
2238
|
-
}
|
|
2239
|
-
const labelLabel = labelCell();
|
|
2240
|
-
const titleMax = Math.max(1, cols - widthOf2());
|
|
2241
|
-
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
2242
|
-
/* @__PURE__ */ jsx(Text4, { color: colors.info, children: active ? "\u276F " : " " }),
|
|
2243
|
-
/* @__PURE__ */ jsx(Text4, { dimColor: true, children: prefix }),
|
|
2244
|
-
/* @__PURE__ */ jsx(Text4, { color, bold: true, children: icon + " " }),
|
|
2245
|
-
/* @__PURE__ */ jsx(Text4, { color: turnColor, bold: turnIcon === "\u2190", children: turnIcon + " " }),
|
|
2246
|
-
/* @__PURE__ */ jsx(Text4, { color: colors.accent, children: numStr }),
|
|
2247
|
-
/* @__PURE__ */ jsx(
|
|
2248
|
-
Text4,
|
|
2249
|
-
{
|
|
2250
|
-
bold: active || !!transient && isArrival(transient),
|
|
2251
|
-
dimColor: !!transient && isDeparture(transient),
|
|
2252
|
-
strikethrough: transient === "out",
|
|
2253
|
-
children: truncate(item.title, titleMax) + " "
|
|
2254
|
-
}
|
|
2255
|
-
),
|
|
2256
|
-
labelLabel ? /* @__PURE__ */ jsx(Text4, { color: colors.secondary, children: labelLabel + " " }) : null,
|
|
2257
|
-
repoLabel && !givingUp.repo ? /* @__PURE__ */ jsx(Text4, { dimColor: true, children: repoLabel }) : null,
|
|
2258
|
-
sizeParts && !givingUp.size ? /* @__PURE__ */ jsxs(Text4, { children: [
|
|
2259
|
-
" ",
|
|
2260
|
-
/* @__PURE__ */ jsx(Text4, { color: colors.success, children: sizeParts.added }),
|
|
2261
|
-
" ",
|
|
2262
|
-
/* @__PURE__ */ jsx(Text4, { color: colors.error, children: sizeParts.removed })
|
|
2263
|
-
] }) : null,
|
|
2264
|
-
unresolvedLabel && !givingUp.threads ? /* @__PURE__ */ jsx(
|
|
2265
|
-
Text4,
|
|
2266
|
-
{
|
|
2267
|
-
bold: !spokeLast,
|
|
2268
|
-
color: spokeLast ? colors.secondary : colors.accent,
|
|
2269
|
-
children: " " + unresolvedLabel
|
|
2270
|
-
}
|
|
2271
|
-
) : null,
|
|
2272
|
-
showAuthor && !givingUp.author ? /* @__PURE__ */ jsx(Text4, { dimColor: true, italic: true, children: " by " + item.author }) : null,
|
|
2273
|
-
ageLabel2 && !givingUp.age ? agePair ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2274
|
-
/* @__PURE__ */ jsx(Text4, { color: colors.secondary, children: " " + agePair.activity }),
|
|
2275
|
-
/* @__PURE__ */ jsx(Text4, { dimColor: true, children: ` (${agePair.lifetime})` })
|
|
2276
|
-
] }) : /* @__PURE__ */ jsx(Text4, { color: colors.secondary, children: " " + ageLabel2 }) : null,
|
|
2277
|
-
mergedLabel && !backdropped ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2278
|
-
/* @__PURE__ */ jsx(Text4, { children: " " }),
|
|
2279
|
-
/* @__PURE__ */ jsx(Pill, { color: MERGED_COLOUR, children: mergedLabel })
|
|
2280
|
-
] }) : null,
|
|
2281
|
-
farewellLabel && !backdropped ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2282
|
-
/* @__PURE__ */ jsx(Text4, { children: " " }),
|
|
2283
|
-
/* @__PURE__ */ jsx(Pill, { color: TRANSIT_COLOUR.out, children: farewellLabel })
|
|
2284
|
-
] }) : null
|
|
2285
|
-
] });
|
|
2338
|
+
);
|
|
2286
2339
|
};
|
|
2287
2340
|
var useActionMenu = () => {
|
|
2288
2341
|
const [actions, setActions] = useState(null);
|
|
@@ -2327,15 +2380,15 @@ var ActionMenu = ({
|
|
|
2327
2380
|
paddingX: 1,
|
|
2328
2381
|
marginTop: 1,
|
|
2329
2382
|
children: [
|
|
2330
|
-
/* @__PURE__ */ jsx(
|
|
2331
|
-
/* @__PURE__ */ jsx(
|
|
2383
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.info, bold: true, children: title }),
|
|
2384
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: "\u2500".repeat(32) }),
|
|
2332
2385
|
actions.map((a, i) => /* @__PURE__ */ jsxs(Box, { children: [
|
|
2333
|
-
/* @__PURE__ */ jsx(
|
|
2334
|
-
/* @__PURE__ */ jsx(
|
|
2335
|
-
/* @__PURE__ */ jsx(
|
|
2386
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.info, children: i === cursor ? "\u276F " : " " }),
|
|
2387
|
+
/* @__PURE__ */ jsx(Text3, { bold: i === cursor, children: a.label }),
|
|
2388
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: " " + a.hint })
|
|
2336
2389
|
] }, a.label)),
|
|
2337
|
-
/* @__PURE__ */ jsx(
|
|
2338
|
-
/* @__PURE__ */ jsx(
|
|
2390
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: "\u2500".repeat(32) }),
|
|
2391
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: "\u2191\u2193 navigate \u21B5 confirm esc cancel" })
|
|
2339
2392
|
]
|
|
2340
2393
|
}
|
|
2341
2394
|
);
|
|
@@ -2383,11 +2436,11 @@ var LegendGroup = ({
|
|
|
2383
2436
|
width,
|
|
2384
2437
|
marginRight
|
|
2385
2438
|
}) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width, marginRight, children: [
|
|
2386
|
-
pinned !== void 0 ? /* @__PURE__ */ jsx(
|
|
2439
|
+
pinned !== void 0 ? /* @__PURE__ */ jsx(Text3, { bold: true, dimColor: true, children: pinned ?? " " }) : null,
|
|
2387
2440
|
lines.map(
|
|
2388
|
-
(line, index) => line.kind === "gap" ? /* @__PURE__ */ jsx(
|
|
2389
|
-
/* @__PURE__ */ jsx(
|
|
2390
|
-
/* @__PURE__ */ jsx(
|
|
2441
|
+
(line, index) => line.kind === "gap" ? /* @__PURE__ */ jsx(Text3, { children: " " }, index) : line.kind === "title" ? /* @__PURE__ */ jsx(Text3, { bold: true, dimColor: true, children: line.text }, index) : /* @__PURE__ */ jsxs(Box, { children: [
|
|
2442
|
+
/* @__PURE__ */ jsx(Text3, { color: line.row.color, bold: line.row.bold, children: line.row.cell.padEnd(line.cellWidth) }),
|
|
2443
|
+
/* @__PURE__ */ jsx(Text3, { wrap: "truncate-end", children: line.row.label })
|
|
2391
2444
|
] }, index)
|
|
2392
2445
|
)
|
|
2393
2446
|
] });
|
|
@@ -2508,8 +2561,8 @@ var HelpModal = ({
|
|
|
2508
2561
|
width: contentWidth + MODAL_CHROME_COLS,
|
|
2509
2562
|
children: [
|
|
2510
2563
|
/* @__PURE__ */ jsxs(Box, { children: [
|
|
2511
|
-
/* @__PURE__ */ jsx(
|
|
2512
|
-
scrollable ? /* @__PURE__ */ jsx(
|
|
2564
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.info, bold: true, children: "Legend" }),
|
|
2565
|
+
scrollable ? /* @__PURE__ */ jsx(Text3, { dimColor: true, children: ` ${offset + 1}\u2013${offset + shown} of ${totalRows}` }) : null
|
|
2513
2566
|
] }),
|
|
2514
2567
|
/* @__PURE__ */ jsx(Box, { marginTop: 1, width: contentWidth, children: groups.map((group, index) => /* @__PURE__ */ jsx(
|
|
2515
2568
|
LegendGroup,
|
|
@@ -2521,8 +2574,8 @@ var HelpModal = ({
|
|
|
2521
2574
|
},
|
|
2522
2575
|
group[0]?.title ?? index
|
|
2523
2576
|
)) }),
|
|
2524
|
-
tabHelp && !scrollable ? /* @__PURE__ */ jsx(
|
|
2525
|
-
/* @__PURE__ */ jsx(
|
|
2577
|
+
tabHelp && !scrollable ? /* @__PURE__ */ jsx(Text3, { dimColor: true, children: LEGEND_FOOTNOTE }) : null,
|
|
2578
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: scrollable ? "\u2191\u2193 scroll \xB7 esc \xB7 ? close" : "esc \xB7 ? close" })
|
|
2526
2579
|
]
|
|
2527
2580
|
}
|
|
2528
2581
|
);
|
|
@@ -2537,13 +2590,13 @@ var ExplainModal = ({ item, login }) => /* @__PURE__ */ jsxs(
|
|
|
2537
2590
|
paddingX: 1,
|
|
2538
2591
|
width: Math.min(COLS, 78),
|
|
2539
2592
|
children: [
|
|
2540
|
-
/* @__PURE__ */ jsx(
|
|
2541
|
-
/* @__PURE__ */ jsx(
|
|
2593
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.accent, bold: true, children: `#${item.number} \xB7 ${item.repo}` }),
|
|
2594
|
+
/* @__PURE__ */ jsx(Text3, { children: item.title }),
|
|
2542
2595
|
explainItem(item, login).map((section) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
2543
|
-
/* @__PURE__ */ jsx(
|
|
2544
|
-
section.lines.map((line, i) => /* @__PURE__ */ jsx(
|
|
2596
|
+
/* @__PURE__ */ jsx(Text3, { bold: true, dimColor: true, children: section.heading }),
|
|
2597
|
+
section.lines.map((line, i) => /* @__PURE__ */ jsx(Text3, { children: " " + line }, i))
|
|
2545
2598
|
] }, section.heading)),
|
|
2546
|
-
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(
|
|
2599
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text3, { dimColor: true, children: "esc \xB7 e close" }) })
|
|
2547
2600
|
]
|
|
2548
2601
|
}
|
|
2549
2602
|
);
|
|
@@ -2569,21 +2622,21 @@ var RepoPicker = ({
|
|
|
2569
2622
|
paddingX: 1,
|
|
2570
2623
|
minWidth: 42,
|
|
2571
2624
|
children: [
|
|
2572
|
-
/* @__PURE__ */ jsx(
|
|
2573
|
-
/* @__PURE__ */ jsx(
|
|
2625
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.info, bold: true, children: `Filter by repo (${selected.size} on)` }),
|
|
2626
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: "\u2500".repeat(36) }),
|
|
2574
2627
|
visible.map((repo, i) => {
|
|
2575
2628
|
const idx = start + i;
|
|
2576
2629
|
const on = selected.has(repo);
|
|
2577
2630
|
const active = idx === cursor;
|
|
2578
2631
|
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
2579
|
-
/* @__PURE__ */ jsx(
|
|
2580
|
-
/* @__PURE__ */ jsx(
|
|
2581
|
-
/* @__PURE__ */ jsx(
|
|
2632
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.info, children: active ? "\u276F " : " " }),
|
|
2633
|
+
/* @__PURE__ */ jsx(Text3, { color: on ? "green" : void 0, children: on ? "\u25C9 " : "\u25CB " }),
|
|
2634
|
+
/* @__PURE__ */ jsx(Text3, { bold: active, children: repo })
|
|
2582
2635
|
] }, repo);
|
|
2583
2636
|
}),
|
|
2584
|
-
repos.length > budget ? /* @__PURE__ */ jsx(
|
|
2585
|
-
/* @__PURE__ */ jsx(
|
|
2586
|
-
/* @__PURE__ */ jsx(
|
|
2637
|
+
repos.length > budget ? /* @__PURE__ */ jsx(Text3, { dimColor: true, children: ` \u2026 ${repos.length} repos total` }) : null,
|
|
2638
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: "\u2500".repeat(36) }),
|
|
2639
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: "space toggle \xB7 a clear all \xB7 \u21B5/esc done" })
|
|
2587
2640
|
]
|
|
2588
2641
|
}
|
|
2589
2642
|
);
|
|
@@ -3287,11 +3340,11 @@ var BrowseScreen = ({
|
|
|
3287
3340
|
const query = palette.trim();
|
|
3288
3341
|
const ticketKey = jiraKeyRe ? query.toUpperCase().match(jiraKeyRe)?.[0] : void 0;
|
|
3289
3342
|
const commands = [];
|
|
3290
|
-
const rich = (key, where) => /* @__PURE__ */ jsxs(
|
|
3343
|
+
const rich = (key, where) => /* @__PURE__ */ jsxs(Text3, { children: [
|
|
3291
3344
|
"Open ",
|
|
3292
|
-
/* @__PURE__ */ jsx(
|
|
3345
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.accent, children: key }),
|
|
3293
3346
|
" ",
|
|
3294
|
-
/* @__PURE__ */ jsx(
|
|
3347
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.info, children: where })
|
|
3295
3348
|
] });
|
|
3296
3349
|
const labels = /* @__PURE__ */ new Map();
|
|
3297
3350
|
if (ticketKey && jiraBase) {
|
|
@@ -3423,8 +3476,8 @@ var BrowseScreen = ({
|
|
|
3423
3476
|
}
|
|
3424
3477
|
) : null,
|
|
3425
3478
|
skippedForBudget ? /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
3426
|
-
/* @__PURE__ */ jsx(
|
|
3427
|
-
/* @__PURE__ */ jsx(
|
|
3479
|
+
/* @__PURE__ */ jsx(Text3, { bold: true, color: colors.accent, children: " \u26A1 auto-refresh paused to save API budget" }),
|
|
3480
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: " r refreshes anyway" })
|
|
3428
3481
|
] }) : null,
|
|
3429
3482
|
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(
|
|
3430
3483
|
Tabs,
|
|
@@ -3460,14 +3513,14 @@ var BrowseScreen = ({
|
|
|
3460
3513
|
}
|
|
3461
3514
|
) }),
|
|
3462
3515
|
search != null ? /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
3463
|
-
/* @__PURE__ */ jsx(
|
|
3464
|
-
/* @__PURE__ */ jsx(
|
|
3465
|
-
searchInput ? /* @__PURE__ */ jsx(
|
|
3466
|
-
/* @__PURE__ */ jsx(
|
|
3516
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.info, children: " / " }),
|
|
3517
|
+
/* @__PURE__ */ jsx(Text3, { children: search }),
|
|
3518
|
+
searchInput ? /* @__PURE__ */ jsx(Text3, { color: colors.info, children: "\u258F" }) : null,
|
|
3519
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: ` ${matchCount} match${matchCount !== 1 ? "es" : ""}${searchInput ? " \u21B5 accept \xB7 esc clear" : " esc clear"}` })
|
|
3467
3520
|
] }) : repoFilter.size > 0 ? /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
3468
|
-
/* @__PURE__ */ jsx(
|
|
3469
|
-
/* @__PURE__ */ jsx(
|
|
3470
|
-
/* @__PURE__ */ jsx(
|
|
3521
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.accent, children: " \u25C9 " }),
|
|
3522
|
+
/* @__PURE__ */ jsx(Text3, { children: `${repoFilter.size} repo${repoFilter.size !== 1 ? "s" : ""}` }),
|
|
3523
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: " f edit \xB7 esc clear" })
|
|
3471
3524
|
] }) : null,
|
|
3472
3525
|
/* @__PURE__ */ jsxs(Box, { children: [
|
|
3473
3526
|
/* @__PURE__ */ jsxs(
|
|
@@ -3505,7 +3558,7 @@ var BrowseScreen = ({
|
|
|
3505
3558
|
},
|
|
3506
3559
|
`${viewStart + i}:${rowKey(item)}`
|
|
3507
3560
|
)) }),
|
|
3508
|
-
hasMore && /* @__PURE__ */ jsxs(
|
|
3561
|
+
hasMore && /* @__PURE__ */ jsxs(Text3, { dimColor: true, children: [
|
|
3509
3562
|
" ",
|
|
3510
3563
|
"\u2193 ",
|
|
3511
3564
|
section.items.length - viewStart - visibleCount,
|
|
@@ -3539,7 +3592,7 @@ var BrowseScreen = ({
|
|
|
3539
3592
|
}
|
|
3540
3593
|
) : null
|
|
3541
3594
|
] }),
|
|
3542
|
-
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: flash ? /* @__PURE__ */ jsx(
|
|
3595
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: flash ? /* @__PURE__ */ jsx(Text3, { color: colors.success, children: flash }) : /* @__PURE__ */ jsx(FooterHints, { hints }) })
|
|
3543
3596
|
]
|
|
3544
3597
|
}
|
|
3545
3598
|
);
|
|
@@ -3554,7 +3607,7 @@ var NoRowsScreen = ({
|
|
|
3554
3607
|
});
|
|
3555
3608
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
3556
3609
|
/* @__PURE__ */ jsx(StatusMessage, { variant: reason === "empty" ? "info" : "error", children: reason === "empty" ? "Nothing open." : `Fetch failed \u2014 ${detail ?? "no reason reported"}` }),
|
|
3557
|
-
reason === "empty" && detail ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(
|
|
3610
|
+
reason === "empty" && detail ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text3, { dimColor: true, children: detail }) }) : null,
|
|
3558
3611
|
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(
|
|
3559
3612
|
FooterHints,
|
|
3560
3613
|
{
|
|
@@ -3722,10 +3775,13 @@ var App = ({
|
|
|
3722
3775
|
const running = [...heldSince].filter(([tab]) => held.has(tab));
|
|
3723
3776
|
if (running.length === 0) return;
|
|
3724
3777
|
const remaining = (at) => at + TRANSIT_HOLD_MS - Date.now();
|
|
3725
|
-
const timer = setTimeout(
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3778
|
+
const timer = setTimeout(
|
|
3779
|
+
() => {
|
|
3780
|
+
for (const [tab, at] of running)
|
|
3781
|
+
if (remaining(at) <= 0) settleTab(tab, transients);
|
|
3782
|
+
},
|
|
3783
|
+
Math.max(0, Math.min(...running.map(([, at]) => remaining(at))))
|
|
3784
|
+
);
|
|
3729
3785
|
return () => clearTimeout(timer);
|
|
3730
3786
|
}, [transients, heldSince, state.phase]);
|
|
3731
3787
|
const pendingSummary = useMemo(
|
|
@@ -4084,4 +4140,4 @@ var matchesFilter = (repo, filter) => {
|
|
|
4084
4140
|
};
|
|
4085
4141
|
var parsePatterns = (value) => value.split(",").map((p) => p.trim()).filter(Boolean);
|
|
4086
4142
|
|
|
4087
|
-
export { ActionMenu, App, COLS, CiStatusLine, CommentsPanel, HealthPanel, MIN_SIDEBAR_COLS, SIDEBAR_COLS, SidePanel, StatusStripLine, ageLabel, budgetNotice, buildActions, buildCheckoutCmd, clipboard, counts, drillCmd, explainGhAction, explainItem, fitCount, gapsAbove, healthColor, healthDisplay, healthGlyph, healthLegend, itermRun, jumpToRepo, jumpToRepoPane, matchesFilter, maxViewStart, moveCursor, openInTab, parsePatterns, railCapacity, railHeights, railRowsOf, railWidth, railsOf, readCache, renderMarkdown, reposInSections, resolveRepoPath, runHere, runInPane, runInPaneHorizontal, sameCiStatusState, signatureOf, stripGlyph, stripLayout, stripSignature, toCiStatusState, truncate, useActionMenu, windowCount, withHeaders, withoutItem, workCount, writeCache };
|
|
4143
|
+
export { ActionMenu, App, COLS, CiStatusLine, CommentsPanel, HealthPanel, MIN_SIDEBAR_COLS, PrRow, SIDEBAR_COLS, SidePanel, StatusStripLine, ageLabel, budgetNotice, buildActions, buildCheckoutCmd, clipboard, counts, drillCmd, explainGhAction, explainItem, fitCount, gapsAbove, healthColor, healthDisplay, healthGlyph, healthLegend, itermRun, jumpToRepo, jumpToRepoPane, matchesFilter, maxViewStart, moveCursor, openInTab, parsePatterns, railCapacity, railHeights, railRowsOf, railWidth, railsOf, readCache, renderMarkdown, reposInSections, resolveRepoPath, runHere, runInPane, runInPaneHorizontal, sameCiStatusState, signatureOf, stripGlyph, stripLayout, stripSignature, toCiStatusState, 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.
|
|
3
|
+
"version": "0.61.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",
|