@kud/gh-ink 0.13.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 CHANGED
@@ -76,12 +76,12 @@ type GHItem = {
76
76
  detail?: GHDetail;
77
77
  indent: boolean;
78
78
  };
79
- type JiraRow = {
80
- kind: "jira";
79
+ type TaskRow = {
80
+ kind: "task";
81
81
  key: string;
82
82
  summary: string;
83
83
  url: string;
84
- jiraStatus: string;
84
+ status: string;
85
85
  age: string;
86
86
  indent: boolean;
87
87
  instanceKey?: string;
@@ -92,6 +92,19 @@ type JiraRow = {
92
92
  * separately instead of being smuggled past the truncation maths.
93
93
  */
94
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;
95
108
  };
96
109
  type RepoHeader = {
97
110
  kind: "repo-header";
@@ -115,7 +128,7 @@ type SubgroupHeader = {
115
128
  age: string;
116
129
  indent: boolean;
117
130
  };
118
- type AnyItem = GHItem | JiraRow | RepoHeader | SubgroupHeader | ShowMore | ShowLess;
131
+ type AnyItem = GHItem | TaskRow | RepoHeader | SubgroupHeader | ShowMore | ShowLess;
119
132
  type CiStatus = {
120
133
  job: string;
121
134
  buildNumber: number;
@@ -275,4 +288,4 @@ declare const writeCache: (key: string, data: {
275
288
  login: string;
276
289
  }) => void;
277
290
 
278
- 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 JiraRow, type JiraTransition, type RepoHeader, type Section, type ShowLess, type ShowMore, type SubgroupHeader, 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 };
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 === "jira") {
644
+ if (item.kind === "task") {
645
645
  const row = item;
646
- return row.url || `jira:${row.key}`;
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 === "jira") {
662
+ if (item.kind === "task") {
663
663
  const j = item;
664
- return [j.summary, j.jiraStatus].join("|");
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 === "jira" ? `${i.summary} ${i.key}` : "";
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 === "jira") return `jira issue view ${item.key}`;
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 === "jira") return "View ticket";
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 === "jira" ? item.key : `#${item.number}`;
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 === "jira") {
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.key} ${state} --resolution ${resolution}`.then(() => {
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.key} ${state}`.then(() => {
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,7 +1605,7 @@ 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 === "jira") {
1608
+ if (item.kind === "task") {
1608
1609
  const note = item.note ?? "";
1609
1610
  const titleMax2 = Math.max(20, COLS - item.key.length - note.length - 10);
1610
1611
  return /* @__PURE__ */ jsxs(Box, { marginTop: gap ? 1 : 0, children: [
@@ -1689,7 +1690,7 @@ var ActionMenu = ({
1689
1690
  actions,
1690
1691
  cursor
1691
1692
  }) => {
1692
- const title = item.kind === "jira" ? item.key : item.kind === "pr" || item.kind === "issue" ? `#${item.number}` : "";
1693
+ const title = item.kind === "task" ? item.key : item.kind === "pr" || item.kind === "issue" ? `#${item.number}` : "";
1693
1694
  return /* @__PURE__ */ jsxs(
1694
1695
  Box,
1695
1696
  {
@@ -2222,6 +2223,12 @@ var BrowseScreen = ({
2222
2223
  return;
2223
2224
  if (key.return) {
2224
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
+ }
2225
2232
  openMenu();
2226
2233
  return;
2227
2234
  }
@@ -2236,13 +2243,13 @@ var BrowseScreen = ({
2236
2243
  if (input === "o") {
2237
2244
  quietly`open ${activeItem.url}`.catch(() => {
2238
2245
  });
2239
- const label = activeItem.kind === "jira" ? activeItem.key : `#${activeItem.number}`;
2246
+ const label = activeItem.kind === "task" ? activeItem.key : `#${activeItem.number}`;
2240
2247
  showFlash(`\u2197 Opened ${label}`);
2241
2248
  return;
2242
2249
  }
2243
2250
  if (input === "c") {
2244
2251
  clipboard(activeItem.url);
2245
- const label = activeItem.kind === "jira" ? activeItem.key : `#${activeItem.number}`;
2252
+ const label = activeItem.kind === "task" ? activeItem.key : `#${activeItem.number}`;
2246
2253
  showFlash(`\u2713 Copied URL for ${label}`);
2247
2254
  return;
2248
2255
  }
@@ -2261,7 +2268,7 @@ var BrowseScreen = ({
2261
2268
  showFlash(`\u2713 Copied ${activeItem.branch}`);
2262
2269
  return;
2263
2270
  }
2264
- if (activeItem.kind !== "jira") {
2271
+ if (activeItem.kind !== "task") {
2265
2272
  if (input === "s" && activeItem.kind === "pr" && activeItem.branch) {
2266
2273
  const script = [
2267
2274
  "delay 0.5",
@@ -2286,8 +2293,8 @@ var BrowseScreen = ({
2286
2293
  return;
2287
2294
  }
2288
2295
  }
2289
- if (input === "t" && activeItem && activeItem.kind === "jira" && jiraTransitions && jiraTransitions.length > 0) {
2290
- const jiraKey = activeItem.key;
2296
+ if (input === "t" && activeItem && activeItem.kind === "task" && activeItem.ticket && jiraTransitions && jiraTransitions.length > 0) {
2297
+ const jiraKey = activeItem.ticket;
2291
2298
  const actions = jiraTransitions.map(
2292
2299
  ({ label, state, resolutions }) => resolutions && resolutions.length > 0 ? {
2293
2300
  label,
@@ -2414,16 +2421,16 @@ var BrowseScreen = ({
2414
2421
  // the whole panel up a line instead of clipping.
2415
2422
  i > 0 && (item.kind === "repo-header" || item.kind === "subgroup-header" || // A header is always followed by a blank line before its
2416
2423
  // first child — in Other PRs that's "free" because the
2417
- // child is itself a repo-header (gap above). A jira row
2424
+ // child is itself a repo-header (gap above). A task row
2418
2425
  // has no such stand-in, so it needs this explicitly. Never
2419
2426
  // applies between two tickets/PRs — only right after a
2420
2427
  // header.
2421
- item.kind === "jira" && ["repo-header", "subgroup-header"].includes(
2428
+ item.kind === "task" && ["repo-header", "subgroup-header"].includes(
2422
2429
  section.items[viewStart + i - 1]?.kind
2423
2430
  ))
2424
2431
  )
2425
2432
  },
2426
- `${viewStart + i}:${item.kind === "jira" ? 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}`}`
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}`}`
2427
2434
  )) }),
2428
2435
  hasMore && /* @__PURE__ */ jsxs(Text2, { dimColor: true, children: [
2429
2436
  " ",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kud/gh-ink",
3
- "version": "0.13.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",