@kud/gh-ink 0.12.0 → 0.14.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 +25 -5
- package/dist/index.js +33 -24
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -76,15 +76,35 @@ type GHItem = {
|
|
|
76
76
|
detail?: GHDetail;
|
|
77
77
|
indent: boolean;
|
|
78
78
|
};
|
|
79
|
-
type
|
|
80
|
-
kind: "
|
|
79
|
+
type TaskRow = {
|
|
80
|
+
kind: "task";
|
|
81
81
|
key: string;
|
|
82
82
|
summary: string;
|
|
83
83
|
url: string;
|
|
84
|
-
|
|
84
|
+
status: string;
|
|
85
85
|
age: string;
|
|
86
86
|
indent: boolean;
|
|
87
87
|
instanceKey?: string;
|
|
88
|
+
/**
|
|
89
|
+
* Trailing annotation, rendered dim after the summary — a recurrence marker,
|
|
90
|
+
* a source hint, anything secondary to the title. Its own node rather than
|
|
91
|
+
* part of `summary` so it can be dimmed, and so its width is measured
|
|
92
|
+
* separately instead of being smuggled past the truncation maths.
|
|
93
|
+
*/
|
|
94
|
+
note?: string;
|
|
95
|
+
/**
|
|
96
|
+
* The Jira issue key behind this row, when one exists. Its PRESENCE is what
|
|
97
|
+
* turns on the ticket affordances — ↵ opens a menu led by `jira issue view`,
|
|
98
|
+
* and `t` transitions the issue. A row without it is just a task: ↵ opens its
|
|
99
|
+
* URL and nothing here shells out to `jira`.
|
|
100
|
+
*
|
|
101
|
+
* Separate from `key` because the two are not the same thing. `key` is the
|
|
102
|
+
* left column, and a caller is free to put anything legible there: cockpit
|
|
103
|
+
* puts the ticket key, `life` puts a Todoist project name. Reading the drill
|
|
104
|
+
* off `key` is what made `life` run `jira issue view "Maison "` and
|
|
105
|
+
* label it "View ticket" on a surface that has never touched Jira.
|
|
106
|
+
*/
|
|
107
|
+
ticket?: string;
|
|
88
108
|
};
|
|
89
109
|
type RepoHeader = {
|
|
90
110
|
kind: "repo-header";
|
|
@@ -108,7 +128,7 @@ type SubgroupHeader = {
|
|
|
108
128
|
age: string;
|
|
109
129
|
indent: boolean;
|
|
110
130
|
};
|
|
111
|
-
type AnyItem = GHItem |
|
|
131
|
+
type AnyItem = GHItem | TaskRow | RepoHeader | SubgroupHeader | ShowMore | ShowLess;
|
|
112
132
|
type CiStatus = {
|
|
113
133
|
job: string;
|
|
114
134
|
buildNumber: number;
|
|
@@ -268,4 +288,4 @@ declare const writeCache: (key: string, data: {
|
|
|
268
288
|
login: string;
|
|
269
289
|
}) => void;
|
|
270
290
|
|
|
271
|
-
export { type Action, ActionMenu, type AnyItem, App, COLS, type CiStatus, CiStatusLine, type CiStatusState, CommentsPanel, type CommentsPanelProps, type DetailContext, type ExplainSection, type ExtensionTarget, type GHDetail, type GHItem, HealthPanel, type HealthPanelProps, type InboxExtension, type
|
|
291
|
+
export { type Action, ActionMenu, type AnyItem, App, COLS, type CiStatus, CiStatusLine, type CiStatusState, CommentsPanel, type CommentsPanelProps, type DetailContext, type ExplainSection, type ExtensionTarget, type GHDetail, type GHItem, HealthPanel, type HealthPanelProps, type InboxExtension, type JiraTransition, type RepoHeader, type Section, type ShowLess, type ShowMore, type SubgroupHeader, type TaskRow, buildActions, buildCheckoutCmd, clipboard, drillCmd, explainItem, filterByOrigin, filterByRepos, filterBySearch, fitCount, healthColor, healthDisplay, healthGlyph, healthLegend, insertRepoHeaders, itermRun, jumpToRepo, jumpToRepoPane, layoutGHItems, maxViewStart, moveCursor, openInTab, readCache, relativeTime, renderMarkdown, repoPriority, reposInSections, resolveRepoPath, runHere, runInPane, runInPaneHorizontal, sameCiStatusState, sortByRecency, sortItems, toCiStatusState, topLevelCount, truncate, useActionMenu, windowCount, withHeaders, withoutItem, writeCache };
|
package/dist/index.js
CHANGED
|
@@ -641,9 +641,9 @@ var invalidateCache = (key) => {
|
|
|
641
641
|
// src/inbox/diff.ts
|
|
642
642
|
var keyOf = (item) => {
|
|
643
643
|
if (item.kind === "pr" || item.kind === "issue") return item.url;
|
|
644
|
-
if (item.kind === "
|
|
644
|
+
if (item.kind === "task") {
|
|
645
645
|
const row = item;
|
|
646
|
-
return row.url || `
|
|
646
|
+
return row.url || `task:${row.key}`;
|
|
647
647
|
}
|
|
648
648
|
return null;
|
|
649
649
|
};
|
|
@@ -659,9 +659,9 @@ var renderedState = (item) => {
|
|
|
659
659
|
i.author ?? ""
|
|
660
660
|
].join("|");
|
|
661
661
|
}
|
|
662
|
-
if (item.kind === "
|
|
662
|
+
if (item.kind === "task") {
|
|
663
663
|
const j = item;
|
|
664
|
-
return [j.summary, j.
|
|
664
|
+
return [j.summary, j.status].join("|");
|
|
665
665
|
}
|
|
666
666
|
return "";
|
|
667
667
|
};
|
|
@@ -881,7 +881,7 @@ var filterByOrigin = (sections, keep, isWorkRepo) => sections.map((s) => {
|
|
|
881
881
|
(i) => i.kind !== "repo-header" && i.kind !== "subgroup-header"
|
|
882
882
|
)
|
|
883
883
|
);
|
|
884
|
-
var searchText = (i) => i.kind === "pr" || i.kind === "issue" ? `${i.title} ${i.repo} #${i.number}` : i.kind === "
|
|
884
|
+
var searchText = (i) => i.kind === "pr" || i.kind === "issue" ? `${i.title} ${i.repo} #${i.number}` : i.kind === "task" ? `${i.summary} ${i.key}` : "";
|
|
885
885
|
var filterBySearch = (sections, query) => {
|
|
886
886
|
const q = query.trim().toLowerCase();
|
|
887
887
|
if (!q) return sections;
|
|
@@ -1202,11 +1202,12 @@ var topLevelCount = (s) => s.items.filter(
|
|
|
1202
1202
|
(i) => i.kind !== "repo-header" && i.kind !== "subgroup-header" && !i.indent
|
|
1203
1203
|
).length;
|
|
1204
1204
|
var drillCmd = (item) => {
|
|
1205
|
-
if (item.kind === "
|
|
1205
|
+
if (item.kind === "task")
|
|
1206
|
+
return item.ticket ? `jira issue view ${item.ticket}` : null;
|
|
1206
1207
|
return null;
|
|
1207
1208
|
};
|
|
1208
1209
|
var drillLabel = (item) => {
|
|
1209
|
-
if (item.kind === "
|
|
1210
|
+
if (item.kind === "task") return "View ticket";
|
|
1210
1211
|
if (item.kind === "issue") return "View issue";
|
|
1211
1212
|
if (item.kind === "pr") return "Open PR";
|
|
1212
1213
|
return "Drill in";
|
|
@@ -1228,7 +1229,7 @@ var buildActions = (item, login, showFlash, jiraBase, jiraKeyRe, jiraTransitions
|
|
|
1228
1229
|
hint: "c",
|
|
1229
1230
|
run: () => {
|
|
1230
1231
|
clipboard(item.url);
|
|
1231
|
-
const label = item.kind === "
|
|
1232
|
+
const label = item.kind === "task" ? item.key : `#${item.number}`;
|
|
1232
1233
|
showFlash(`\u2713 Copied URL for ${label}`);
|
|
1233
1234
|
}
|
|
1234
1235
|
};
|
|
@@ -1246,9 +1247,9 @@ var buildActions = (item, login, showFlash, jiraBase, jiraKeyRe, jiraTransitions
|
|
|
1246
1247
|
}
|
|
1247
1248
|
}
|
|
1248
1249
|
} : null;
|
|
1249
|
-
if (item.kind === "
|
|
1250
|
+
if (item.kind === "task") {
|
|
1250
1251
|
const base = drillAction ? [drillAction, open, copyUrl] : [open, copyUrl];
|
|
1251
|
-
if (jiraTransitions && jiraTransitions.length > 0) {
|
|
1252
|
+
if (item.ticket && jiraTransitions && jiraTransitions.length > 0) {
|
|
1252
1253
|
base.push({
|
|
1253
1254
|
label: "Move status",
|
|
1254
1255
|
hint: "t",
|
|
@@ -1265,7 +1266,7 @@ var buildActions = (item, login, showFlash, jiraBase, jiraKeyRe, jiraTransitions
|
|
|
1265
1266
|
hint: "",
|
|
1266
1267
|
run: () => {
|
|
1267
1268
|
showFlash(`\u22EF ${label} \xB7 ${resolution}\u2026`);
|
|
1268
|
-
void quietly`jira issue move ${item.
|
|
1269
|
+
void quietly`jira issue move ${item.ticket} ${state} --resolution ${resolution}`.then(() => {
|
|
1269
1270
|
showFlash(`\u2713 ${label} \xB7 ${resolution}`);
|
|
1270
1271
|
ext?.onActed?.();
|
|
1271
1272
|
}).catch(() => showFlash(`\u2717 Move to ${label} failed`));
|
|
@@ -1276,7 +1277,7 @@ var buildActions = (item, login, showFlash, jiraBase, jiraKeyRe, jiraTransitions
|
|
|
1276
1277
|
hint: "",
|
|
1277
1278
|
run: () => {
|
|
1278
1279
|
showFlash(`\u22EF Moving to ${label}\u2026`);
|
|
1279
|
-
void quietly`jira issue move ${item.
|
|
1280
|
+
void quietly`jira issue move ${item.ticket} ${state}`.then(() => {
|
|
1280
1281
|
showFlash(`\u2713 Moved to ${label}`);
|
|
1281
1282
|
ext?.onActed?.();
|
|
1282
1283
|
}).catch(() => showFlash(`\u2717 Move to ${label} failed`));
|
|
@@ -1604,12 +1605,14 @@ var ItemRow = ({
|
|
|
1604
1605
|
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: active ? "\u21B5 " : " " }),
|
|
1605
1606
|
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: "show less" })
|
|
1606
1607
|
] });
|
|
1607
|
-
if (item.kind === "
|
|
1608
|
-
const
|
|
1608
|
+
if (item.kind === "task") {
|
|
1609
|
+
const note = item.note ?? "";
|
|
1610
|
+
const titleMax2 = Math.max(20, COLS - item.key.length - note.length - 10);
|
|
1609
1611
|
return /* @__PURE__ */ jsxs(Box, { marginTop: gap ? 1 : 0, children: [
|
|
1610
1612
|
/* @__PURE__ */ jsx(Text2, { color: "cyan", children: active ? "\u276F " : " " }),
|
|
1611
1613
|
/* @__PURE__ */ jsx(Text2, { color: "#FF8700", bold: active, children: item.key + " " }),
|
|
1612
|
-
/* @__PURE__ */ jsx(Text2, { bold: active, children: truncate(item.summary, titleMax2) })
|
|
1614
|
+
/* @__PURE__ */ jsx(Text2, { bold: active, children: truncate(item.summary, titleMax2) }),
|
|
1615
|
+
note ? /* @__PURE__ */ jsx(Text2, { dimColor: true, children: ` ${note}` }) : null
|
|
1613
1616
|
] });
|
|
1614
1617
|
}
|
|
1615
1618
|
const { glyph: healthIcon, color: healthColor2 } = healthDisplay[item.health];
|
|
@@ -1687,7 +1690,7 @@ var ActionMenu = ({
|
|
|
1687
1690
|
actions,
|
|
1688
1691
|
cursor
|
|
1689
1692
|
}) => {
|
|
1690
|
-
const title = item.kind === "
|
|
1693
|
+
const title = item.kind === "task" ? item.key : item.kind === "pr" || item.kind === "issue" ? `#${item.number}` : "";
|
|
1691
1694
|
return /* @__PURE__ */ jsxs(
|
|
1692
1695
|
Box,
|
|
1693
1696
|
{
|
|
@@ -2220,6 +2223,12 @@ var BrowseScreen = ({
|
|
|
2220
2223
|
return;
|
|
2221
2224
|
if (key.return) {
|
|
2222
2225
|
if (openDrillView(activeItem)) return;
|
|
2226
|
+
if (activeItem.kind === "task" && !activeItem.ticket) {
|
|
2227
|
+
void quietly`open ${activeItem.url}`.catch(() => {
|
|
2228
|
+
});
|
|
2229
|
+
showFlash("\u2197 Opened in browser");
|
|
2230
|
+
return;
|
|
2231
|
+
}
|
|
2223
2232
|
openMenu();
|
|
2224
2233
|
return;
|
|
2225
2234
|
}
|
|
@@ -2234,13 +2243,13 @@ var BrowseScreen = ({
|
|
|
2234
2243
|
if (input === "o") {
|
|
2235
2244
|
quietly`open ${activeItem.url}`.catch(() => {
|
|
2236
2245
|
});
|
|
2237
|
-
const label = activeItem.kind === "
|
|
2246
|
+
const label = activeItem.kind === "task" ? activeItem.key : `#${activeItem.number}`;
|
|
2238
2247
|
showFlash(`\u2197 Opened ${label}`);
|
|
2239
2248
|
return;
|
|
2240
2249
|
}
|
|
2241
2250
|
if (input === "c") {
|
|
2242
2251
|
clipboard(activeItem.url);
|
|
2243
|
-
const label = activeItem.kind === "
|
|
2252
|
+
const label = activeItem.kind === "task" ? activeItem.key : `#${activeItem.number}`;
|
|
2244
2253
|
showFlash(`\u2713 Copied URL for ${label}`);
|
|
2245
2254
|
return;
|
|
2246
2255
|
}
|
|
@@ -2259,7 +2268,7 @@ var BrowseScreen = ({
|
|
|
2259
2268
|
showFlash(`\u2713 Copied ${activeItem.branch}`);
|
|
2260
2269
|
return;
|
|
2261
2270
|
}
|
|
2262
|
-
if (activeItem.kind !== "
|
|
2271
|
+
if (activeItem.kind !== "task") {
|
|
2263
2272
|
if (input === "s" && activeItem.kind === "pr" && activeItem.branch) {
|
|
2264
2273
|
const script = [
|
|
2265
2274
|
"delay 0.5",
|
|
@@ -2284,8 +2293,8 @@ var BrowseScreen = ({
|
|
|
2284
2293
|
return;
|
|
2285
2294
|
}
|
|
2286
2295
|
}
|
|
2287
|
-
if (input === "t" && activeItem && activeItem.kind === "
|
|
2288
|
-
const jiraKey = activeItem.
|
|
2296
|
+
if (input === "t" && activeItem && activeItem.kind === "task" && activeItem.ticket && jiraTransitions && jiraTransitions.length > 0) {
|
|
2297
|
+
const jiraKey = activeItem.ticket;
|
|
2289
2298
|
const actions = jiraTransitions.map(
|
|
2290
2299
|
({ label, state, resolutions }) => resolutions && resolutions.length > 0 ? {
|
|
2291
2300
|
label,
|
|
@@ -2412,16 +2421,16 @@ var BrowseScreen = ({
|
|
|
2412
2421
|
// the whole panel up a line instead of clipping.
|
|
2413
2422
|
i > 0 && (item.kind === "repo-header" || item.kind === "subgroup-header" || // A header is always followed by a blank line before its
|
|
2414
2423
|
// first child — in Other PRs that's "free" because the
|
|
2415
|
-
// child is itself a repo-header (gap above). A
|
|
2424
|
+
// child is itself a repo-header (gap above). A task row
|
|
2416
2425
|
// has no such stand-in, so it needs this explicitly. Never
|
|
2417
2426
|
// applies between two tickets/PRs — only right after a
|
|
2418
2427
|
// header.
|
|
2419
|
-
item.kind === "
|
|
2428
|
+
item.kind === "task" && ["repo-header", "subgroup-header"].includes(
|
|
2420
2429
|
section.items[viewStart + i - 1]?.kind
|
|
2421
2430
|
))
|
|
2422
2431
|
)
|
|
2423
2432
|
},
|
|
2424
|
-
`${viewStart + i}:${item.kind === "
|
|
2433
|
+
`${viewStart + i}:${item.kind === "task" ? item.instanceKey ?? item.key : item.kind === "repo-header" ? `header:${item.repo}` : item.kind === "subgroup-header" ? `subgroup:${item.label}` : item.kind === "show-more" ? `show-more:${item.hidden[0]?.repo ?? i}` : item.kind === "show-less" ? `show-less:${item.toHide[0]?.repo ?? i}` : `${item.repo}/${item.number}`}`
|
|
2425
2434
|
)) }),
|
|
2426
2435
|
hasMore && /* @__PURE__ */ jsxs(Text2, { dimColor: true, children: [
|
|
2427
2436
|
" ",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kud/gh-ink",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.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",
|