clairo 0.6.0 → 1.0.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.
Files changed (3) hide show
  1. package/README.md +15 -10
  2. package/dist/cli.js +140 -95
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -7,29 +7,34 @@ Terminal dashboard for GitHub PRs and Jira tickets.
7
7
  - Node.js 18+
8
8
  - [GitHub CLI](https://cli.github.com/) (`gh`) installed and authenticated
9
9
 
10
- ## Install
10
+ ## Usage
11
11
 
12
12
  ```bash
13
- pnpm install
14
- pnpm build
13
+ npx clairo
15
14
  ```
16
15
 
17
- ## Run
16
+ ### Options
18
17
 
19
- ```bash
20
- pnpm start
18
+ ```
19
+ --cwd <path>, -C Run in a different directory
20
+ --version Show version
21
+ --help Show help
21
22
  ```
22
23
 
23
- Or for development:
24
+ ### Examples
24
25
 
25
26
  ```bash
26
- pnpm dev
27
+ # Run in current directory
28
+ npx clairo
29
+
30
+ # Run in a different repo
31
+ npx clairo --cwd ~/projects/other-repo
27
32
  ```
28
33
 
29
34
  ## Keyboard
30
35
 
31
- - `1-4` - Switch between boxes
36
+ - `1-6` - Switch between boxes
32
37
  - `j/k` - Navigate lists
33
38
  - `Enter` - Select
34
- - `Esc` - Cancel
39
+ - `o` - Open in browser
35
40
  - `Ctrl+C` - Quit
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ import { Box as Box16, useApp, useInput as useInput13 } from "ink";
10
10
  // src/components/github/GitHubView.tsx
11
11
  import { exec as exec3 } from "child_process";
12
12
  import { useCallback, useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
13
- import { TitledBox as TitledBox4 } from "@mishieck/ink-titled-box";
13
+ import { TitledBox as TitledBox3 } from "@mishieck/ink-titled-box";
14
14
  import { Box as Box5, Text as Text5, useInput as useInput4 } from "ink";
15
15
 
16
16
  // src/lib/config/index.ts
@@ -586,10 +586,9 @@ ${oldStatus} \u2192 ${newStatus}
586
586
  }
587
587
 
588
588
  // src/components/github/PRDetailsBox.tsx
589
- import { useRef } from "react";
590
589
  import open from "open";
591
- import { TitledBox } from "@mishieck/ink-titled-box";
592
- import { Box as Box2, Text as Text2, useInput } from "ink";
590
+ import { useRef } from "react";
591
+ import { Box as Box2, Text as Text2, useInput, useStdout } from "ink";
593
592
  import { ScrollView } from "ink-scroll-view";
594
593
 
595
594
  // src/components/ui/Markdown.tsx
@@ -756,67 +755,88 @@ function PRDetailsBox({ pr, loading, error, isFocused }) {
756
755
  },
757
756
  { isActive: isFocused }
758
757
  );
759
- return /* @__PURE__ */ jsx2(TitledBox, { borderStyle: "round", titles: [displayTitle], borderColor, flexGrow: 1, children: /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", flexGrow: 1, children: /* @__PURE__ */ jsx2(ScrollView, { ref: scrollRef, children: /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", paddingX: 1, children: [
760
- loading && /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Loading details..." }),
761
- error && /* @__PURE__ */ jsx2(Text2, { color: "red", children: error }),
762
- !loading && !error && !pr && /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Select a PR to view details" }),
763
- !loading && !error && pr && /* @__PURE__ */ jsxs2(Fragment, { children: [
764
- /* @__PURE__ */ jsx2(Text2, { bold: true, children: pr.title }),
765
- /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
766
- "by ",
767
- ((_a = pr.author) == null ? void 0 : _a.login) ?? "unknown",
768
- " | ",
769
- ((_b = pr.commits) == null ? void 0 : _b.length) ?? 0,
770
- " commits"
771
- ] }),
772
- /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, children: [
773
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Review: " }),
774
- /* @__PURE__ */ jsx2(Text2, { color: reviewColor, children: reviewStatus }),
775
- /* @__PURE__ */ jsx2(Text2, { children: " | " }),
776
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Status: " }),
777
- /* @__PURE__ */ jsx2(Text2, { color: mergeDisplay.color, children: mergeDisplay.text })
778
- ] }),
779
- (((_c = pr.assignees) == null ? void 0 : _c.length) ?? 0) > 0 && /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, children: [
780
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Assignees: " }),
781
- /* @__PURE__ */ jsx2(Text2, { children: pr.assignees.map((a) => a.login).join(", ") })
782
- ] }),
783
- (((_d = pr.reviews) == null ? void 0 : _d.length) ?? 0) > 0 && /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
784
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Reviews:" }),
785
- pr.reviews.map((review, idx) => {
786
- const color = review.state === "APPROVED" ? "green" : review.state === "CHANGES_REQUESTED" ? "red" : review.state === "COMMENTED" ? "blue" : "yellow";
787
- const icon = review.state === "APPROVED" ? "\u2713" : review.state === "CHANGES_REQUESTED" ? "\u2717" : review.state === "COMMENTED" ? "\u{1F4AC}" : "\u25CB";
788
- return /* @__PURE__ */ jsxs2(Text2, { color, children: [
789
- " ",
790
- icon,
791
- " ",
792
- review.author.login
793
- ] }, idx);
794
- })
795
- ] }),
796
- (((_e = pr.reviewRequests) == null ? void 0 : _e.length) ?? 0) > 0 && /* @__PURE__ */ jsxs2(Box2, { children: [
797
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Pending: " }),
798
- /* @__PURE__ */ jsx2(Text2, { color: "yellow", children: pr.reviewRequests.map((r) => r.login ?? r.name ?? r.slug ?? "Team").join(", ") })
799
- ] }),
800
- (((_f = pr.statusCheckRollup) == null ? void 0 : _f.length) ?? 0) > 0 && /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, flexDirection: "column", children: [
801
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Checks:" }),
802
- (_g = pr.statusCheckRollup) == null ? void 0 : _g.map((check, idx) => /* @__PURE__ */ jsxs2(Text2, { color: getCheckColor(check), children: [
803
- " ",
804
- getCheckIcon(check),
805
- " ",
806
- check.name ?? check.context
807
- ] }, idx))
808
- ] }),
809
- pr.body && /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, flexDirection: "column", children: [
810
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Description:" }),
811
- /* @__PURE__ */ jsx2(Markdown, { children: pr.body })
812
- ] })
813
- ] })
814
- ] }) }) }) });
758
+ const { stdout } = useStdout();
759
+ const terminalWidth = (stdout == null ? void 0 : stdout.columns) ?? 80;
760
+ const columnWidth = Math.floor(terminalWidth / 2);
761
+ const titlePart = `\u256D\u2500 ${displayTitle} `;
762
+ const dashCount = Math.max(0, columnWidth - titlePart.length - 1);
763
+ const topBorder = `${titlePart}${"\u2500".repeat(dashCount)}\u256E`;
764
+ return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", flexGrow: 1, children: [
765
+ /* @__PURE__ */ jsx2(Text2, { color: borderColor, children: topBorder }),
766
+ /* @__PURE__ */ jsx2(
767
+ Box2,
768
+ {
769
+ flexDirection: "column",
770
+ flexGrow: 1,
771
+ flexBasis: 0,
772
+ overflow: "hidden",
773
+ borderStyle: "round",
774
+ borderTop: false,
775
+ borderColor,
776
+ children: /* @__PURE__ */ jsx2(ScrollView, { ref: scrollRef, children: /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", paddingX: 1, children: [
777
+ loading && /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Loading details..." }),
778
+ error && /* @__PURE__ */ jsx2(Text2, { color: "red", children: error }),
779
+ !loading && !error && !pr && /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Select a PR to view details" }),
780
+ !loading && !error && pr && /* @__PURE__ */ jsxs2(Fragment, { children: [
781
+ /* @__PURE__ */ jsx2(Text2, { bold: true, children: pr.title }),
782
+ /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
783
+ "by ",
784
+ ((_a = pr.author) == null ? void 0 : _a.login) ?? "unknown",
785
+ " | ",
786
+ ((_b = pr.commits) == null ? void 0 : _b.length) ?? 0,
787
+ " commits"
788
+ ] }),
789
+ /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, children: [
790
+ /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Review: " }),
791
+ /* @__PURE__ */ jsx2(Text2, { color: reviewColor, children: reviewStatus }),
792
+ /* @__PURE__ */ jsx2(Text2, { children: " | " }),
793
+ /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Status: " }),
794
+ /* @__PURE__ */ jsx2(Text2, { color: mergeDisplay.color, children: mergeDisplay.text })
795
+ ] }),
796
+ (((_c = pr.assignees) == null ? void 0 : _c.length) ?? 0) > 0 && /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, children: [
797
+ /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Assignees: " }),
798
+ /* @__PURE__ */ jsx2(Text2, { children: pr.assignees.map((a) => a.login).join(", ") })
799
+ ] }),
800
+ (((_d = pr.reviews) == null ? void 0 : _d.length) ?? 0) > 0 && /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
801
+ /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Reviews:" }),
802
+ pr.reviews.map((review, idx) => {
803
+ const color = review.state === "APPROVED" ? "green" : review.state === "CHANGES_REQUESTED" ? "red" : review.state === "COMMENTED" ? "blue" : "yellow";
804
+ const icon = review.state === "APPROVED" ? "\u2713" : review.state === "CHANGES_REQUESTED" ? "\u2717" : review.state === "COMMENTED" ? "\u{1F4AC}" : "\u25CB";
805
+ return /* @__PURE__ */ jsxs2(Text2, { color, children: [
806
+ " ",
807
+ icon,
808
+ " ",
809
+ review.author.login
810
+ ] }, idx);
811
+ })
812
+ ] }),
813
+ (((_e = pr.reviewRequests) == null ? void 0 : _e.length) ?? 0) > 0 && /* @__PURE__ */ jsxs2(Box2, { children: [
814
+ /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Pending: " }),
815
+ /* @__PURE__ */ jsx2(Text2, { color: "yellow", children: pr.reviewRequests.map((r) => r.login ?? r.name ?? r.slug ?? "Team").join(", ") })
816
+ ] }),
817
+ (((_f = pr.statusCheckRollup) == null ? void 0 : _f.length) ?? 0) > 0 && /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, flexDirection: "column", children: [
818
+ /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Checks:" }),
819
+ (_g = pr.statusCheckRollup) == null ? void 0 : _g.map((check, idx) => /* @__PURE__ */ jsxs2(Text2, { color: getCheckColor(check), children: [
820
+ " ",
821
+ getCheckIcon(check),
822
+ " ",
823
+ check.name ?? check.context
824
+ ] }, idx))
825
+ ] }),
826
+ pr.body && /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, flexDirection: "column", children: [
827
+ /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Description:" }),
828
+ /* @__PURE__ */ jsx2(Markdown, { children: pr.body })
829
+ ] })
830
+ ] })
831
+ ] }) })
832
+ }
833
+ )
834
+ ] });
815
835
  }
816
836
 
817
837
  // src/components/github/PullRequestsBox.tsx
818
838
  import { useEffect, useState } from "react";
819
- import { TitledBox as TitledBox2 } from "@mishieck/ink-titled-box";
839
+ import { TitledBox } from "@mishieck/ink-titled-box";
820
840
  import { Box as Box3, Text as Text3, useInput as useInput2 } from "ink";
821
841
 
822
842
  // src/lib/clipboard.ts
@@ -886,7 +906,7 @@ function PullRequestsBox({
886
906
  const title = "[2] Pull Requests";
887
907
  const subtitle = branch ? ` (${branch})` : "";
888
908
  const borderColor = isFocused ? "yellow" : void 0;
889
- return /* @__PURE__ */ jsx3(TitledBox2, { borderStyle: "round", titles: [`${title}${subtitle}`], borderColor, flexShrink: 0, children: /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", paddingX: 1, overflow: "hidden", children: [
909
+ return /* @__PURE__ */ jsx3(TitledBox, { borderStyle: "round", titles: [`${title}${subtitle}`], borderColor, flexShrink: 0, children: /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", paddingX: 1, overflow: "hidden", children: [
890
910
  loading && /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "Loading PRs..." }),
891
911
  error && /* @__PURE__ */ jsx3(Text3, { color: "red", children: error }),
892
912
  !loading && !error && /* @__PURE__ */ jsxs3(Fragment2, { children: [
@@ -894,14 +914,21 @@ function PullRequestsBox({
894
914
  prs.map((pr, idx) => {
895
915
  const isHighlighted = isFocused && idx === highlightedIndex;
896
916
  const isSelected = pr.number === (selectedPR == null ? void 0 : selectedPR.number);
897
- const prefix = isHighlighted ? "> " : isSelected ? "\u25CF " : " ";
898
- return /* @__PURE__ */ jsxs3(Text3, { color: isSelected ? "green" : void 0, children: [
899
- prefix,
900
- "#",
901
- pr.number,
902
- " ",
903
- pr.isDraft ? "[Draft] " : "",
904
- pr.title
917
+ const cursor = isHighlighted ? ">" : " ";
918
+ const indicator = isSelected ? " *" : "";
919
+ return /* @__PURE__ */ jsxs3(Box3, { children: [
920
+ /* @__PURE__ */ jsxs3(Text3, { color: isHighlighted ? "yellow" : void 0, children: [
921
+ cursor,
922
+ " "
923
+ ] }),
924
+ /* @__PURE__ */ jsxs3(Text3, { color: isSelected ? "green" : void 0, children: [
925
+ "#",
926
+ pr.number,
927
+ " ",
928
+ pr.isDraft ? "[Draft] " : "",
929
+ pr.title
930
+ ] }),
931
+ /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: indicator })
905
932
  ] }, pr.number);
906
933
  }),
907
934
  /* @__PURE__ */ jsxs3(Text3, { color: "blue", children: [
@@ -914,7 +941,7 @@ function PullRequestsBox({
914
941
 
915
942
  // src/components/github/RemotesBox.tsx
916
943
  import { useEffect as useEffect2, useState as useState2 } from "react";
917
- import { TitledBox as TitledBox3 } from "@mishieck/ink-titled-box";
944
+ import { TitledBox as TitledBox2 } from "@mishieck/ink-titled-box";
918
945
  import { Box as Box4, Text as Text4, useInput as useInput3 } from "ink";
919
946
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
920
947
  function RemotesBox({ remotes, selectedRemote, onSelect, loading, error, isFocused }) {
@@ -940,20 +967,27 @@ function RemotesBox({ remotes, selectedRemote, onSelect, loading, error, isFocus
940
967
  );
941
968
  const title = "[1] Remotes";
942
969
  const borderColor = isFocused ? "yellow" : void 0;
943
- return /* @__PURE__ */ jsx4(TitledBox3, { borderStyle: "round", titles: [title], borderColor, flexShrink: 0, children: /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", paddingX: 1, overflow: "hidden", children: [
970
+ return /* @__PURE__ */ jsx4(TitledBox2, { borderStyle: "round", titles: [title], borderColor, flexShrink: 0, children: /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", paddingX: 1, overflow: "hidden", children: [
944
971
  loading && /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "Loading..." }),
945
972
  error && /* @__PURE__ */ jsx4(Text4, { color: "red", children: error }),
946
973
  !loading && !error && remotes.length === 0 && /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "No remotes configured" }),
947
974
  !loading && !error && remotes.map((remote, idx) => {
948
975
  const isHighlighted = isFocused && idx === highlightedIndex;
949
976
  const isSelected = remote.name === selectedRemote;
950
- const prefix = isHighlighted ? "> " : isSelected ? "\u25CF " : " ";
951
- return /* @__PURE__ */ jsxs4(Text4, { color: isSelected ? "green" : void 0, children: [
952
- prefix,
953
- remote.name,
954
- " (",
955
- remote.url,
956
- ")"
977
+ const cursor = isHighlighted ? ">" : " ";
978
+ const indicator = isSelected ? " *" : "";
979
+ return /* @__PURE__ */ jsxs4(Box4, { children: [
980
+ /* @__PURE__ */ jsxs4(Text4, { color: isHighlighted ? "yellow" : void 0, children: [
981
+ cursor,
982
+ " "
983
+ ] }),
984
+ /* @__PURE__ */ jsxs4(Text4, { color: isSelected ? "green" : void 0, children: [
985
+ remote.name,
986
+ " (",
987
+ remote.url,
988
+ ")"
989
+ ] }),
990
+ /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: indicator })
957
991
  ] }, remote.name);
958
992
  })
959
993
  ] }) });
@@ -1155,7 +1189,7 @@ function GitHubView({ isFocused, onKeybindingsChange, onLogUpdated }) {
1155
1189
  { isActive: isFocused }
1156
1190
  );
1157
1191
  if (isRepo === false) {
1158
- return /* @__PURE__ */ jsx5(TitledBox4, { borderStyle: "round", titles: ["Error"], flexGrow: 1, children: /* @__PURE__ */ jsx5(Text5, { color: "red", children: "Current directory is not a git repository" }) });
1192
+ return /* @__PURE__ */ jsx5(TitledBox3, { borderStyle: "round", titles: ["Error"], flexGrow: 1, children: /* @__PURE__ */ jsx5(Text5, { color: "red", children: "Current directory is not a git repository" }) });
1159
1193
  }
1160
1194
  return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", flexGrow: 1, children: [
1161
1195
  /* @__PURE__ */ jsx5(
@@ -1198,7 +1232,7 @@ function GitHubView({ isFocused, onKeybindingsChange, onLogUpdated }) {
1198
1232
  // src/components/jira/JiraView.tsx
1199
1233
  import { useCallback as useCallback2, useEffect as useEffect5, useState as useState7 } from "react";
1200
1234
  import open2 from "open";
1201
- import { TitledBox as TitledBox5 } from "@mishieck/ink-titled-box";
1235
+ import { TitledBox as TitledBox4 } from "@mishieck/ink-titled-box";
1202
1236
  import { Box as Box11, Text as Text11, useInput as useInput9 } from "ink";
1203
1237
 
1204
1238
  // src/components/jira/ChangeStatusModal.tsx
@@ -1712,7 +1746,7 @@ function JiraView({ isFocused, onModalChange, onKeybindingsChange, onLogUpdated
1712
1746
  { isActive: isFocused && !showConfigureModal && !showLinkModal && !showStatusModal }
1713
1747
  );
1714
1748
  if (isRepo === false) {
1715
- return /* @__PURE__ */ jsx11(TitledBox5, { borderStyle: "round", titles: ["Jira"], flexShrink: 0, children: /* @__PURE__ */ jsx11(Text11, { color: "red", children: "Not a git repository" }) });
1749
+ return /* @__PURE__ */ jsx11(TitledBox4, { borderStyle: "round", titles: ["Jira"], flexShrink: 0, children: /* @__PURE__ */ jsx11(Text11, { color: "red", children: "Not a git repository" }) });
1716
1750
  }
1717
1751
  if (showConfigureModal) {
1718
1752
  const siteUrl = repoPath ? getJiraSiteUrl(repoPath) : void 0;
@@ -1768,7 +1802,7 @@ function JiraView({ isFocused, onModalChange, onKeybindingsChange, onLogUpdated
1768
1802
  }
1769
1803
  const title = "[4] Jira";
1770
1804
  const borderColor = isFocused ? "yellow" : void 0;
1771
- return /* @__PURE__ */ jsx11(TitledBox5, { borderStyle: "round", titles: [title], borderColor, flexShrink: 0, children: /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", paddingX: 1, children: [
1805
+ return /* @__PURE__ */ jsx11(TitledBox4, { borderStyle: "round", titles: [title], borderColor, flexShrink: 0, children: /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", paddingX: 1, children: [
1772
1806
  jiraState === "not_configured" && /* @__PURE__ */ jsx11(Text11, { dimColor: true, children: "No Jira site configured" }),
1773
1807
  jiraState === "no_tickets" && /* @__PURE__ */ jsx11(Text11, { dimColor: true, children: "No tickets linked to this branch" }),
1774
1808
  jiraState === "has_tickets" && tickets.map((ticket, idx) => /* @__PURE__ */ jsx11(
@@ -1789,7 +1823,7 @@ import { useCallback as useCallback3, useEffect as useEffect6, useState as useSt
1789
1823
  import { Box as Box14, useInput as useInput12 } from "ink";
1790
1824
 
1791
1825
  // src/components/logs/LogsHistoryBox.tsx
1792
- import { TitledBox as TitledBox6 } from "@mishieck/ink-titled-box";
1826
+ import { TitledBox as TitledBox5 } from "@mishieck/ink-titled-box";
1793
1827
  import { Box as Box12, Text as Text12, useInput as useInput10 } from "ink";
1794
1828
  import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
1795
1829
  function LogsHistoryBox({
@@ -1820,7 +1854,7 @@ function LogsHistoryBox({
1820
1854
  },
1821
1855
  { isActive: isFocused }
1822
1856
  );
1823
- return /* @__PURE__ */ jsx12(TitledBox6, { borderStyle: "round", titles: [title], borderColor, flexShrink: 0, children: /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", paddingX: 1, children: [
1857
+ return /* @__PURE__ */ jsx12(TitledBox5, { borderStyle: "round", titles: [title], borderColor, flexShrink: 0, children: /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", paddingX: 1, children: [
1824
1858
  logFiles.length === 0 && /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: "No logs yet" }),
1825
1859
  logFiles.map((file, idx) => {
1826
1860
  const isHighlighted = idx === highlightedIndex;
@@ -1849,7 +1883,7 @@ function LogsHistoryBox({
1849
1883
 
1850
1884
  // src/components/logs/LogViewerBox.tsx
1851
1885
  import { useRef as useRef3 } from "react";
1852
- import { TitledBox as TitledBox7 } from "@mishieck/ink-titled-box";
1886
+ import { TitledBox as TitledBox6 } from "@mishieck/ink-titled-box";
1853
1887
  import { Box as Box13, Text as Text13, useInput as useInput11 } from "ink";
1854
1888
  import { ScrollView as ScrollView2 } from "ink-scroll-view";
1855
1889
  import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
@@ -1884,7 +1918,7 @@ function LogViewerBox({ date, content, isFocused, onRefresh, onLogCreated }) {
1884
1918
  },
1885
1919
  { isActive: isFocused }
1886
1920
  );
1887
- return /* @__PURE__ */ jsx13(TitledBox7, { borderStyle: "round", titles: [displayTitle], borderColor, flexGrow: 1, children: /* @__PURE__ */ jsx13(Box13, { flexDirection: "column", flexGrow: 1, children: /* @__PURE__ */ jsx13(ScrollView2, { ref: scrollRef, children: /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", paddingX: 1, children: [
1921
+ return /* @__PURE__ */ jsx13(TitledBox6, { borderStyle: "round", titles: [displayTitle], borderColor, flexGrow: 1, children: /* @__PURE__ */ jsx13(Box13, { flexDirection: "column", flexGrow: 1, children: /* @__PURE__ */ jsx13(ScrollView2, { ref: scrollRef, children: /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", paddingX: 1, children: [
1888
1922
  !date && /* @__PURE__ */ jsx13(Text13, { dimColor: true, children: "Select a log file to view" }),
1889
1923
  date && content === null && /* @__PURE__ */ jsx13(Text13, { dimColor: true, children: "Log file not found" }),
1890
1924
  date && content !== null && content.trim() === "" && /* @__PURE__ */ jsx13(Text13, { dimColor: true, children: "Empty log file" }),
@@ -2097,11 +2131,11 @@ function App() {
2097
2131
  import { render as inkRender } from "ink";
2098
2132
 
2099
2133
  // src/lib/Screen.tsx
2100
- import { Box as Box17, useStdout } from "ink";
2134
+ import { Box as Box17, useStdout as useStdout2 } from "ink";
2101
2135
  import { useCallback as useCallback5, useEffect as useEffect7, useState as useState10 } from "react";
2102
2136
  import { jsx as jsx17 } from "react/jsx-runtime";
2103
2137
  function Screen({ children }) {
2104
- const { stdout } = useStdout();
2138
+ const { stdout } = useStdout2();
2105
2139
  const getSize = useCallback5(
2106
2140
  () => ({ height: stdout.rows, width: stdout.columns }),
2107
2141
  [stdout]
@@ -2146,25 +2180,36 @@ function render(node, options) {
2146
2180
 
2147
2181
  // src/cli.tsx
2148
2182
  import { jsx as jsx19 } from "react/jsx-runtime";
2149
- meow(
2183
+ var cli = meow(
2150
2184
  `
2151
2185
  Usage
2152
2186
  $ clairo
2153
2187
 
2154
2188
  Options
2155
- --name Your name
2189
+ --cwd <path> Run in a different directory
2190
+ --version Show version
2191
+ --help Show this help
2156
2192
 
2157
2193
  Examples
2158
- $ clairo --name=Jane
2159
- Hello, Jane
2194
+ $ clairo
2195
+ $ clairo --cwd ~/projects/other-repo
2160
2196
  `,
2161
2197
  {
2162
2198
  importMeta: import.meta,
2163
2199
  flags: {
2164
- name: {
2165
- type: "string"
2200
+ cwd: {
2201
+ type: "string",
2202
+ shortFlag: "C"
2166
2203
  }
2167
2204
  }
2168
2205
  }
2169
2206
  );
2207
+ if (cli.flags.cwd) {
2208
+ try {
2209
+ process.chdir(cli.flags.cwd);
2210
+ } catch {
2211
+ console.error(`Error: Cannot access directory "${cli.flags.cwd}"`);
2212
+ process.exit(1);
2213
+ }
2214
+ }
2170
2215
  render(/* @__PURE__ */ jsx19(App, {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clairo",
3
- "version": "0.6.0",
3
+ "version": "1.0.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",