clairo 0.3.0 → 0.4.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/cli.js +240 -129
- package/package.json +4 -1
package/dist/cli.js
CHANGED
|
@@ -5,13 +5,13 @@ import meow from "meow";
|
|
|
5
5
|
|
|
6
6
|
// src/app.tsx
|
|
7
7
|
import { useState as useState8 } from "react";
|
|
8
|
-
import { Box as
|
|
8
|
+
import { Box as Box13, useApp, useInput as useInput10 } from "ink";
|
|
9
9
|
|
|
10
10
|
// src/components/github/GitHubView.tsx
|
|
11
11
|
import { exec as exec3 } from "child_process";
|
|
12
12
|
import { useCallback, useEffect as useEffect3, useState as useState3 } from "react";
|
|
13
13
|
import { TitledBox as TitledBox4 } from "@mishieck/ink-titled-box";
|
|
14
|
-
import { Box as
|
|
14
|
+
import { Box as Box5, Text as Text5, useInput as useInput4 } from "ink";
|
|
15
15
|
|
|
16
16
|
// src/lib/config/index.ts
|
|
17
17
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -245,9 +245,120 @@ async function getPRDetails(prNumber, repo) {
|
|
|
245
245
|
import { useRef } from "react";
|
|
246
246
|
import open from "open";
|
|
247
247
|
import { TitledBox } from "@mishieck/ink-titled-box";
|
|
248
|
-
import { Box, Text, useInput } from "ink";
|
|
248
|
+
import { Box as Box2, Text as Text2, useInput } from "ink";
|
|
249
249
|
import { ScrollView } from "ink-scroll-view";
|
|
250
|
-
|
|
250
|
+
|
|
251
|
+
// src/components/ui/Markdown.tsx
|
|
252
|
+
import { Box, Text } from "ink";
|
|
253
|
+
import Link from "ink-link";
|
|
254
|
+
import { marked } from "marked";
|
|
255
|
+
import Table from "cli-table3";
|
|
256
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
257
|
+
function Markdown({ children }) {
|
|
258
|
+
const tokens = marked.lexer(children);
|
|
259
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: tokens.map((token, idx) => /* @__PURE__ */ jsx(TokenRenderer, { token }, idx)) });
|
|
260
|
+
}
|
|
261
|
+
function TokenRenderer({ token }) {
|
|
262
|
+
var _a, _b;
|
|
263
|
+
switch (token.type) {
|
|
264
|
+
case "heading":
|
|
265
|
+
return /* @__PURE__ */ jsx(Box, { marginTop: token.depth === 1 ? 0 : 1, children: /* @__PURE__ */ jsx(Text, { bold: true, underline: token.depth === 1, children: renderInline(token.tokens) }) });
|
|
266
|
+
case "paragraph": {
|
|
267
|
+
const hasLinks = (_a = token.tokens) == null ? void 0 : _a.some((t) => {
|
|
268
|
+
var _a2;
|
|
269
|
+
return t.type === "link" || t.type === "strong" && "tokens" in t && ((_a2 = t.tokens) == null ? void 0 : _a2.some((st) => st.type === "link"));
|
|
270
|
+
});
|
|
271
|
+
if (hasLinks) {
|
|
272
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "row", flexWrap: "wrap", children: renderInline(token.tokens) });
|
|
273
|
+
}
|
|
274
|
+
return /* @__PURE__ */ jsx(Text, { children: renderInline(token.tokens) });
|
|
275
|
+
}
|
|
276
|
+
case "code":
|
|
277
|
+
return /* @__PURE__ */ jsx(Box, { marginY: 1, paddingX: 1, borderStyle: "single", borderColor: "gray", children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: token.text }) });
|
|
278
|
+
case "blockquote":
|
|
279
|
+
return /* @__PURE__ */ jsxs(Box, { marginLeft: 2, children: [
|
|
280
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", children: "\u2502 " }),
|
|
281
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", children: (_b = token.tokens) == null ? void 0 : _b.map((t, idx) => /* @__PURE__ */ jsx(TokenRenderer, { token: t }, idx)) })
|
|
282
|
+
] });
|
|
283
|
+
case "list":
|
|
284
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginY: 1, children: token.items.map((item, idx) => /* @__PURE__ */ jsxs(Box, { children: [
|
|
285
|
+
/* @__PURE__ */ jsx(Text, { children: token.ordered ? `${idx + 1}. ` : "\u2022 " }),
|
|
286
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", children: item.tokens.map((t, i) => /* @__PURE__ */ jsx(TokenRenderer, { token: t }, i)) })
|
|
287
|
+
] }, idx)) });
|
|
288
|
+
case "table":
|
|
289
|
+
return /* @__PURE__ */ jsx(TableRenderer, { token });
|
|
290
|
+
case "hr":
|
|
291
|
+
return /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2500".repeat(40) });
|
|
292
|
+
case "space":
|
|
293
|
+
return null;
|
|
294
|
+
default:
|
|
295
|
+
if ("text" in token && typeof token.text === "string") {
|
|
296
|
+
return /* @__PURE__ */ jsx(Text, { children: token.text });
|
|
297
|
+
}
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
function TableRenderer({ token }) {
|
|
302
|
+
const table = new Table({
|
|
303
|
+
head: token.header.map((cell) => renderInlineToString(cell.tokens)),
|
|
304
|
+
style: { head: ["cyan"], border: ["gray"] }
|
|
305
|
+
});
|
|
306
|
+
for (const row of token.rows) {
|
|
307
|
+
table.push(row.map((cell) => renderInlineToString(cell.tokens)));
|
|
308
|
+
}
|
|
309
|
+
return /* @__PURE__ */ jsx(Text, { children: table.toString() });
|
|
310
|
+
}
|
|
311
|
+
function renderInline(tokens) {
|
|
312
|
+
if (!tokens) return null;
|
|
313
|
+
return tokens.map((token, idx) => {
|
|
314
|
+
switch (token.type) {
|
|
315
|
+
case "text":
|
|
316
|
+
return /* @__PURE__ */ jsx(Text, { children: token.text }, idx);
|
|
317
|
+
case "strong":
|
|
318
|
+
return /* @__PURE__ */ jsx(Text, { bold: true, children: renderInline(token.tokens) }, idx);
|
|
319
|
+
case "em":
|
|
320
|
+
return /* @__PURE__ */ jsx(Text, { italic: true, children: renderInline(token.tokens) }, idx);
|
|
321
|
+
case "codespan":
|
|
322
|
+
return /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
323
|
+
"`",
|
|
324
|
+
token.text,
|
|
325
|
+
"`"
|
|
326
|
+
] }, idx);
|
|
327
|
+
case "link":
|
|
328
|
+
return /* @__PURE__ */ jsx(Link, { url: token.href, children: /* @__PURE__ */ jsx(Text, { color: "blue", children: renderInlineToString(token.tokens) }) }, idx);
|
|
329
|
+
case "image":
|
|
330
|
+
return /* @__PURE__ */ jsxs(Text, { color: "blue", children: [
|
|
331
|
+
"[Image: ",
|
|
332
|
+
token.text || token.href,
|
|
333
|
+
"]"
|
|
334
|
+
] }, idx);
|
|
335
|
+
case "br":
|
|
336
|
+
return /* @__PURE__ */ jsx(Text, { children: "\n" }, idx);
|
|
337
|
+
case "del":
|
|
338
|
+
return /* @__PURE__ */ jsx(Text, { strikethrough: true, children: renderInline(token.tokens) }, idx);
|
|
339
|
+
default:
|
|
340
|
+
if ("text" in token && typeof token.text === "string") {
|
|
341
|
+
return /* @__PURE__ */ jsx(Text, { children: token.text }, idx);
|
|
342
|
+
}
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
function renderInlineToString(tokens) {
|
|
348
|
+
if (!tokens) return "";
|
|
349
|
+
return tokens.map((token) => {
|
|
350
|
+
if ("text" in token && typeof token.text === "string") {
|
|
351
|
+
return token.text;
|
|
352
|
+
}
|
|
353
|
+
if ("tokens" in token && Array.isArray(token.tokens)) {
|
|
354
|
+
return renderInlineToString(token.tokens);
|
|
355
|
+
}
|
|
356
|
+
return "";
|
|
357
|
+
}).join("");
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// src/components/github/PRDetailsBox.tsx
|
|
361
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
251
362
|
function getCheckColor(check) {
|
|
252
363
|
const conclusion = check.conclusion ?? check.state;
|
|
253
364
|
if (conclusion === "SUCCESS") return "green";
|
|
@@ -301,36 +412,36 @@ function PRDetailsBox({ pr, loading, error, isFocused }) {
|
|
|
301
412
|
},
|
|
302
413
|
{ isActive: isFocused }
|
|
303
414
|
);
|
|
304
|
-
return /* @__PURE__ */
|
|
305
|
-
loading && /* @__PURE__ */
|
|
306
|
-
error && /* @__PURE__ */
|
|
307
|
-
!loading && !error && !pr && /* @__PURE__ */
|
|
308
|
-
!loading && !error && pr && /* @__PURE__ */
|
|
309
|
-
/* @__PURE__ */
|
|
310
|
-
/* @__PURE__ */
|
|
415
|
+
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: [
|
|
416
|
+
loading && /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Loading details..." }),
|
|
417
|
+
error && /* @__PURE__ */ jsx2(Text2, { color: "red", children: error }),
|
|
418
|
+
!loading && !error && !pr && /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Select a PR to view details" }),
|
|
419
|
+
!loading && !error && pr && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
420
|
+
/* @__PURE__ */ jsx2(Text2, { bold: true, children: pr.title }),
|
|
421
|
+
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
311
422
|
"by ",
|
|
312
423
|
((_a = pr.author) == null ? void 0 : _a.login) ?? "unknown",
|
|
313
424
|
" | ",
|
|
314
425
|
((_b = pr.commits) == null ? void 0 : _b.length) ?? 0,
|
|
315
426
|
" commits"
|
|
316
427
|
] }),
|
|
317
|
-
/* @__PURE__ */
|
|
318
|
-
/* @__PURE__ */
|
|
319
|
-
/* @__PURE__ */
|
|
320
|
-
/* @__PURE__ */
|
|
321
|
-
/* @__PURE__ */
|
|
322
|
-
/* @__PURE__ */
|
|
428
|
+
/* @__PURE__ */ jsxs2(Box2, { marginTop: 1, children: [
|
|
429
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Review: " }),
|
|
430
|
+
/* @__PURE__ */ jsx2(Text2, { color: reviewColor, children: reviewStatus }),
|
|
431
|
+
/* @__PURE__ */ jsx2(Text2, { children: " | " }),
|
|
432
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Status: " }),
|
|
433
|
+
/* @__PURE__ */ jsx2(Text2, { color: mergeDisplay.color, children: mergeDisplay.text })
|
|
323
434
|
] }),
|
|
324
|
-
(((_c = pr.assignees) == null ? void 0 : _c.length) ?? 0) > 0 && /* @__PURE__ */
|
|
325
|
-
/* @__PURE__ */
|
|
326
|
-
/* @__PURE__ */
|
|
435
|
+
(((_c = pr.assignees) == null ? void 0 : _c.length) ?? 0) > 0 && /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, children: [
|
|
436
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Assignees: " }),
|
|
437
|
+
/* @__PURE__ */ jsx2(Text2, { children: pr.assignees.map((a) => a.login).join(", ") })
|
|
327
438
|
] }),
|
|
328
|
-
(((_d = pr.reviews) == null ? void 0 : _d.length) ?? 0) > 0 && /* @__PURE__ */
|
|
329
|
-
/* @__PURE__ */
|
|
439
|
+
(((_d = pr.reviews) == null ? void 0 : _d.length) ?? 0) > 0 && /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
|
|
440
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Reviews:" }),
|
|
330
441
|
pr.reviews.map((review, idx) => {
|
|
331
442
|
const color = review.state === "APPROVED" ? "green" : review.state === "CHANGES_REQUESTED" ? "red" : review.state === "COMMENTED" ? "blue" : "yellow";
|
|
332
443
|
const icon = review.state === "APPROVED" ? "\u2713" : review.state === "CHANGES_REQUESTED" ? "\u2717" : review.state === "COMMENTED" ? "\u{1F4AC}" : "\u25CB";
|
|
333
|
-
return /* @__PURE__ */
|
|
444
|
+
return /* @__PURE__ */ jsxs2(Text2, { color, children: [
|
|
334
445
|
" ",
|
|
335
446
|
icon,
|
|
336
447
|
" ",
|
|
@@ -338,22 +449,22 @@ function PRDetailsBox({ pr, loading, error, isFocused }) {
|
|
|
338
449
|
] }, idx);
|
|
339
450
|
})
|
|
340
451
|
] }),
|
|
341
|
-
(((_e = pr.reviewRequests) == null ? void 0 : _e.length) ?? 0) > 0 && /* @__PURE__ */
|
|
342
|
-
/* @__PURE__ */
|
|
343
|
-
/* @__PURE__ */
|
|
452
|
+
(((_e = pr.reviewRequests) == null ? void 0 : _e.length) ?? 0) > 0 && /* @__PURE__ */ jsxs2(Box2, { children: [
|
|
453
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Pending: " }),
|
|
454
|
+
/* @__PURE__ */ jsx2(Text2, { color: "yellow", children: pr.reviewRequests.map((r) => r.login ?? r.name ?? r.slug ?? "Team").join(", ") })
|
|
344
455
|
] }),
|
|
345
|
-
(((_f = pr.statusCheckRollup) == null ? void 0 : _f.length) ?? 0) > 0 && /* @__PURE__ */
|
|
346
|
-
/* @__PURE__ */
|
|
347
|
-
(_g = pr.statusCheckRollup) == null ? void 0 : _g.map((check, idx) => /* @__PURE__ */
|
|
456
|
+
(((_f = pr.statusCheckRollup) == null ? void 0 : _f.length) ?? 0) > 0 && /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, flexDirection: "column", children: [
|
|
457
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Checks:" }),
|
|
458
|
+
(_g = pr.statusCheckRollup) == null ? void 0 : _g.map((check, idx) => /* @__PURE__ */ jsxs2(Text2, { color: getCheckColor(check), children: [
|
|
348
459
|
" ",
|
|
349
460
|
getCheckIcon(check),
|
|
350
461
|
" ",
|
|
351
462
|
check.name ?? check.context
|
|
352
463
|
] }, idx))
|
|
353
464
|
] }),
|
|
354
|
-
pr.body && /* @__PURE__ */
|
|
355
|
-
/* @__PURE__ */
|
|
356
|
-
/* @__PURE__ */
|
|
465
|
+
pr.body && /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, flexDirection: "column", children: [
|
|
466
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Description:" }),
|
|
467
|
+
/* @__PURE__ */ jsx2(Markdown, { children: pr.body })
|
|
357
468
|
] })
|
|
358
469
|
] })
|
|
359
470
|
] }) }) }) });
|
|
@@ -362,7 +473,7 @@ function PRDetailsBox({ pr, loading, error, isFocused }) {
|
|
|
362
473
|
// src/components/github/PullRequestsBox.tsx
|
|
363
474
|
import { useEffect, useState } from "react";
|
|
364
475
|
import { TitledBox as TitledBox2 } from "@mishieck/ink-titled-box";
|
|
365
|
-
import { Box as
|
|
476
|
+
import { Box as Box3, Text as Text3, useInput as useInput2 } from "ink";
|
|
366
477
|
|
|
367
478
|
// src/lib/clipboard.ts
|
|
368
479
|
import { exec as exec2 } from "child_process";
|
|
@@ -386,7 +497,7 @@ async function copyToClipboard(text) {
|
|
|
386
497
|
}
|
|
387
498
|
|
|
388
499
|
// src/components/github/PullRequestsBox.tsx
|
|
389
|
-
import { Fragment as Fragment2, jsx as
|
|
500
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
390
501
|
function PullRequestsBox({
|
|
391
502
|
prs,
|
|
392
503
|
selectedPR,
|
|
@@ -431,16 +542,16 @@ function PullRequestsBox({
|
|
|
431
542
|
const title = "[2] Pull Requests";
|
|
432
543
|
const subtitle = branch ? ` (${branch})` : "";
|
|
433
544
|
const borderColor = isFocused ? "yellow" : void 0;
|
|
434
|
-
return /* @__PURE__ */
|
|
435
|
-
loading && /* @__PURE__ */
|
|
436
|
-
error && /* @__PURE__ */
|
|
437
|
-
!loading && !error && /* @__PURE__ */
|
|
438
|
-
prs.length === 0 && /* @__PURE__ */
|
|
545
|
+
return /* @__PURE__ */ jsx3(TitledBox2, { borderStyle: "round", titles: [`${title}${subtitle}`], borderColor, flexShrink: 0, children: /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", paddingX: 1, overflow: "hidden", children: [
|
|
546
|
+
loading && /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "Loading PRs..." }),
|
|
547
|
+
error && /* @__PURE__ */ jsx3(Text3, { color: "red", children: error }),
|
|
548
|
+
!loading && !error && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
549
|
+
prs.length === 0 && /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "No PRs for this branch" }),
|
|
439
550
|
prs.map((pr, idx) => {
|
|
440
551
|
const isHighlighted = isFocused && idx === highlightedIndex;
|
|
441
552
|
const isSelected = pr.number === (selectedPR == null ? void 0 : selectedPR.number);
|
|
442
553
|
const prefix = isHighlighted ? "> " : isSelected ? "\u25CF " : " ";
|
|
443
|
-
return /* @__PURE__ */
|
|
554
|
+
return /* @__PURE__ */ jsxs3(Text3, { color: isSelected ? "green" : void 0, children: [
|
|
444
555
|
prefix,
|
|
445
556
|
"#",
|
|
446
557
|
pr.number,
|
|
@@ -449,7 +560,7 @@ function PullRequestsBox({
|
|
|
449
560
|
pr.title
|
|
450
561
|
] }, pr.number);
|
|
451
562
|
}),
|
|
452
|
-
/* @__PURE__ */
|
|
563
|
+
/* @__PURE__ */ jsxs3(Text3, { color: "blue", children: [
|
|
453
564
|
isFocused && highlightedIndex === prs.length ? "> " : " ",
|
|
454
565
|
"+ Create new PR"
|
|
455
566
|
] })
|
|
@@ -460,8 +571,8 @@ function PullRequestsBox({
|
|
|
460
571
|
// src/components/github/RemotesBox.tsx
|
|
461
572
|
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
462
573
|
import { TitledBox as TitledBox3 } from "@mishieck/ink-titled-box";
|
|
463
|
-
import { Box as
|
|
464
|
-
import { jsx as
|
|
574
|
+
import { Box as Box4, Text as Text4, useInput as useInput3 } from "ink";
|
|
575
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
465
576
|
function RemotesBox({ remotes, selectedRemote, onSelect, loading, error, isFocused }) {
|
|
466
577
|
const [highlightedIndex, setHighlightedIndex] = useState2(0);
|
|
467
578
|
useEffect2(() => {
|
|
@@ -485,15 +596,15 @@ function RemotesBox({ remotes, selectedRemote, onSelect, loading, error, isFocus
|
|
|
485
596
|
);
|
|
486
597
|
const title = "[1] Remotes";
|
|
487
598
|
const borderColor = isFocused ? "yellow" : void 0;
|
|
488
|
-
return /* @__PURE__ */
|
|
489
|
-
loading && /* @__PURE__ */
|
|
490
|
-
error && /* @__PURE__ */
|
|
491
|
-
!loading && !error && remotes.length === 0 && /* @__PURE__ */
|
|
599
|
+
return /* @__PURE__ */ jsx4(TitledBox3, { borderStyle: "round", titles: [title], borderColor, flexShrink: 0, children: /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", paddingX: 1, overflow: "hidden", children: [
|
|
600
|
+
loading && /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "Loading..." }),
|
|
601
|
+
error && /* @__PURE__ */ jsx4(Text4, { color: "red", children: error }),
|
|
602
|
+
!loading && !error && remotes.length === 0 && /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "No remotes configured" }),
|
|
492
603
|
!loading && !error && remotes.map((remote, idx) => {
|
|
493
604
|
const isHighlighted = isFocused && idx === highlightedIndex;
|
|
494
605
|
const isSelected = remote.name === selectedRemote;
|
|
495
606
|
const prefix = isHighlighted ? "> " : isSelected ? "\u25CF " : " ";
|
|
496
|
-
return /* @__PURE__ */
|
|
607
|
+
return /* @__PURE__ */ jsxs4(Text4, { color: isSelected ? "green" : void 0, children: [
|
|
497
608
|
prefix,
|
|
498
609
|
remote.name,
|
|
499
610
|
" (",
|
|
@@ -505,7 +616,7 @@ function RemotesBox({ remotes, selectedRemote, onSelect, loading, error, isFocus
|
|
|
505
616
|
}
|
|
506
617
|
|
|
507
618
|
// src/components/github/GitHubView.tsx
|
|
508
|
-
import { jsx as
|
|
619
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
509
620
|
function GitHubView({ isFocused, onKeybindingsChange }) {
|
|
510
621
|
const [isRepo, setIsRepo] = useState3(null);
|
|
511
622
|
const [repoPath, setRepoPath] = useState3(null);
|
|
@@ -658,10 +769,10 @@ function GitHubView({ isFocused, onKeybindingsChange }) {
|
|
|
658
769
|
{ isActive: isFocused }
|
|
659
770
|
);
|
|
660
771
|
if (isRepo === false) {
|
|
661
|
-
return /* @__PURE__ */
|
|
772
|
+
return /* @__PURE__ */ jsx5(TitledBox4, { borderStyle: "round", titles: ["Error"], flexGrow: 1, children: /* @__PURE__ */ jsx5(Text5, { color: "red", children: "Current directory is not a git repository" }) });
|
|
662
773
|
}
|
|
663
|
-
return /* @__PURE__ */
|
|
664
|
-
/* @__PURE__ */
|
|
774
|
+
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", flexGrow: 1, children: [
|
|
775
|
+
/* @__PURE__ */ jsx5(
|
|
665
776
|
RemotesBox,
|
|
666
777
|
{
|
|
667
778
|
remotes,
|
|
@@ -672,7 +783,7 @@ function GitHubView({ isFocused, onKeybindingsChange }) {
|
|
|
672
783
|
isFocused: isFocused && focusedBox === "remotes"
|
|
673
784
|
}
|
|
674
785
|
),
|
|
675
|
-
/* @__PURE__ */
|
|
786
|
+
/* @__PURE__ */ jsx5(
|
|
676
787
|
PullRequestsBox,
|
|
677
788
|
{
|
|
678
789
|
prs,
|
|
@@ -686,7 +797,7 @@ function GitHubView({ isFocused, onKeybindingsChange }) {
|
|
|
686
797
|
isFocused: isFocused && focusedBox === "prs"
|
|
687
798
|
}
|
|
688
799
|
),
|
|
689
|
-
/* @__PURE__ */
|
|
800
|
+
/* @__PURE__ */ jsx5(
|
|
690
801
|
PRDetailsBox,
|
|
691
802
|
{
|
|
692
803
|
pr: prDetails,
|
|
@@ -702,7 +813,7 @@ function GitHubView({ isFocused, onKeybindingsChange }) {
|
|
|
702
813
|
import { useCallback as useCallback2, useEffect as useEffect5, useState as useState7 } from "react";
|
|
703
814
|
import open2 from "open";
|
|
704
815
|
import { TitledBox as TitledBox5 } from "@mishieck/ink-titled-box";
|
|
705
|
-
import { Box as
|
|
816
|
+
import { Box as Box11, Text as Text11, useInput as useInput9 } from "ink";
|
|
706
817
|
|
|
707
818
|
// src/lib/jira/parser.ts
|
|
708
819
|
var TICKET_KEY_PATTERN = /^[A-Z][A-Z0-9]+-\d+$/;
|
|
@@ -929,9 +1040,9 @@ async function applyTransition(auth, ticketKey, transitionId) {
|
|
|
929
1040
|
|
|
930
1041
|
// src/components/jira/ChangeStatusModal.tsx
|
|
931
1042
|
import { useEffect as useEffect4, useState as useState4 } from "react";
|
|
932
|
-
import { Box as
|
|
1043
|
+
import { Box as Box6, Text as Text6, useInput as useInput5 } from "ink";
|
|
933
1044
|
import SelectInput from "ink-select-input";
|
|
934
|
-
import { jsx as
|
|
1045
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
935
1046
|
function ChangeStatusModal({ repoPath, ticketKey, currentStatus, onComplete, onCancel }) {
|
|
936
1047
|
const [transitions, setTransitions] = useState4([]);
|
|
937
1048
|
const [loading, setLoading] = useState4(true);
|
|
@@ -991,23 +1102,23 @@ function ChangeStatusModal({ repoPath, ticketKey, currentStatus, onComplete, onC
|
|
|
991
1102
|
value: t.id
|
|
992
1103
|
}));
|
|
993
1104
|
const initialIndex = Math.max(0, transitions.findIndex((t) => t.to.name === currentStatus));
|
|
994
|
-
return /* @__PURE__ */
|
|
995
|
-
/* @__PURE__ */
|
|
1105
|
+
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, paddingY: 1, children: [
|
|
1106
|
+
/* @__PURE__ */ jsxs6(Text6, { bold: true, color: "yellow", children: [
|
|
996
1107
|
"Change Status: ",
|
|
997
1108
|
ticketKey
|
|
998
1109
|
] }),
|
|
999
|
-
loading && /* @__PURE__ */
|
|
1000
|
-
error && /* @__PURE__ */
|
|
1001
|
-
!loading && !error && transitions.length === 0 && /* @__PURE__ */
|
|
1002
|
-
!loading && !error && transitions.length > 0 && !applying && /* @__PURE__ */
|
|
1003
|
-
applying && /* @__PURE__ */
|
|
1004
|
-
/* @__PURE__ */
|
|
1110
|
+
loading && /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "Loading transitions..." }),
|
|
1111
|
+
error && /* @__PURE__ */ jsx6(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx6(Text6, { color: "red", children: error }) }),
|
|
1112
|
+
!loading && !error && transitions.length === 0 && /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "No available transitions" }),
|
|
1113
|
+
!loading && !error && transitions.length > 0 && !applying && /* @__PURE__ */ jsx6(Box6, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx6(SelectInput, { items, initialIndex, onSelect: handleSelect }) }),
|
|
1114
|
+
applying && /* @__PURE__ */ jsx6(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx6(Text6, { color: "yellow", children: "Updating status..." }) }),
|
|
1115
|
+
/* @__PURE__ */ jsx6(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "Esc to cancel" }) })
|
|
1005
1116
|
] });
|
|
1006
1117
|
}
|
|
1007
1118
|
|
|
1008
1119
|
// src/components/jira/ConfigureJiraSiteModal.tsx
|
|
1009
1120
|
import { useState as useState5 } from "react";
|
|
1010
|
-
import { Box as
|
|
1121
|
+
import { Box as Box7, Text as Text7, useInput as useInput6 } from "ink";
|
|
1011
1122
|
|
|
1012
1123
|
// src/lib/editor.ts
|
|
1013
1124
|
import { spawnSync } from "child_process";
|
|
@@ -1038,7 +1149,7 @@ function openInEditor(content, filename) {
|
|
|
1038
1149
|
}
|
|
1039
1150
|
|
|
1040
1151
|
// src/components/jira/ConfigureJiraSiteModal.tsx
|
|
1041
|
-
import { jsx as
|
|
1152
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1042
1153
|
function ConfigureJiraSiteModal({
|
|
1043
1154
|
initialSiteUrl,
|
|
1044
1155
|
initialEmail,
|
|
@@ -1102,41 +1213,41 @@ function ConfigureJiraSiteModal({
|
|
|
1102
1213
|
const prefix = isSelected ? "> " : " ";
|
|
1103
1214
|
const color = isSelected ? "yellow" : void 0;
|
|
1104
1215
|
const displayValue = isSensitive && value ? "*".repeat(Math.min(value.length, 20)) : value;
|
|
1105
|
-
return /* @__PURE__ */
|
|
1106
|
-
/* @__PURE__ */
|
|
1216
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1217
|
+
/* @__PURE__ */ jsxs7(Text7, { color, bold: isSelected, children: [
|
|
1107
1218
|
prefix,
|
|
1108
1219
|
label
|
|
1109
1220
|
] }),
|
|
1110
|
-
value !== void 0 && /* @__PURE__ */
|
|
1221
|
+
value !== void 0 && /* @__PURE__ */ jsx7(Box7, { marginLeft: 4, children: /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: displayValue || "(empty - press Enter to edit)" }) })
|
|
1111
1222
|
] });
|
|
1112
1223
|
};
|
|
1113
|
-
return /* @__PURE__ */
|
|
1114
|
-
/* @__PURE__ */
|
|
1115
|
-
/* @__PURE__ */
|
|
1116
|
-
/* @__PURE__ */
|
|
1117
|
-
error && /* @__PURE__ */
|
|
1224
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, paddingY: 1, children: [
|
|
1225
|
+
/* @__PURE__ */ jsx7(Text7, { bold: true, color: "cyan", children: "Configure Jira Site" }),
|
|
1226
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "Up/Down to select, Enter to edit, Esc to cancel" }),
|
|
1227
|
+
/* @__PURE__ */ jsx7(Box7, { marginTop: 1 }),
|
|
1228
|
+
error && /* @__PURE__ */ jsx7(Box7, { marginBottom: 1, children: /* @__PURE__ */ jsx7(Text7, { color: "red", children: error }) }),
|
|
1118
1229
|
renderItem("siteUrl", "Site URL (e.g., https://company.atlassian.net)", siteUrl),
|
|
1119
|
-
/* @__PURE__ */
|
|
1230
|
+
/* @__PURE__ */ jsx7(Box7, { marginTop: 1 }),
|
|
1120
1231
|
renderItem("email", "Email", email),
|
|
1121
|
-
/* @__PURE__ */
|
|
1232
|
+
/* @__PURE__ */ jsx7(Box7, { marginTop: 1 }),
|
|
1122
1233
|
renderItem("apiToken", "API Token", apiToken, true),
|
|
1123
|
-
/* @__PURE__ */
|
|
1124
|
-
/* @__PURE__ */
|
|
1234
|
+
/* @__PURE__ */ jsx7(Box7, { marginTop: 1 }),
|
|
1235
|
+
/* @__PURE__ */ jsx7(Box7, { children: /* @__PURE__ */ jsxs7(Text7, { color: selectedItem === "submit" ? "green" : void 0, bold: selectedItem === "submit", children: [
|
|
1125
1236
|
selectedItem === "submit" ? "> " : " ",
|
|
1126
1237
|
canSubmit ? "[Save Configuration]" : "[Fill all fields first]"
|
|
1127
1238
|
] }) }),
|
|
1128
|
-
loading && /* @__PURE__ */
|
|
1129
|
-
/* @__PURE__ */
|
|
1239
|
+
loading && /* @__PURE__ */ jsx7(Box7, { marginTop: 1, children: /* @__PURE__ */ jsx7(Text7, { color: "yellow", children: "Validating credentials..." }) }),
|
|
1240
|
+
/* @__PURE__ */ jsx7(Box7, { marginTop: 1, children: /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "Get your API token from: https://id.atlassian.com/manage-profile/security/api-tokens" }) })
|
|
1130
1241
|
] });
|
|
1131
1242
|
}
|
|
1132
1243
|
|
|
1133
1244
|
// src/components/jira/LinkTicketModal.tsx
|
|
1134
1245
|
import { useState as useState6 } from "react";
|
|
1135
|
-
import { Box as
|
|
1246
|
+
import { Box as Box9, Text as Text9, useInput as useInput8 } from "ink";
|
|
1136
1247
|
|
|
1137
1248
|
// src/components/ui/TextInput.tsx
|
|
1138
|
-
import { Box as
|
|
1139
|
-
import { jsx as
|
|
1249
|
+
import { Box as Box8, Text as Text8, useInput as useInput7 } from "ink";
|
|
1250
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1140
1251
|
function TextInput({ value, onChange, placeholder, isActive, mask }) {
|
|
1141
1252
|
useInput7(
|
|
1142
1253
|
(input, key) => {
|
|
@@ -1157,14 +1268,14 @@ function TextInput({ value, onChange, placeholder, isActive, mask }) {
|
|
|
1157
1268
|
);
|
|
1158
1269
|
const displayValue = mask ? "*".repeat(value.length) : value;
|
|
1159
1270
|
const showPlaceholder = value.length === 0 && placeholder;
|
|
1160
|
-
return /* @__PURE__ */
|
|
1161
|
-
showPlaceholder ? /* @__PURE__ */
|
|
1162
|
-
isActive && /* @__PURE__ */
|
|
1271
|
+
return /* @__PURE__ */ jsx8(Box8, { children: /* @__PURE__ */ jsxs8(Text8, { children: [
|
|
1272
|
+
showPlaceholder ? /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: placeholder }) : /* @__PURE__ */ jsx8(Text8, { children: displayValue }),
|
|
1273
|
+
isActive && /* @__PURE__ */ jsx8(Text8, { backgroundColor: "yellow", children: " " })
|
|
1163
1274
|
] }) });
|
|
1164
1275
|
}
|
|
1165
1276
|
|
|
1166
1277
|
// src/components/jira/LinkTicketModal.tsx
|
|
1167
|
-
import { jsx as
|
|
1278
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1168
1279
|
function LinkTicketModal({ onSubmit, onCancel, loading, error }) {
|
|
1169
1280
|
const [ticketInput, setTicketInput] = useState6("");
|
|
1170
1281
|
const canSubmit = ticketInput.trim().length > 0;
|
|
@@ -1181,14 +1292,14 @@ function LinkTicketModal({ onSubmit, onCancel, loading, error }) {
|
|
|
1181
1292
|
},
|
|
1182
1293
|
{ isActive: !loading }
|
|
1183
1294
|
);
|
|
1184
|
-
return /* @__PURE__ */
|
|
1185
|
-
/* @__PURE__ */
|
|
1186
|
-
/* @__PURE__ */
|
|
1187
|
-
/* @__PURE__ */
|
|
1188
|
-
error && /* @__PURE__ */
|
|
1189
|
-
/* @__PURE__ */
|
|
1190
|
-
/* @__PURE__ */
|
|
1191
|
-
/* @__PURE__ */
|
|
1295
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, paddingY: 1, children: [
|
|
1296
|
+
/* @__PURE__ */ jsx9(Text9, { bold: true, color: "yellow", children: "Link Jira Ticket" }),
|
|
1297
|
+
/* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "Type ticket ID, Enter to submit, Esc to cancel" }),
|
|
1298
|
+
/* @__PURE__ */ jsx9(Box9, { marginTop: 1 }),
|
|
1299
|
+
error && /* @__PURE__ */ jsx9(Box9, { marginBottom: 1, children: /* @__PURE__ */ jsx9(Text9, { color: "red", children: error }) }),
|
|
1300
|
+
/* @__PURE__ */ jsxs9(Box9, { children: [
|
|
1301
|
+
/* @__PURE__ */ jsx9(Text9, { color: "blue", children: "Ticket: " }),
|
|
1302
|
+
/* @__PURE__ */ jsx9(
|
|
1192
1303
|
TextInput,
|
|
1193
1304
|
{
|
|
1194
1305
|
value: ticketInput,
|
|
@@ -1198,23 +1309,23 @@ function LinkTicketModal({ onSubmit, onCancel, loading, error }) {
|
|
|
1198
1309
|
}
|
|
1199
1310
|
)
|
|
1200
1311
|
] }),
|
|
1201
|
-
loading && /* @__PURE__ */
|
|
1202
|
-
/* @__PURE__ */
|
|
1312
|
+
loading && /* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text9, { color: "yellow", children: "Fetching ticket..." }) }),
|
|
1313
|
+
/* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "Examples: PROJ-123 or https://company.atlassian.net/browse/PROJ-123" }) })
|
|
1203
1314
|
] });
|
|
1204
1315
|
}
|
|
1205
1316
|
|
|
1206
1317
|
// src/components/jira/TicketItem.tsx
|
|
1207
|
-
import { Box as
|
|
1208
|
-
import { jsx as
|
|
1318
|
+
import { Box as Box10, Text as Text10 } from "ink";
|
|
1319
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1209
1320
|
function TicketItem({ ticketKey, summary, status, isHighlighted, isSelected }) {
|
|
1210
1321
|
const prefix = isHighlighted ? "> " : isSelected ? "\u25CF " : " ";
|
|
1211
1322
|
const textColor = isSelected ? "green" : void 0;
|
|
1212
|
-
return /* @__PURE__ */
|
|
1323
|
+
return /* @__PURE__ */ jsx10(Box10, { children: /* @__PURE__ */ jsxs10(Text10, { color: textColor, children: [
|
|
1213
1324
|
prefix,
|
|
1214
|
-
/* @__PURE__ */
|
|
1325
|
+
/* @__PURE__ */ jsx10(Text10, { bold: true, color: "blue", children: ticketKey }),
|
|
1215
1326
|
" ",
|
|
1216
1327
|
summary,
|
|
1217
|
-
status && /* @__PURE__ */
|
|
1328
|
+
status && /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
1218
1329
|
" [",
|
|
1219
1330
|
status,
|
|
1220
1331
|
"]"
|
|
@@ -1223,7 +1334,7 @@ function TicketItem({ ticketKey, summary, status, isHighlighted, isSelected }) {
|
|
|
1223
1334
|
}
|
|
1224
1335
|
|
|
1225
1336
|
// src/components/jira/JiraView.tsx
|
|
1226
|
-
import { jsx as
|
|
1337
|
+
import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1227
1338
|
function JiraView({ isFocused, onModalChange, onKeybindingsChange }) {
|
|
1228
1339
|
const [repoPath, setRepoPath] = useState7(null);
|
|
1229
1340
|
const [currentBranch, setCurrentBranch] = useState7(null);
|
|
@@ -1438,12 +1549,12 @@ function JiraView({ isFocused, onModalChange, onKeybindingsChange }) {
|
|
|
1438
1549
|
{ isActive: isFocused && !showConfigureModal && !showLinkModal && !showStatusModal }
|
|
1439
1550
|
);
|
|
1440
1551
|
if (isRepo === false) {
|
|
1441
|
-
return /* @__PURE__ */
|
|
1552
|
+
return /* @__PURE__ */ jsx11(TitledBox5, { borderStyle: "round", titles: ["Jira"], flexShrink: 0, children: /* @__PURE__ */ jsx11(Text11, { color: "red", children: "Not a git repository" }) });
|
|
1442
1553
|
}
|
|
1443
1554
|
if (showConfigureModal) {
|
|
1444
1555
|
const siteUrl = repoPath ? getJiraSiteUrl(repoPath) : void 0;
|
|
1445
1556
|
const creds = repoPath ? getJiraCredentials(repoPath) : { email: null, apiToken: null };
|
|
1446
|
-
return /* @__PURE__ */
|
|
1557
|
+
return /* @__PURE__ */ jsx11(Box11, { flexDirection: "column", flexShrink: 0, children: /* @__PURE__ */ jsx11(
|
|
1447
1558
|
ConfigureJiraSiteModal,
|
|
1448
1559
|
{
|
|
1449
1560
|
initialSiteUrl: siteUrl ?? void 0,
|
|
@@ -1459,7 +1570,7 @@ function JiraView({ isFocused, onModalChange, onKeybindingsChange }) {
|
|
|
1459
1570
|
) });
|
|
1460
1571
|
}
|
|
1461
1572
|
if (showLinkModal) {
|
|
1462
|
-
return /* @__PURE__ */
|
|
1573
|
+
return /* @__PURE__ */ jsx11(Box11, { flexDirection: "column", flexShrink: 0, children: /* @__PURE__ */ jsx11(
|
|
1463
1574
|
LinkTicketModal,
|
|
1464
1575
|
{
|
|
1465
1576
|
onSubmit: handleLinkSubmit,
|
|
@@ -1474,7 +1585,7 @@ function JiraView({ isFocused, onModalChange, onKeybindingsChange }) {
|
|
|
1474
1585
|
}
|
|
1475
1586
|
if (showStatusModal && repoPath && currentBranch && tickets[highlightedIndex]) {
|
|
1476
1587
|
const ticket = tickets[highlightedIndex];
|
|
1477
|
-
return /* @__PURE__ */
|
|
1588
|
+
return /* @__PURE__ */ jsx11(Box11, { flexDirection: "column", flexShrink: 0, children: /* @__PURE__ */ jsx11(
|
|
1478
1589
|
ChangeStatusModal,
|
|
1479
1590
|
{
|
|
1480
1591
|
repoPath,
|
|
@@ -1491,10 +1602,10 @@ function JiraView({ isFocused, onModalChange, onKeybindingsChange }) {
|
|
|
1491
1602
|
}
|
|
1492
1603
|
const title = "[4] Jira";
|
|
1493
1604
|
const borderColor = isFocused ? "yellow" : void 0;
|
|
1494
|
-
return /* @__PURE__ */
|
|
1495
|
-
jiraState === "not_configured" && /* @__PURE__ */
|
|
1496
|
-
jiraState === "no_tickets" && /* @__PURE__ */
|
|
1497
|
-
jiraState === "has_tickets" && tickets.map((ticket, idx) => /* @__PURE__ */
|
|
1605
|
+
return /* @__PURE__ */ jsx11(TitledBox5, { borderStyle: "round", titles: [title], borderColor, flexShrink: 0, children: /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", paddingX: 1, children: [
|
|
1606
|
+
jiraState === "not_configured" && /* @__PURE__ */ jsx11(Text11, { dimColor: true, children: "No Jira site configured" }),
|
|
1607
|
+
jiraState === "no_tickets" && /* @__PURE__ */ jsx11(Text11, { dimColor: true, children: "No tickets linked to this branch" }),
|
|
1608
|
+
jiraState === "has_tickets" && tickets.map((ticket, idx) => /* @__PURE__ */ jsx11(
|
|
1498
1609
|
TicketItem,
|
|
1499
1610
|
{
|
|
1500
1611
|
ticketKey: ticket.key,
|
|
@@ -1508,8 +1619,8 @@ function JiraView({ isFocused, onModalChange, onKeybindingsChange }) {
|
|
|
1508
1619
|
}
|
|
1509
1620
|
|
|
1510
1621
|
// src/components/ui/KeybindingsBar.tsx
|
|
1511
|
-
import { Box as
|
|
1512
|
-
import { jsx as
|
|
1622
|
+
import { Box as Box12, Text as Text12 } from "ink";
|
|
1623
|
+
import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1513
1624
|
var globalBindings = [
|
|
1514
1625
|
{ key: "1-4", label: "Focus" },
|
|
1515
1626
|
{ key: "j/k", label: "Navigate" },
|
|
@@ -1520,14 +1631,14 @@ var modalBindings = [
|
|
|
1520
1631
|
];
|
|
1521
1632
|
function KeybindingsBar({ contextBindings = [], modalOpen = false }) {
|
|
1522
1633
|
const allBindings = modalOpen ? [...contextBindings, ...modalBindings] : [...contextBindings, ...globalBindings];
|
|
1523
|
-
return /* @__PURE__ */
|
|
1524
|
-
/* @__PURE__ */
|
|
1525
|
-
/* @__PURE__ */
|
|
1634
|
+
return /* @__PURE__ */ jsx12(Box12, { flexShrink: 0, paddingX: 1, gap: 2, children: allBindings.map((binding) => /* @__PURE__ */ jsxs12(Box12, { gap: 1, children: [
|
|
1635
|
+
/* @__PURE__ */ jsx12(Text12, { bold: true, color: binding.color ?? "yellow", children: binding.key }),
|
|
1636
|
+
/* @__PURE__ */ jsx12(Text12, { dimColor: true, children: binding.label })
|
|
1526
1637
|
] }, binding.key)) });
|
|
1527
1638
|
}
|
|
1528
1639
|
|
|
1529
1640
|
// src/app.tsx
|
|
1530
|
-
import { jsx as
|
|
1641
|
+
import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1531
1642
|
function App() {
|
|
1532
1643
|
const { exit } = useApp();
|
|
1533
1644
|
const [focusedView, setFocusedView] = useState8("github");
|
|
@@ -1547,15 +1658,15 @@ function App() {
|
|
|
1547
1658
|
},
|
|
1548
1659
|
{ isActive: !modalOpen }
|
|
1549
1660
|
);
|
|
1550
|
-
return /* @__PURE__ */
|
|
1551
|
-
/* @__PURE__ */
|
|
1661
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexGrow: 1, flexDirection: "column", overflow: "hidden", children: [
|
|
1662
|
+
/* @__PURE__ */ jsx13(
|
|
1552
1663
|
GitHubView,
|
|
1553
1664
|
{
|
|
1554
1665
|
isFocused: focusedView === "github",
|
|
1555
1666
|
onKeybindingsChange: focusedView === "github" ? setContextBindings : void 0
|
|
1556
1667
|
}
|
|
1557
1668
|
),
|
|
1558
|
-
/* @__PURE__ */
|
|
1669
|
+
/* @__PURE__ */ jsx13(
|
|
1559
1670
|
JiraView,
|
|
1560
1671
|
{
|
|
1561
1672
|
isFocused: focusedView === "jira",
|
|
@@ -1563,7 +1674,7 @@ function App() {
|
|
|
1563
1674
|
onKeybindingsChange: focusedView === "jira" ? setContextBindings : void 0
|
|
1564
1675
|
}
|
|
1565
1676
|
),
|
|
1566
|
-
/* @__PURE__ */
|
|
1677
|
+
/* @__PURE__ */ jsx13(KeybindingsBar, { contextBindings, modalOpen })
|
|
1567
1678
|
] });
|
|
1568
1679
|
}
|
|
1569
1680
|
|
|
@@ -1571,9 +1682,9 @@ function App() {
|
|
|
1571
1682
|
import { render as inkRender } from "ink";
|
|
1572
1683
|
|
|
1573
1684
|
// src/lib/Screen.tsx
|
|
1574
|
-
import { Box as
|
|
1685
|
+
import { Box as Box14, useStdout } from "ink";
|
|
1575
1686
|
import { useCallback as useCallback3, useEffect as useEffect6, useState as useState9 } from "react";
|
|
1576
|
-
import { jsx as
|
|
1687
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1577
1688
|
function Screen({ children }) {
|
|
1578
1689
|
const { stdout } = useStdout();
|
|
1579
1690
|
const getSize = useCallback3(
|
|
@@ -1588,17 +1699,17 @@ function Screen({ children }) {
|
|
|
1588
1699
|
stdout.off("resize", onResize);
|
|
1589
1700
|
};
|
|
1590
1701
|
}, [stdout, getSize]);
|
|
1591
|
-
return /* @__PURE__ */
|
|
1702
|
+
return /* @__PURE__ */ jsx14(Box14, { height: size.height, width: size.width, children });
|
|
1592
1703
|
}
|
|
1593
1704
|
|
|
1594
1705
|
// src/lib/render.tsx
|
|
1595
|
-
import { jsx as
|
|
1706
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1596
1707
|
var ENTER_ALT_BUFFER = "\x1B[?1049h";
|
|
1597
1708
|
var EXIT_ALT_BUFFER = "\x1B[?1049l";
|
|
1598
1709
|
var CLEAR_SCREEN = "\x1B[2J\x1B[H";
|
|
1599
1710
|
function render(node, options) {
|
|
1600
1711
|
process.stdout.write(ENTER_ALT_BUFFER + CLEAR_SCREEN);
|
|
1601
|
-
const element = /* @__PURE__ */
|
|
1712
|
+
const element = /* @__PURE__ */ jsx15(Screen, { children: node });
|
|
1602
1713
|
const instance = inkRender(element, options);
|
|
1603
1714
|
setImmediate(() => instance.rerender(element));
|
|
1604
1715
|
const cleanup = () => process.stdout.write(EXIT_ALT_BUFFER);
|
|
@@ -1619,7 +1730,7 @@ function render(node, options) {
|
|
|
1619
1730
|
}
|
|
1620
1731
|
|
|
1621
1732
|
// src/cli.tsx
|
|
1622
|
-
import { jsx as
|
|
1733
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
1623
1734
|
meow(
|
|
1624
1735
|
`
|
|
1625
1736
|
Usage
|
|
@@ -1641,4 +1752,4 @@ meow(
|
|
|
1641
1752
|
}
|
|
1642
1753
|
}
|
|
1643
1754
|
);
|
|
1644
|
-
render(/* @__PURE__ */
|
|
1755
|
+
render(/* @__PURE__ */ jsx16(App, {}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clairo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -22,9 +22,12 @@
|
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@mishieck/ink-titled-box": "^0.4.2",
|
|
25
|
+
"cli-table3": "^0.6.5",
|
|
25
26
|
"ink": "^6.6.0",
|
|
27
|
+
"ink-link": "^5.0.0",
|
|
26
28
|
"ink-scroll-view": "^0.3.5",
|
|
27
29
|
"ink-select-input": "^6.2.0",
|
|
30
|
+
"marked": "^17.0.1",
|
|
28
31
|
"meow": "^11.0.0",
|
|
29
32
|
"open": "^11.0.0",
|
|
30
33
|
"react": "^19.2.4"
|