clairo 3.1.3 → 3.1.4

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.
Files changed (3) hide show
  1. package/README.md +1 -0
  2. package/dist/cli.js +109 -98
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -33,6 +33,7 @@ an opinionated dashboard tui for github PRs, jira tickets, and daily logs.
33
33
 
34
34
  - Node.js 18+
35
35
  - [GitHub CLI](https://cli.github.com/) (`gh`) installed and authenticated
36
+ - A [Nerd Font](https://www.nerdfonts.com/) is highly recommended for proper icon rendering
36
37
 
37
38
  ## usage
38
39
 
package/dist/cli.js CHANGED
@@ -216,11 +216,11 @@ function resolveReviewDisplay(reviewDecision) {
216
216
  }
217
217
  function resolveMergeDisplay(pr) {
218
218
  if (!pr) return { text: "Unknown", color: "yellow" };
219
- if (pr.state === "MERGED") return { text: "Merged", color: "magenta" };
220
- if (pr.state === "CLOSED") return { text: "Closed", color: "red" };
221
- if (pr.isDraft) return { text: "Draft", color: "yellow" };
222
- if (pr.mergeable === "MERGEABLE") return { text: "Open", color: "green" };
223
- if (pr.mergeable === "CONFLICTING") return { text: "Conflicts", color: "red" };
219
+ if (pr.state === "MERGED") return { text: "\uE727 Merged", color: "magenta" };
220
+ if (pr.state === "CLOSED") return { text: "\uE726 Closed", color: "red" };
221
+ if (pr.isDraft) return { text: "\uE726 Draft", color: "yellow" };
222
+ if (pr.mergeable === "MERGEABLE") return { text: "\uE726 Open", color: "green" };
223
+ if (pr.mergeable === "CONFLICTING") return { text: "\uE726 Conflicts", color: "red" };
224
224
  return { text: "Unknown", color: "yellow" };
225
225
  }
226
226
  async function isGhInstalled() {
@@ -1554,7 +1554,7 @@ ${detail}
1554
1554
 
1555
1555
  // src/components/github/PRDetailsBox.tsx
1556
1556
  import open from "open";
1557
- import { useRef as useRef2 } from "react";
1557
+ import React, { useRef as useRef2 } from "react";
1558
1558
  import { Box as Box4, Text as Text4, useInput } from "ink";
1559
1559
  import { ScrollView } from "ink-scroll-view";
1560
1560
  import Spinner from "ink-spinner";
@@ -1701,7 +1701,7 @@ function renderInlineToString(tokens) {
1701
1701
  }
1702
1702
 
1703
1703
  // src/components/ui/TitledBox.tsx
1704
- import { Box as Box3, Spacer, Text as Text3, useStdout } from "ink";
1704
+ import { Box as Box3, Text as Text3, useStdout } from "ink";
1705
1705
  import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1706
1706
  function TitledBox({
1707
1707
  title,
@@ -1730,7 +1730,7 @@ function TitledBox({
1730
1730
  ] });
1731
1731
  return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", flexGrow: 1, children: [
1732
1732
  topBorder,
1733
- /* @__PURE__ */ jsxs3(
1733
+ /* @__PURE__ */ jsx4(
1734
1734
  Box3,
1735
1735
  {
1736
1736
  flexDirection: "column",
@@ -1740,13 +1740,10 @@ function TitledBox({
1740
1740
  borderStyle: "round",
1741
1741
  borderTop: false,
1742
1742
  borderColor,
1743
- children: [
1744
- children,
1745
- footer && /* @__PURE__ */ jsxs3(Fragment2, { children: [
1746
- /* @__PURE__ */ jsx4(Spacer, {}),
1747
- footer
1748
- ] })
1749
- ]
1743
+ children: footer ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
1744
+ /* @__PURE__ */ jsx4(Box3, { flexDirection: "column", flexGrow: 1, flexBasis: 0, overflow: "hidden", children }),
1745
+ footer
1746
+ ] }) : children
1750
1747
  }
1751
1748
  )
1752
1749
  ] });
@@ -1777,6 +1774,83 @@ function PRDetailsBox({ pr, loading, error, isActive, title = "[3] PR Details",
1777
1774
  },
1778
1775
  { isActive }
1779
1776
  );
1777
+ const sections = [];
1778
+ if (pr) {
1779
+ if ((((_a = pr.assignees) == null ? void 0 : _a.length) ?? 0) > 0) {
1780
+ sections.push({
1781
+ key: "assignees",
1782
+ content: /* @__PURE__ */ jsxs4(Box4, { children: [
1783
+ /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: "Assignees: " }),
1784
+ /* @__PURE__ */ jsx5(Text4, { children: pr.assignees.map((a) => a.login).join(", ") })
1785
+ ] })
1786
+ });
1787
+ }
1788
+ if ((((_b = pr.reviews) == null ? void 0 : _b.length) ?? 0) > 0 || (((_c = pr.reviewRequests) == null ? void 0 : _c.length) ?? 0) > 0) {
1789
+ sections.push({
1790
+ key: "reviews",
1791
+ content: /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
1792
+ /* @__PURE__ */ jsxs4(Box4, { children: [
1793
+ /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: "Reviews: " }),
1794
+ /* @__PURE__ */ jsx5(Text4, { color: reviewDisplay.color, children: reviewDisplay.text })
1795
+ ] }),
1796
+ (_d = pr.reviews) == null ? void 0 : _d.map((review, idx) => {
1797
+ const color = review.state === "APPROVED" ? "green" : review.state === "CHANGES_REQUESTED" ? "red" : review.state === "COMMENTED" ? "blue" : "yellow";
1798
+ const icon = review.state === "APPROVED" ? "\uF00C" : review.state === "CHANGES_REQUESTED" ? "\uF00D" : review.state === "COMMENTED" ? "\uF075" : "\uF10C";
1799
+ return /* @__PURE__ */ jsxs4(Text4, { color, children: [
1800
+ " ",
1801
+ icon,
1802
+ " ",
1803
+ review.author.login
1804
+ ] }, idx);
1805
+ }),
1806
+ (_e = pr.reviewRequests) == null ? void 0 : _e.map((r, idx) => /* @__PURE__ */ jsxs4(Text4, { color: "yellow", children: [
1807
+ " ",
1808
+ "\u25CB ",
1809
+ r.login ?? r.name ?? r.slug ?? "Team",
1810
+ " ",
1811
+ /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: "(pending)" })
1812
+ ] }, `pending-${idx}`))
1813
+ ] })
1814
+ });
1815
+ }
1816
+ if ((((_f = pr.statusCheckRollup) == null ? void 0 : _f.length) ?? 0) > 0) {
1817
+ sections.push({
1818
+ key: "checks",
1819
+ content: /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
1820
+ /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: "Checks:" }),
1821
+ Array.from(
1822
+ ((_g = pr.statusCheckRollup) == null ? void 0 : _g.reduce((acc, check) => {
1823
+ const key = check.name ?? check.context ?? "";
1824
+ const existing = acc.get(key);
1825
+ if (!existing || (check.startedAt ?? "") > (existing.startedAt ?? "")) {
1826
+ acc.set(key, check);
1827
+ }
1828
+ return acc;
1829
+ }, /* @__PURE__ */ new Map()).values()) ?? []
1830
+ ).sort((a, b) => CHECK_SORT_ORDER[resolveCheckStatus(a)] - CHECK_SORT_ORDER[resolveCheckStatus(b)]).map((check, idx) => {
1831
+ const jobName = check.name ?? check.context;
1832
+ const displayName = check.workflowName ? `${check.workflowName} / ${jobName}` : jobName;
1833
+ const status = resolveCheckStatus(check);
1834
+ return /* @__PURE__ */ jsxs4(Text4, { color: CHECK_COLORS[status], children: [
1835
+ " ",
1836
+ CHECK_ICONS[status],
1837
+ " ",
1838
+ displayName
1839
+ ] }, idx);
1840
+ })
1841
+ ] })
1842
+ });
1843
+ }
1844
+ if (pr.body) {
1845
+ sections.push({
1846
+ key: "description",
1847
+ content: /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
1848
+ /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: "Description:" }),
1849
+ /* @__PURE__ */ jsx5(Markdown, { children: pr.body })
1850
+ ] })
1851
+ });
1852
+ }
1853
+ }
1780
1854
  return /* @__PURE__ */ jsx5(TitledBox, { title: displayTitle, borderColor, footer, children: /* @__PURE__ */ jsx5(Box4, { flexDirection: "column", flexGrow: 1, flexBasis: 0, overflow: "hidden", children: /* @__PURE__ */ jsx5(ScrollView, { ref: scrollRef, children: /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", paddingX: 1, children: [
1781
1855
  loading && /* @__PURE__ */ jsxs4(Text4, { color: "yellow", children: [
1782
1856
  /* @__PURE__ */ jsx5(Spinner, { type: "dots" }),
@@ -1798,9 +1872,9 @@ function PRDetailsBox({ pr, loading, error, isActive, title = "[3] PR Details",
1798
1872
  " \u2190 ",
1799
1873
  pr.headRefName,
1800
1874
  " | by ",
1801
- ((_a = pr.author) == null ? void 0 : _a.login) ?? "unknown",
1875
+ ((_h = pr.author) == null ? void 0 : _h.login) ?? "unknown",
1802
1876
  " | ",
1803
- ((_b = pr.commits) == null ? void 0 : _b.length) ?? 0,
1877
+ ((_i = pr.commits) == null ? void 0 : _i.length) ?? 0,
1804
1878
  " ",
1805
1879
  "commits",
1806
1880
  pr.createdAt && ` | opened ${timeAgo(pr.createdAt)}`,
@@ -1817,64 +1891,11 @@ function PRDetailsBox({ pr, loading, error, isActive, title = "[3] PR Details",
1817
1891
  pr.deletions
1818
1892
  ] })
1819
1893
  ] }),
1820
- (((_c = pr.labels) == null ? void 0 : _c.length) ?? 0) > 0 && /* @__PURE__ */ jsx5(Box4, { gap: 1, children: pr.labels.map((l) => /* @__PURE__ */ jsx5(Box4, { children: /* @__PURE__ */ jsx5(Badge, { color: "black", background: "gray", children: l.name }) }, l.name)) }),
1821
- /* @__PURE__ */ jsx5(Box4, { marginTop: 1, children: /* @__PURE__ */ jsx5(Divider, {}) }),
1822
- (((_d = pr.assignees) == null ? void 0 : _d.length) ?? 0) > 0 && /* @__PURE__ */ jsxs4(Box4, { marginTop: 1, children: [
1823
- /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: "Assignees: " }),
1824
- /* @__PURE__ */ jsx5(Text4, { children: pr.assignees.map((a) => a.login).join(", ") })
1825
- ] }),
1826
- ((((_e = pr.reviews) == null ? void 0 : _e.length) ?? 0) > 0 || (((_f = pr.reviewRequests) == null ? void 0 : _f.length) ?? 0) > 0) && /* @__PURE__ */ jsxs4(Box4, { marginTop: 1, flexDirection: "column", children: [
1827
- /* @__PURE__ */ jsxs4(Box4, { children: [
1828
- /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: "Reviews: " }),
1829
- /* @__PURE__ */ jsx5(Text4, { color: reviewDisplay.color, children: reviewDisplay.text })
1830
- ] }),
1831
- (_g = pr.reviews) == null ? void 0 : _g.map((review, idx) => {
1832
- const color = review.state === "APPROVED" ? "green" : review.state === "CHANGES_REQUESTED" ? "red" : review.state === "COMMENTED" ? "blue" : "yellow";
1833
- const icon = review.state === "APPROVED" ? "\u2713" : review.state === "CHANGES_REQUESTED" ? "\u2717" : review.state === "COMMENTED" ? "\u{1F4AC}" : "\u25CB";
1834
- return /* @__PURE__ */ jsxs4(Text4, { color, children: [
1835
- " ",
1836
- icon,
1837
- " ",
1838
- review.author.login
1839
- ] }, idx);
1840
- }),
1841
- (_h = pr.reviewRequests) == null ? void 0 : _h.map((r, idx) => /* @__PURE__ */ jsxs4(Text4, { color: "yellow", children: [
1842
- " ",
1843
- "\u25CB ",
1844
- r.login ?? r.name ?? r.slug ?? "Team",
1845
- " ",
1846
- /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: "(pending)" })
1847
- ] }, `pending-${idx}`))
1848
- ] }),
1849
- (((_i = pr.statusCheckRollup) == null ? void 0 : _i.length) ?? 0) > 0 && /* @__PURE__ */ jsxs4(Box4, { marginTop: 1, flexDirection: "column", children: [
1850
- /* @__PURE__ */ jsx5(Divider, {}),
1851
- /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: "Checks:" }),
1852
- Array.from(
1853
- ((_j = pr.statusCheckRollup) == null ? void 0 : _j.reduce((acc, check) => {
1854
- const key = check.name ?? check.context ?? "";
1855
- const existing = acc.get(key);
1856
- if (!existing || (check.startedAt ?? "") > (existing.startedAt ?? "")) {
1857
- acc.set(key, check);
1858
- }
1859
- return acc;
1860
- }, /* @__PURE__ */ new Map()).values()) ?? []
1861
- ).sort((a, b) => CHECK_SORT_ORDER[resolveCheckStatus(a)] - CHECK_SORT_ORDER[resolveCheckStatus(b)]).map((check, idx) => {
1862
- const jobName = check.name ?? check.context;
1863
- const displayName = check.workflowName ? `${check.workflowName} / ${jobName}` : jobName;
1864
- const status = resolveCheckStatus(check);
1865
- return /* @__PURE__ */ jsxs4(Text4, { color: CHECK_COLORS[status], children: [
1866
- " ",
1867
- CHECK_ICONS[status],
1868
- " ",
1869
- displayName
1870
- ] }, idx);
1871
- })
1872
- ] }),
1873
- pr.body && /* @__PURE__ */ jsxs4(Box4, { marginTop: 1, flexDirection: "column", children: [
1874
- /* @__PURE__ */ jsx5(Divider, {}),
1875
- /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: "Description:" }),
1876
- /* @__PURE__ */ jsx5(Markdown, { children: pr.body })
1877
- ] })
1894
+ (((_j = pr.labels) == null ? void 0 : _j.length) ?? 0) > 0 && /* @__PURE__ */ jsx5(Box4, { gap: 1, children: pr.labels.map((l) => /* @__PURE__ */ jsx5(Box4, { children: /* @__PURE__ */ jsx5(Badge, { color: "black", background: "gray", children: l.name }) }, l.name)) }),
1895
+ sections.map((section) => /* @__PURE__ */ jsxs4(React.Fragment, { children: [
1896
+ /* @__PURE__ */ jsx5(Box4, { marginTop: 1, children: /* @__PURE__ */ jsx5(Divider, {}) }),
1897
+ section.content
1898
+ ] }, section.key))
1878
1899
  ] })
1879
1900
  ] }) }) }) });
1880
1901
  }
@@ -5705,18 +5726,14 @@ function AllPullRequestsView({ isActive, onModalChange }) {
5705
5726
  const borderColor = isActive ? "yellow" : void 0;
5706
5727
  const scrollRatio = isActive && prs.length > 1 ? highlightedIndex / (prs.length - 1) : null;
5707
5728
  const stateColor = (pr) => {
5708
- const display = resolveMergeDisplay({
5709
- state: pr.state,
5710
- isDraft: pr.isDraft,
5711
- mergeable: "UNKNOWN"
5712
- });
5713
- return display.color;
5729
+ if (pr.state === "MERGED") return "magenta";
5730
+ if (pr.state === "CLOSED") return "red";
5731
+ if (pr.isDraft) return "gray";
5732
+ return "green";
5714
5733
  };
5715
- const stateLabel = (pr) => {
5716
- if (pr.isDraft) return "Draft";
5717
- if (pr.state === "MERGED") return "Merged";
5718
- if (pr.state === "CLOSED") return "Closed";
5719
- return "Open";
5734
+ const stateIcon = (pr) => {
5735
+ if (pr.state === "MERGED") return "\uE727";
5736
+ return "\uE726";
5720
5737
  };
5721
5738
  if (detailPR) {
5722
5739
  const hintFooter = checkoutLoading ? /* @__PURE__ */ jsx24(Box22, { paddingX: 1, children: /* @__PURE__ */ jsxs22(Text21, { color: "yellow", children: [
@@ -5769,25 +5786,19 @@ function AllPullRequestsView({ isActive, onModalChange }) {
5769
5786
  cursor,
5770
5787
  " "
5771
5788
  ] }),
5772
- /* @__PURE__ */ jsxs22(Text21, { children: [
5773
- "#",
5774
- pr.number
5775
- ] }),
5776
- /* @__PURE__ */ jsxs22(Text21, { children: [
5777
- " ",
5778
- pr.title,
5789
+ /* @__PURE__ */ jsxs22(Text21, { color: stateColor(pr), children: [
5790
+ stateIcon(pr),
5779
5791
  " "
5780
5792
  ] }),
5781
- (pr.state !== "OPEN" || pr.isDraft) && /* @__PURE__ */ jsxs22(Text21, { color: stateColor(pr), children: [
5782
- "[",
5783
- stateLabel(pr),
5784
- "]"
5785
- ] })
5793
+ /* @__PURE__ */ jsx24(Text21, { children: pr.title })
5786
5794
  ] }),
5787
5795
  /* @__PURE__ */ jsxs22(Box22, { children: [
5788
5796
  /* @__PURE__ */ jsx24(Text21, { children: " " }),
5789
5797
  /* @__PURE__ */ jsxs22(Text21, { dimColor: true, children: [
5790
5798
  " ",
5799
+ "#",
5800
+ pr.number,
5801
+ " \xB7 ",
5791
5802
  pr.author.login,
5792
5803
  " \xB7 ",
5793
5804
  timeAgo(pr.createdAt)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clairo",
3
- "version": "3.1.3",
3
+ "version": "3.1.4",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",