@tomkapa/tayto 0.7.0 → 0.8.1
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/{chunk-5V4TBQ5S.js → chunk-6ZNCVCAS.js} +24 -2
- package/dist/chunk-6ZNCVCAS.js.map +1 -0
- package/dist/index.js +160 -22
- package/dist/index.js.map +1 -1
- package/dist/{tui-NCL4RFFD.js → tui-APMSKU4E.js} +563 -362
- package/dist/tui-APMSKU4E.js.map +1 -0
- package/package.json +2 -2
- package/dist/chunk-5V4TBQ5S.js.map +0 -1
- package/dist/tui-NCL4RFFD.js.map +0 -1
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
APP_VERSION,
|
|
3
4
|
DependencyType,
|
|
4
5
|
TaskLevel,
|
|
5
6
|
TaskStatus,
|
|
6
7
|
TaskType,
|
|
7
8
|
UIDependencyType,
|
|
9
|
+
define_CHANGELOG_ENTRIES_default,
|
|
8
10
|
detectGitRemote,
|
|
11
|
+
isNewerVersion,
|
|
9
12
|
isTerminalStatus,
|
|
10
13
|
logger
|
|
11
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-6ZNCVCAS.js";
|
|
12
15
|
|
|
13
16
|
// src/tui/index.tsx
|
|
14
17
|
import { render } from "ink";
|
|
15
18
|
|
|
16
19
|
// src/tui/components/App.tsx
|
|
17
|
-
import { useReducer, useEffect as
|
|
18
|
-
import { Box as
|
|
20
|
+
import { useReducer, useEffect as useEffect5, useCallback as useCallback2, useMemo as useMemo3, useState as useState8, useRef as useRef5 } from "react";
|
|
21
|
+
import { Box as Box21, Text as Text21, useInput as useInput7, useApp, useStdout as useStdout4 } from "ink";
|
|
19
22
|
|
|
20
23
|
// src/tui/types.ts
|
|
21
24
|
var ViewType = {
|
|
@@ -181,7 +184,10 @@ var initialState = {
|
|
|
181
184
|
editingProject: null,
|
|
182
185
|
isEpicReordering: false,
|
|
183
186
|
epicReorderSnapshot: null,
|
|
184
|
-
detectedGitRemote: null
|
|
187
|
+
detectedGitRemote: null,
|
|
188
|
+
changelogEntries: null,
|
|
189
|
+
changelogIndex: 0,
|
|
190
|
+
changelogDialogOpen: false
|
|
185
191
|
};
|
|
186
192
|
function appReducer(state, action) {
|
|
187
193
|
switch (action.type) {
|
|
@@ -393,11 +399,25 @@ function appReducer(state, action) {
|
|
|
393
399
|
return { ...state, editingProject: action.project };
|
|
394
400
|
case "SET_DETECTED_GIT_REMOTE":
|
|
395
401
|
return { ...state, detectedGitRemote: action.remote };
|
|
402
|
+
case "SET_CHANGELOG":
|
|
403
|
+
return { ...state, changelogEntries: action.entries, changelogIndex: 0 };
|
|
404
|
+
case "CHANGELOG_NAVIGATE": {
|
|
405
|
+
if (!state.changelogEntries) return state;
|
|
406
|
+
const max = Math.max(0, state.changelogEntries.length - 1);
|
|
407
|
+
const newIdx = action.direction === "up" ? Math.max(0, state.changelogIndex - 1) : Math.min(max, state.changelogIndex + 1);
|
|
408
|
+
return { ...state, changelogIndex: newIdx };
|
|
409
|
+
}
|
|
410
|
+
case "DISMISS_CHANGELOG":
|
|
411
|
+
return { ...state, changelogEntries: null, changelogIndex: 0, changelogDialogOpen: false };
|
|
412
|
+
case "OPEN_CHANGELOG_DIALOG":
|
|
413
|
+
return { ...state, changelogDialogOpen: true, changelogIndex: 0 };
|
|
414
|
+
case "CLOSE_CHANGELOG_DIALOG":
|
|
415
|
+
return { ...state, changelogDialogOpen: false };
|
|
396
416
|
}
|
|
397
417
|
}
|
|
398
418
|
|
|
399
419
|
// src/tui/components/Header.tsx
|
|
400
|
-
import { Box as
|
|
420
|
+
import { Box as Box3, Text as Text3 } from "ink";
|
|
401
421
|
|
|
402
422
|
// src/tui/components/Logo.tsx
|
|
403
423
|
import React from "react";
|
|
@@ -432,10 +452,71 @@ var Logo = React.memo(function Logo2() {
|
|
|
432
452
|
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: lines });
|
|
433
453
|
});
|
|
434
454
|
|
|
435
|
-
// src/tui/components/
|
|
455
|
+
// src/tui/components/ChangelogTicker.tsx
|
|
456
|
+
import { useState, useEffect, useMemo } from "react";
|
|
457
|
+
import { Box as Box2, Text as Text2 } from "ink";
|
|
436
458
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
459
|
+
var INTERVAL_MS = 4e3;
|
|
460
|
+
var WIDTH = 98;
|
|
461
|
+
function ChangelogTicker({ entries }) {
|
|
462
|
+
const items = useMemo(
|
|
463
|
+
() => entries.flatMap(
|
|
464
|
+
(entry) => entry.sections.flatMap(
|
|
465
|
+
(section) => section.items.map((item) => ({
|
|
466
|
+
version: entry.version,
|
|
467
|
+
section: section.heading,
|
|
468
|
+
text: item
|
|
469
|
+
}))
|
|
470
|
+
)
|
|
471
|
+
),
|
|
472
|
+
[entries]
|
|
473
|
+
);
|
|
474
|
+
const [index, setIndex] = useState(0);
|
|
475
|
+
useEffect(() => {
|
|
476
|
+
if (items.length <= 1) return;
|
|
477
|
+
const timer = setInterval(() => {
|
|
478
|
+
setIndex((i) => (i + 1) % items.length);
|
|
479
|
+
}, INTERVAL_MS);
|
|
480
|
+
return () => {
|
|
481
|
+
clearInterval(timer);
|
|
482
|
+
};
|
|
483
|
+
}, [items.length]);
|
|
484
|
+
const current = items[index % Math.max(1, items.length)];
|
|
485
|
+
if (!current) return null;
|
|
486
|
+
return /* @__PURE__ */ jsxs(
|
|
487
|
+
Box2,
|
|
488
|
+
{
|
|
489
|
+
borderStyle: "bold",
|
|
490
|
+
borderColor: theme.border,
|
|
491
|
+
paddingX: 2,
|
|
492
|
+
width: WIDTH,
|
|
493
|
+
flexShrink: 0,
|
|
494
|
+
flexDirection: "column",
|
|
495
|
+
children: [
|
|
496
|
+
/* @__PURE__ */ jsxs(Box2, { gap: 1, children: [
|
|
497
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.dialog.label, bold: true, children: `v${current.version}` }),
|
|
498
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.border, children: "\xB7" }),
|
|
499
|
+
/* @__PURE__ */ jsx2(Text2, { color: theme.table.headerFg, children: current.section })
|
|
500
|
+
] }),
|
|
501
|
+
/* @__PURE__ */ jsxs(Box2, { flexDirection: "row", gap: 1, children: [
|
|
502
|
+
/* @__PURE__ */ jsx2(Box2, { flexGrow: 1, children: /* @__PURE__ */ jsx2(Text2, { color: theme.fg, wrap: "truncate", children: current.text }) }),
|
|
503
|
+
/* @__PURE__ */ jsx2(Box2, { flexShrink: 0, children: /* @__PURE__ */ jsx2(Text2, { color: theme.menu.key, bold: true, children: "<W>" }) })
|
|
504
|
+
] })
|
|
505
|
+
]
|
|
506
|
+
}
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// src/tui/components/Header.tsx
|
|
511
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
437
512
|
function getKeyHints(state) {
|
|
438
513
|
const { activeView, isSearchActive, isReordering, isEpicReordering, isAddingDep, focusedPanel } = state;
|
|
514
|
+
if (state.changelogDialogOpen) {
|
|
515
|
+
return [
|
|
516
|
+
{ key: "\u2191/\u2193", desc: "navigate" },
|
|
517
|
+
{ key: "esc", desc: "close" }
|
|
518
|
+
];
|
|
519
|
+
}
|
|
439
520
|
if (isAddingDep) {
|
|
440
521
|
return [
|
|
441
522
|
{ key: "type", desc: "search" },
|
|
@@ -566,40 +647,47 @@ function Header({ state, latestVersion }) {
|
|
|
566
647
|
const hints = getKeyHints(state);
|
|
567
648
|
const hintCols = hints.length <= 7 ? 2 : hints.length <= 12 ? 3 : 4;
|
|
568
649
|
const columns = chunkHints(hints, hintCols);
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
/* @__PURE__ */
|
|
572
|
-
|
|
573
|
-
/* @__PURE__ */
|
|
574
|
-
|
|
575
|
-
/* @__PURE__ */
|
|
650
|
+
const hasTicker = state.changelogEntries !== null;
|
|
651
|
+
return /* @__PURE__ */ jsxs2(Box3, { flexDirection: "row", gap: 1, children: [
|
|
652
|
+
/* @__PURE__ */ jsx3(Box3, { flexShrink: 0, children: /* @__PURE__ */ jsx3(Logo, {}) }),
|
|
653
|
+
/* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", justifyContent: "center", flexShrink: 0, paddingLeft: 1, children: [
|
|
654
|
+
/* @__PURE__ */ jsx3(Text3, { color: theme.logo, bold: true, children: "tayto" }),
|
|
655
|
+
/* @__PURE__ */ jsxs2(Box3, { gap: 1, children: [
|
|
656
|
+
/* @__PURE__ */ jsx3(Text3, { color: theme.fg, children: "Project:" }),
|
|
657
|
+
/* @__PURE__ */ jsx3(Text3, { color: theme.titleCounter, bold: true, children: projectName })
|
|
576
658
|
] }),
|
|
577
|
-
/* @__PURE__ */
|
|
578
|
-
/* @__PURE__ */
|
|
579
|
-
/* @__PURE__ */
|
|
659
|
+
/* @__PURE__ */ jsxs2(Box3, { gap: 1, children: [
|
|
660
|
+
/* @__PURE__ */ jsx3(Text3, { color: theme.fg, children: "Tasks:" }),
|
|
661
|
+
/* @__PURE__ */ jsx3(Text3, { color: theme.titleCounter, bold: true, children: taskCount })
|
|
580
662
|
] }),
|
|
581
|
-
latestVersion && /* @__PURE__ */
|
|
582
|
-
/* @__PURE__ */
|
|
663
|
+
latestVersion && /* @__PURE__ */ jsxs2(Box3, { gap: 1, children: [
|
|
664
|
+
/* @__PURE__ */ jsxs2(Text3, { color: theme.flash.warn, children: [
|
|
583
665
|
"Update ",
|
|
584
666
|
latestVersion
|
|
585
667
|
] }),
|
|
586
|
-
/* @__PURE__ */
|
|
668
|
+
/* @__PURE__ */ jsx3(Text3, { color: theme.fg, children: "\u2014 tayto upgrade" })
|
|
587
669
|
] })
|
|
588
670
|
] }),
|
|
589
|
-
|
|
590
|
-
/* @__PURE__ */
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
">"
|
|
594
|
-
] }),
|
|
595
|
-
/* @__PURE__ */ jsx2(Text2, { color: theme.menu.desc, children: h.desc })
|
|
596
|
-
] }, h.key)) }, col[0]?.key ?? String(ci))) }) })
|
|
671
|
+
hasTicker && state.changelogEntries ? /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
672
|
+
/* @__PURE__ */ jsx3(Box3, { flexGrow: 1, justifyContent: "center", children: /* @__PURE__ */ jsx3(ChangelogTicker, { entries: state.changelogEntries }) }),
|
|
673
|
+
/* @__PURE__ */ jsx3(Box3, { flexShrink: 0, children: /* @__PURE__ */ jsx3(HintGrid, { columns }) })
|
|
674
|
+
] }) : /* @__PURE__ */ jsx3(Box3, { flexGrow: 1, justifyContent: "flex-end", children: /* @__PURE__ */ jsx3(HintGrid, { columns }) })
|
|
597
675
|
] });
|
|
598
676
|
}
|
|
677
|
+
function HintGrid({ columns }) {
|
|
678
|
+
return /* @__PURE__ */ jsx3(Box3, { flexDirection: "row", gap: 2, children: columns.map((col, ci) => /* @__PURE__ */ jsx3(Box3, { flexDirection: "column", children: col.map((h) => /* @__PURE__ */ jsxs2(Box3, { children: [
|
|
679
|
+
/* @__PURE__ */ jsxs2(Text3, { color: theme.menu.key, bold: true, children: [
|
|
680
|
+
"<",
|
|
681
|
+
h.key,
|
|
682
|
+
">"
|
|
683
|
+
] }),
|
|
684
|
+
/* @__PURE__ */ jsx3(Text3, { color: theme.menu.desc, children: h.desc })
|
|
685
|
+
] }, h.key)) }, col[0]?.key ?? String(ci))) });
|
|
686
|
+
}
|
|
599
687
|
|
|
600
688
|
// src/tui/components/Crumbs.tsx
|
|
601
|
-
import { Box as
|
|
602
|
-
import { jsx as
|
|
689
|
+
import { Box as Box4, Text as Text4 } from "ink";
|
|
690
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
603
691
|
var VIEW_LABELS = {
|
|
604
692
|
"task-list": "tasks",
|
|
605
693
|
"task-detail": "detail",
|
|
@@ -609,11 +697,11 @@ var VIEW_LABELS = {
|
|
|
609
697
|
help: "help"
|
|
610
698
|
};
|
|
611
699
|
function Crumbs({ breadcrumbs }) {
|
|
612
|
-
return /* @__PURE__ */
|
|
700
|
+
return /* @__PURE__ */ jsx4(Box4, { flexDirection: "row", gap: 0, width: "100%", children: breadcrumbs.map((crumb, i) => {
|
|
613
701
|
const isActive = i === breadcrumbs.length - 1;
|
|
614
702
|
const label = ` ${VIEW_LABELS[crumb] ?? crumb} `;
|
|
615
|
-
return /* @__PURE__ */
|
|
616
|
-
|
|
703
|
+
return /* @__PURE__ */ jsx4(
|
|
704
|
+
Text4,
|
|
617
705
|
{
|
|
618
706
|
color: theme.crumb.fg,
|
|
619
707
|
backgroundColor: isActive ? theme.crumb.activeBg : theme.crumb.bg,
|
|
@@ -626,20 +714,20 @@ function Crumbs({ breadcrumbs }) {
|
|
|
626
714
|
}
|
|
627
715
|
|
|
628
716
|
// src/tui/components/FlashMessage.tsx
|
|
629
|
-
import { Box as
|
|
630
|
-
import { jsx as
|
|
717
|
+
import { Box as Box5, Text as Text5 } from "ink";
|
|
718
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
631
719
|
var LEVEL_COLOR = {
|
|
632
720
|
info: theme.flash.info,
|
|
633
721
|
warn: theme.flash.warn,
|
|
634
722
|
error: theme.flash.error
|
|
635
723
|
};
|
|
636
724
|
function FlashMessage({ message, level }) {
|
|
637
|
-
return /* @__PURE__ */
|
|
725
|
+
return /* @__PURE__ */ jsx5(Box5, { justifyContent: "center", width: "100%", children: /* @__PURE__ */ jsx5(Text5, { color: LEVEL_COLOR[level], bold: level === "error", children: message }) });
|
|
638
726
|
}
|
|
639
727
|
|
|
640
728
|
// src/tui/components/TaskList.tsx
|
|
641
|
-
import { Box as
|
|
642
|
-
import { jsx as
|
|
729
|
+
import { Box as Box6, Text as Text6 } from "ink";
|
|
730
|
+
import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
643
731
|
var COL = {
|
|
644
732
|
rank: 5,
|
|
645
733
|
type: 12,
|
|
@@ -667,50 +755,50 @@ function TaskList({
|
|
|
667
755
|
if (filter.type) filterParts.push(`type:${filter.type}`);
|
|
668
756
|
if (filter.search) filterParts.push(filter.search);
|
|
669
757
|
const filterText = filterParts.length > 0 ? filterParts.join(" ") : "";
|
|
670
|
-
return /* @__PURE__ */
|
|
671
|
-
|
|
758
|
+
return /* @__PURE__ */ jsxs3(
|
|
759
|
+
Box6,
|
|
672
760
|
{
|
|
673
761
|
flexDirection: "column",
|
|
674
762
|
flexGrow: 1,
|
|
675
763
|
borderStyle: "bold",
|
|
676
764
|
borderColor: isFocused ? theme.borderFocus : theme.border,
|
|
677
765
|
children: [
|
|
678
|
-
/* @__PURE__ */
|
|
679
|
-
/* @__PURE__ */
|
|
766
|
+
/* @__PURE__ */ jsxs3(Box6, { children: [
|
|
767
|
+
/* @__PURE__ */ jsxs3(Text6, { color: theme.title, bold: true, children: [
|
|
680
768
|
" ",
|
|
681
769
|
"tasks"
|
|
682
770
|
] }),
|
|
683
|
-
/* @__PURE__ */
|
|
684
|
-
/* @__PURE__ */
|
|
685
|
-
/* @__PURE__ */
|
|
686
|
-
/* @__PURE__ */
|
|
771
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.fg, children: "(" }),
|
|
772
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.titleHighlight, bold: true, children: activeProjectName }),
|
|
773
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.fg, children: ")" }),
|
|
774
|
+
/* @__PURE__ */ jsxs3(Text6, { color: theme.titleCounter, bold: true, children: [
|
|
687
775
|
"[",
|
|
688
776
|
tasks.length,
|
|
689
777
|
"]"
|
|
690
778
|
] }),
|
|
691
|
-
isReordering && /* @__PURE__ */
|
|
779
|
+
isReordering && /* @__PURE__ */ jsxs3(Text6, { color: theme.flash.warn, bold: true, children: [
|
|
692
780
|
" ",
|
|
693
781
|
"REORDER"
|
|
694
782
|
] }),
|
|
695
|
-
epicFilterActive && /* @__PURE__ */
|
|
696
|
-
filterText && /* @__PURE__ */
|
|
783
|
+
epicFilterActive && /* @__PURE__ */ jsx6(Text6, { color: theme.titleHighlight, children: " [epic]" }),
|
|
784
|
+
filterText && /* @__PURE__ */ jsxs3(Text6, { color: theme.titleFilter, children: [
|
|
697
785
|
" /",
|
|
698
786
|
filterText
|
|
699
787
|
] })
|
|
700
788
|
] }),
|
|
701
|
-
isSearchActive && /* @__PURE__ */
|
|
702
|
-
/* @__PURE__ */
|
|
703
|
-
/* @__PURE__ */
|
|
704
|
-
/* @__PURE__ */
|
|
789
|
+
isSearchActive && /* @__PURE__ */ jsxs3(Box6, { borderStyle: "round", borderColor: theme.prompt, paddingX: 1, children: [
|
|
790
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.prompt, children: "/" }),
|
|
791
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.prompt, children: searchQuery }),
|
|
792
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.promptSuggest, children: "_" })
|
|
705
793
|
] }),
|
|
706
|
-
/* @__PURE__ */
|
|
707
|
-
/* @__PURE__ */
|
|
708
|
-
/* @__PURE__ */
|
|
709
|
-
/* @__PURE__ */
|
|
710
|
-
/* @__PURE__ */
|
|
711
|
-
/* @__PURE__ */
|
|
794
|
+
/* @__PURE__ */ jsxs3(Box6, { children: [
|
|
795
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.table.headerFg, bold: true, children: " " }),
|
|
796
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.table.headerFg, bold: true, children: "#".padEnd(COL.rank) }),
|
|
797
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.table.headerFg, bold: true, children: "TYPE".padEnd(COL.type) }),
|
|
798
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.table.headerFg, bold: true, children: "STATUS".padEnd(COL.status) }),
|
|
799
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.table.headerFg, bold: true, children: "NAME" })
|
|
712
800
|
] }),
|
|
713
|
-
/* @__PURE__ */
|
|
801
|
+
/* @__PURE__ */ jsx6(Box6, { flexDirection: "column", flexGrow: 1, overflowY: "hidden", children: tasks.length === 0 ? /* @__PURE__ */ jsx6(Box6, { paddingX: 2, paddingY: 1, children: /* @__PURE__ */ jsx6(Text6, { color: theme.fg, children: "No tasks found. Press 'c' to create one." }) }) : visibleTasks.map((task, i) => {
|
|
714
802
|
const actualIndex = viewStart + i;
|
|
715
803
|
const isSelected = actualIndex === selectedIndex;
|
|
716
804
|
const isNonTerminalBlocker = nonTerminalBlockerIds.has(task.id);
|
|
@@ -720,7 +808,7 @@ function TaskList({
|
|
|
720
808
|
const depMarker = isNonTerminalBlocker ? "\u25B2 " : isNonTerminalDependent ? "\u25BC " : " ";
|
|
721
809
|
if (isSelected) {
|
|
722
810
|
const cursorBg = isReordering ? theme.flash.warn : isSelectedBlocked ? theme.table.blockedCursorBg : theme.table.cursorBg;
|
|
723
|
-
return /* @__PURE__ */
|
|
811
|
+
return /* @__PURE__ */ jsx6(Box6, { children: /* @__PURE__ */ jsxs3(Text6, { backgroundColor: cursorBg, color: theme.table.cursorFg, bold: true, children: [
|
|
724
812
|
isReordering ? "~ " : "> ",
|
|
725
813
|
rowNum.padEnd(COL.rank),
|
|
726
814
|
task.type.padEnd(COL.type),
|
|
@@ -729,7 +817,7 @@ function TaskList({
|
|
|
729
817
|
] }) }, task.id);
|
|
730
818
|
}
|
|
731
819
|
if (isNonTerminalBlocker || isNonTerminalDependent) {
|
|
732
|
-
return /* @__PURE__ */
|
|
820
|
+
return /* @__PURE__ */ jsx6(Box6, { children: /* @__PURE__ */ jsxs3(Text6, { backgroundColor: theme.table.depHighlightBg, color: theme.table.fg, bold: true, children: [
|
|
733
821
|
depMarker,
|
|
734
822
|
rowNum.padEnd(COL.rank),
|
|
735
823
|
task.type.padEnd(COL.type),
|
|
@@ -737,15 +825,15 @@ function TaskList({
|
|
|
737
825
|
task.name
|
|
738
826
|
] }) }, task.id);
|
|
739
827
|
}
|
|
740
|
-
return /* @__PURE__ */
|
|
741
|
-
/* @__PURE__ */
|
|
742
|
-
/* @__PURE__ */
|
|
743
|
-
/* @__PURE__ */
|
|
744
|
-
/* @__PURE__ */
|
|
745
|
-
/* @__PURE__ */
|
|
828
|
+
return /* @__PURE__ */ jsxs3(Box6, { children: [
|
|
829
|
+
/* @__PURE__ */ jsx6(Text6, { children: " " }),
|
|
830
|
+
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: rowNum.padEnd(COL.rank) }),
|
|
831
|
+
/* @__PURE__ */ jsx6(Text6, { color: TYPE_COLOR[task.type] ?? rowColor, children: task.type.padEnd(COL.type) }),
|
|
832
|
+
/* @__PURE__ */ jsx6(Text6, { color: STATUS_COLOR[task.status] ?? rowColor, children: task.status.padEnd(COL.status) }),
|
|
833
|
+
/* @__PURE__ */ jsx6(Text6, { color: rowColor, children: task.name })
|
|
746
834
|
] }, task.id);
|
|
747
835
|
}) }),
|
|
748
|
-
tasks.length > PAGE_SIZE && /* @__PURE__ */
|
|
836
|
+
tasks.length > PAGE_SIZE && /* @__PURE__ */ jsx6(Box6, { justifyContent: "flex-end", paddingRight: 1, children: /* @__PURE__ */ jsxs3(Text6, { dimColor: true, children: [
|
|
749
837
|
"[",
|
|
750
838
|
viewStart + 1,
|
|
751
839
|
"-",
|
|
@@ -760,12 +848,12 @@ function TaskList({
|
|
|
760
848
|
}
|
|
761
849
|
|
|
762
850
|
// src/tui/components/TaskDetail.tsx
|
|
763
|
-
import { useMemo } from "react";
|
|
764
|
-
import { Box as
|
|
851
|
+
import { useMemo as useMemo2 } from "react";
|
|
852
|
+
import { Box as Box8, Text as Text8, useStdout } from "ink";
|
|
765
853
|
import chalk2 from "chalk";
|
|
766
854
|
|
|
767
855
|
// src/tui/components/Markdown.tsx
|
|
768
|
-
import { Text as
|
|
856
|
+
import { Text as Text7, Box as Box7 } from "ink";
|
|
769
857
|
import { Marked } from "marked";
|
|
770
858
|
import { markedTerminal } from "marked-terminal";
|
|
771
859
|
import chalk from "chalk";
|
|
@@ -801,7 +889,7 @@ mermaid.initialize({ startOnLoad: true, theme: 'dark' });
|
|
|
801
889
|
}
|
|
802
890
|
|
|
803
891
|
// src/tui/components/Markdown.tsx
|
|
804
|
-
import { jsx as
|
|
892
|
+
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
805
893
|
function extractMermaidBlocks(content) {
|
|
806
894
|
const lexer = new Marked();
|
|
807
895
|
const tokens = lexer.lexer(content);
|
|
@@ -862,12 +950,12 @@ function renderMarkdown(content) {
|
|
|
862
950
|
function MermaidHint({ content }) {
|
|
863
951
|
const blocks = extractMermaidBlocks(content);
|
|
864
952
|
if (blocks.length === 0) return null;
|
|
865
|
-
return /* @__PURE__ */
|
|
866
|
-
/* @__PURE__ */
|
|
953
|
+
return /* @__PURE__ */ jsxs4(Box7, { children: [
|
|
954
|
+
/* @__PURE__ */ jsxs4(Text7, { color: theme.menu.key, bold: true, children: [
|
|
867
955
|
"<m>",
|
|
868
956
|
" "
|
|
869
957
|
] }),
|
|
870
|
-
/* @__PURE__ */
|
|
958
|
+
/* @__PURE__ */ jsxs4(Text7, { dimColor: true, children: [
|
|
871
959
|
"Open ",
|
|
872
960
|
blocks.length,
|
|
873
961
|
" mermaid diagram",
|
|
@@ -885,7 +973,7 @@ function openAllMermaidDiagrams(content) {
|
|
|
885
973
|
}
|
|
886
974
|
|
|
887
975
|
// src/tui/components/TaskDetail.tsx
|
|
888
|
-
import { jsx as
|
|
976
|
+
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
889
977
|
var PAD = " ";
|
|
890
978
|
function field(label, value) {
|
|
891
979
|
return PAD + chalk2.hex(theme.yaml.key).bold(label) + chalk2.hex(theme.yaml.colon)(": ") + chalk2.hex(theme.yaml.value)(value);
|
|
@@ -961,44 +1049,44 @@ function TaskDetail({
|
|
|
961
1049
|
const allText = `${task.description}
|
|
962
1050
|
${task.technicalNotes}
|
|
963
1051
|
${task.additionalRequirements}`;
|
|
964
|
-
const contentLines =
|
|
1052
|
+
const contentLines = useMemo2(
|
|
965
1053
|
() => buildContentLines(task, blockers, dependents, related, duplicates),
|
|
966
1054
|
[task, blockers, dependents, related, duplicates]
|
|
967
1055
|
);
|
|
968
1056
|
const viewportHeight = Math.max(1, (stdout.rows > 0 ? stdout.rows : 24) - CHROME_LINES);
|
|
969
1057
|
const visibleLines = contentLines.slice(scrollOffset, scrollOffset + viewportHeight);
|
|
970
|
-
return /* @__PURE__ */
|
|
971
|
-
|
|
1058
|
+
return /* @__PURE__ */ jsxs5(
|
|
1059
|
+
Box8,
|
|
972
1060
|
{
|
|
973
1061
|
flexDirection: "column",
|
|
974
1062
|
flexGrow: 1,
|
|
975
1063
|
borderStyle: "bold",
|
|
976
1064
|
borderColor: isFocused ? theme.borderFocus : theme.border,
|
|
977
1065
|
children: [
|
|
978
|
-
/* @__PURE__ */
|
|
979
|
-
/* @__PURE__ */
|
|
1066
|
+
/* @__PURE__ */ jsxs5(Box8, { gap: 0, children: [
|
|
1067
|
+
/* @__PURE__ */ jsxs5(Text8, { color: theme.title, bold: true, children: [
|
|
980
1068
|
" ",
|
|
981
1069
|
"detail"
|
|
982
1070
|
] }),
|
|
983
|
-
/* @__PURE__ */
|
|
984
|
-
/* @__PURE__ */
|
|
985
|
-
/* @__PURE__ */
|
|
986
|
-
scrollOffset > 0 && /* @__PURE__ */
|
|
1071
|
+
/* @__PURE__ */ jsx8(Text8, { color: theme.fg, children: "(" }),
|
|
1072
|
+
/* @__PURE__ */ jsx8(Text8, { color: theme.titleHighlight, bold: true, children: task.name }),
|
|
1073
|
+
/* @__PURE__ */ jsx8(Text8, { color: theme.fg, children: ")" }),
|
|
1074
|
+
scrollOffset > 0 && /* @__PURE__ */ jsxs5(Text8, { dimColor: true, children: [
|
|
987
1075
|
" \u2191",
|
|
988
1076
|
scrollOffset
|
|
989
1077
|
] })
|
|
990
1078
|
] }),
|
|
991
|
-
/* @__PURE__ */
|
|
992
|
-
/* @__PURE__ */
|
|
993
|
-
/* @__PURE__ */
|
|
1079
|
+
/* @__PURE__ */ jsx8(Text8, { children: visibleLines.join("\n") }),
|
|
1080
|
+
/* @__PURE__ */ jsx8(Box8, { flexGrow: 1 }),
|
|
1081
|
+
/* @__PURE__ */ jsx8(Box8, { paddingX: 1, children: /* @__PURE__ */ jsx8(MermaidHint, { content: allText }) })
|
|
994
1082
|
]
|
|
995
1083
|
}
|
|
996
1084
|
);
|
|
997
1085
|
}
|
|
998
1086
|
|
|
999
1087
|
// src/tui/components/TaskForm.tsx
|
|
1000
|
-
import { useState as
|
|
1001
|
-
import { Box as
|
|
1088
|
+
import { useState as useState3, useCallback, useEffect as useEffect2, useRef } from "react";
|
|
1089
|
+
import { Box as Box10, Text as Text10, useInput as useInput2, useStdin } from "ink";
|
|
1002
1090
|
|
|
1003
1091
|
// src/tui/editor.ts
|
|
1004
1092
|
import { writeFileSync as writeFileSync2, readFileSync, unlinkSync, mkdtempSync as mkdtempSync2 } from "fs";
|
|
@@ -1036,9 +1124,9 @@ function openInEditor(content, filename, options) {
|
|
|
1036
1124
|
}
|
|
1037
1125
|
|
|
1038
1126
|
// src/tui/components/TaskPicker.tsx
|
|
1039
|
-
import { useState } from "react";
|
|
1040
|
-
import { Box as
|
|
1041
|
-
import { Fragment, jsx as
|
|
1127
|
+
import { useState as useState2 } from "react";
|
|
1128
|
+
import { Box as Box9, Text as Text9, useInput, useStdout as useStdout2 } from "ink";
|
|
1129
|
+
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1042
1130
|
var DEP_TYPE_VALUES = Object.values(UIDependencyType);
|
|
1043
1131
|
var DEP_TYPE_COLOR = {
|
|
1044
1132
|
[DependencyType.Blocks]: theme.status.error,
|
|
@@ -1050,10 +1138,10 @@ function TaskPicker({ tasks, excludeIds, initialSelection, onConfirm, onCancel }
|
|
|
1050
1138
|
const { stdout } = useStdout2();
|
|
1051
1139
|
const termHeight = stdout.rows > 0 ? stdout.rows : 24;
|
|
1052
1140
|
const maxVisible = Math.max(3, termHeight - 12);
|
|
1053
|
-
const [searchQuery, setSearchQuery] =
|
|
1054
|
-
const [isSearching, setIsSearching] =
|
|
1055
|
-
const [cursorIndex, setCursorIndex] =
|
|
1056
|
-
const [selected, setSelected] =
|
|
1141
|
+
const [searchQuery, setSearchQuery] = useState2("");
|
|
1142
|
+
const [isSearching, setIsSearching] = useState2(false);
|
|
1143
|
+
const [cursorIndex, setCursorIndex] = useState2(0);
|
|
1144
|
+
const [selected, setSelected] = useState2(() => {
|
|
1057
1145
|
const map = /* @__PURE__ */ new Map();
|
|
1058
1146
|
if (initialSelection) {
|
|
1059
1147
|
for (const dep of initialSelection) {
|
|
@@ -1152,28 +1240,28 @@ function TaskPicker({ tasks, excludeIds, initialSelection, onConfirm, onCancel }
|
|
|
1152
1240
|
return;
|
|
1153
1241
|
}
|
|
1154
1242
|
});
|
|
1155
|
-
return /* @__PURE__ */
|
|
1156
|
-
/* @__PURE__ */
|
|
1157
|
-
/* @__PURE__ */
|
|
1243
|
+
return /* @__PURE__ */ jsxs6(Box9, { flexDirection: "column", borderStyle: "bold", borderColor: theme.borderFocus, flexGrow: 1, children: [
|
|
1244
|
+
/* @__PURE__ */ jsxs6(Box9, { gap: 0, children: [
|
|
1245
|
+
/* @__PURE__ */ jsxs6(Text9, { color: theme.title, bold: true, children: [
|
|
1158
1246
|
" ",
|
|
1159
1247
|
"select dependencies"
|
|
1160
1248
|
] }),
|
|
1161
|
-
/* @__PURE__ */
|
|
1249
|
+
/* @__PURE__ */ jsxs6(Text9, { color: theme.titleCounter, bold: true, children: [
|
|
1162
1250
|
" ",
|
|
1163
1251
|
"[",
|
|
1164
1252
|
selected.size,
|
|
1165
1253
|
" selected]"
|
|
1166
1254
|
] })
|
|
1167
1255
|
] }),
|
|
1168
|
-
isSearching ? /* @__PURE__ */
|
|
1169
|
-
/* @__PURE__ */
|
|
1170
|
-
/* @__PURE__ */
|
|
1171
|
-
/* @__PURE__ */
|
|
1172
|
-
] }) : searchQuery ? /* @__PURE__ */
|
|
1256
|
+
isSearching ? /* @__PURE__ */ jsxs6(Box9, { borderStyle: "round", borderColor: theme.prompt, paddingX: 1, children: [
|
|
1257
|
+
/* @__PURE__ */ jsx9(Text9, { color: theme.prompt, children: "/" }),
|
|
1258
|
+
/* @__PURE__ */ jsx9(Text9, { color: theme.prompt, children: searchQuery }),
|
|
1259
|
+
/* @__PURE__ */ jsx9(Text9, { color: theme.promptSuggest, children: "_" })
|
|
1260
|
+
] }) : searchQuery ? /* @__PURE__ */ jsx9(Box9, { paddingX: 1, children: /* @__PURE__ */ jsxs6(Text9, { color: theme.titleFilter, children: [
|
|
1173
1261
|
"/",
|
|
1174
1262
|
searchQuery
|
|
1175
1263
|
] }) }) : null,
|
|
1176
|
-
/* @__PURE__ */
|
|
1264
|
+
/* @__PURE__ */ jsx9(Box9, { paddingX: 1, children: /* @__PURE__ */ jsxs6(Text9, { color: theme.table.headerFg, bold: true, children: [
|
|
1177
1265
|
" ",
|
|
1178
1266
|
"SEL".padEnd(5),
|
|
1179
1267
|
"ID".padEnd(14),
|
|
@@ -1181,7 +1269,7 @@ function TaskPicker({ tasks, excludeIds, initialSelection, onConfirm, onCancel }
|
|
|
1181
1269
|
"STATUS".padEnd(14),
|
|
1182
1270
|
"NAME"
|
|
1183
1271
|
] }) }),
|
|
1184
|
-
available.length === 0 ? /* @__PURE__ */
|
|
1272
|
+
available.length === 0 ? /* @__PURE__ */ jsx9(Box9, { paddingX: 2, paddingY: 1, children: /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "No tasks match the filter" }) }) : visible.map((task, i) => {
|
|
1185
1273
|
const actualIndex = viewStart + i;
|
|
1186
1274
|
const isCursor = actualIndex === cursorIndex;
|
|
1187
1275
|
const entry = selected.get(task.id);
|
|
@@ -1189,24 +1277,24 @@ function TaskPicker({ tasks, excludeIds, initialSelection, onConfirm, onCancel }
|
|
|
1189
1277
|
const checkMark = isChecked ? "[x]" : "[ ]";
|
|
1190
1278
|
const depType = entry ? DEP_TYPE_LABEL[entry.type] ?? entry.type : "";
|
|
1191
1279
|
const depColor = entry ? DEP_TYPE_COLOR[entry.type] ?? theme.table.fg : theme.table.fg;
|
|
1192
|
-
return /* @__PURE__ */
|
|
1280
|
+
return /* @__PURE__ */ jsx9(Box9, { paddingX: 1, children: isCursor ? /* @__PURE__ */ jsxs6(Text9, { backgroundColor: theme.table.cursorBg, color: theme.table.cursorFg, bold: true, children: [
|
|
1193
1281
|
"> ",
|
|
1194
1282
|
checkMark.padEnd(5),
|
|
1195
1283
|
task.id.padEnd(14),
|
|
1196
1284
|
depType.padEnd(12),
|
|
1197
1285
|
task.status.padEnd(14),
|
|
1198
1286
|
task.name
|
|
1199
|
-
] }) : /* @__PURE__ */
|
|
1200
|
-
/* @__PURE__ */
|
|
1201
|
-
/* @__PURE__ */
|
|
1202
|
-
/* @__PURE__ */
|
|
1203
|
-
/* @__PURE__ */
|
|
1204
|
-
/* @__PURE__ */
|
|
1205
|
-
/* @__PURE__ */
|
|
1287
|
+
] }) : /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
1288
|
+
/* @__PURE__ */ jsx9(Text9, { children: " " }),
|
|
1289
|
+
/* @__PURE__ */ jsx9(Text9, { color: isChecked ? theme.status.added : theme.table.fg, children: checkMark.padEnd(5) }),
|
|
1290
|
+
/* @__PURE__ */ jsx9(Text9, { color: theme.yaml.value, children: task.id.padEnd(14) }),
|
|
1291
|
+
/* @__PURE__ */ jsx9(Text9, { color: depColor, children: depType.padEnd(12) }),
|
|
1292
|
+
/* @__PURE__ */ jsx9(Text9, { color: theme.status.completed, children: task.status.padEnd(14) }),
|
|
1293
|
+
/* @__PURE__ */ jsx9(Text9, { color: theme.table.fg, children: task.name })
|
|
1206
1294
|
] }) }, task.id);
|
|
1207
1295
|
}),
|
|
1208
|
-
/* @__PURE__ */
|
|
1209
|
-
available.length > maxVisible && /* @__PURE__ */
|
|
1296
|
+
/* @__PURE__ */ jsx9(Box9, { flexGrow: 1 }),
|
|
1297
|
+
available.length > maxVisible && /* @__PURE__ */ jsx9(Box9, { justifyContent: "flex-end", paddingRight: 1, children: /* @__PURE__ */ jsxs6(Text9, { dimColor: true, children: [
|
|
1210
1298
|
"[",
|
|
1211
1299
|
viewStart + 1,
|
|
1212
1300
|
"-",
|
|
@@ -1215,11 +1303,11 @@ function TaskPicker({ tasks, excludeIds, initialSelection, onConfirm, onCancel }
|
|
|
1215
1303
|
available.length,
|
|
1216
1304
|
"]"
|
|
1217
1305
|
] }) }),
|
|
1218
|
-
selected.size > 0 && /* @__PURE__ */
|
|
1219
|
-
/* @__PURE__ */
|
|
1220
|
-
/* @__PURE__ */
|
|
1306
|
+
selected.size > 0 && /* @__PURE__ */ jsxs6(Box9, { paddingX: 1, flexDirection: "column", children: [
|
|
1307
|
+
/* @__PURE__ */ jsx9(Text9, { color: theme.table.headerFg, bold: true, children: "Selected:" }),
|
|
1308
|
+
/* @__PURE__ */ jsx9(Box9, { children: /* @__PURE__ */ jsx9(Text9, { children: Array.from(selected.values()).map((d) => `${d.id} (${DEP_TYPE_LABEL[d.type] ?? d.type})`).join(", ") }) })
|
|
1221
1309
|
] }),
|
|
1222
|
-
/* @__PURE__ */
|
|
1310
|
+
/* @__PURE__ */ jsx9(Box9, { paddingX: 1, children: /* @__PURE__ */ jsxs6(Text9, { dimColor: true, children: [
|
|
1223
1311
|
"space/t: select & cycle type (blocks ",
|
|
1224
1312
|
"->",
|
|
1225
1313
|
" relates-to ",
|
|
@@ -1235,7 +1323,7 @@ function TaskPicker({ tasks, excludeIds, initialSelection, onConfirm, onCancel }
|
|
|
1235
1323
|
}
|
|
1236
1324
|
|
|
1237
1325
|
// src/tui/components/TaskForm.tsx
|
|
1238
|
-
import { Fragment as
|
|
1326
|
+
import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1239
1327
|
var FIELDS = [
|
|
1240
1328
|
{ label: "Name", key: "name", type: "inline" },
|
|
1241
1329
|
{ label: "Type", key: "type", type: "select", options: TYPE_VALUES },
|
|
@@ -1256,8 +1344,8 @@ var FIELDS = [
|
|
|
1256
1344
|
}
|
|
1257
1345
|
];
|
|
1258
1346
|
function TaskForm({ editingTask, allTasks, initialDeps, onSave, onCancel }) {
|
|
1259
|
-
const [focusIndex, setFocusIndex] =
|
|
1260
|
-
const [values, setValues] =
|
|
1347
|
+
const [focusIndex, setFocusIndex] = useState3(0);
|
|
1348
|
+
const [values, setValues] = useState3({
|
|
1261
1349
|
name: editingTask?.name ?? "",
|
|
1262
1350
|
type: editingTask?.type ?? TaskType.Story,
|
|
1263
1351
|
status: editingTask?.status ?? TaskStatus.Backlog,
|
|
@@ -1265,14 +1353,14 @@ function TaskForm({ editingTask, allTasks, initialDeps, onSave, onCancel }) {
|
|
|
1265
1353
|
technicalNotes: editingTask?.technicalNotes ?? "",
|
|
1266
1354
|
additionalRequirements: editingTask?.additionalRequirements ?? ""
|
|
1267
1355
|
});
|
|
1268
|
-
const [cursorPos, setCursorPos] =
|
|
1356
|
+
const [cursorPos, setCursorPos] = useState3(() => (editingTask?.name ?? "").length);
|
|
1269
1357
|
const cursorRef = useRef(cursorPos);
|
|
1270
1358
|
cursorRef.current = cursorPos;
|
|
1271
|
-
const [editorActive, setEditorActive] =
|
|
1272
|
-
const [pickerActive, setPickerActive] =
|
|
1273
|
-
const [pickedDeps, setPickedDeps] =
|
|
1359
|
+
const [editorActive, setEditorActive] = useState3(false);
|
|
1360
|
+
const [pickerActive, setPickerActive] = useState3(false);
|
|
1361
|
+
const [pickedDeps, setPickedDeps] = useState3(initialDeps ?? []);
|
|
1274
1362
|
const { setRawMode } = useStdin();
|
|
1275
|
-
|
|
1363
|
+
useEffect2(() => {
|
|
1276
1364
|
const field2 = FIELDS[focusIndex];
|
|
1277
1365
|
if (field2?.type === "inline") {
|
|
1278
1366
|
const pos = values[field2.key]?.length ?? 0;
|
|
@@ -1402,7 +1490,7 @@ function TaskForm({ editingTask, allTasks, initialDeps, onSave, onCancel }) {
|
|
|
1402
1490
|
);
|
|
1403
1491
|
if (pickerActive) {
|
|
1404
1492
|
const pickerExclude = editingTask ? { excludeIds: /* @__PURE__ */ new Set([editingTask.id]) } : {};
|
|
1405
|
-
return /* @__PURE__ */
|
|
1493
|
+
return /* @__PURE__ */ jsx10(
|
|
1406
1494
|
TaskPicker,
|
|
1407
1495
|
{
|
|
1408
1496
|
tasks: allTasks,
|
|
@@ -1415,53 +1503,53 @@ function TaskForm({ editingTask, allTasks, initialDeps, onSave, onCancel }) {
|
|
|
1415
1503
|
}
|
|
1416
1504
|
const isEdit = editingTask !== null;
|
|
1417
1505
|
const depSummary = pickedDeps.length > 0 ? pickedDeps.map((d) => `${d.id} (${DEP_TYPE_LABEL[d.type] ?? d.type})`).join(", ") : "";
|
|
1418
|
-
return /* @__PURE__ */
|
|
1419
|
-
/* @__PURE__ */
|
|
1506
|
+
return /* @__PURE__ */ jsxs7(Box10, { flexDirection: "column", flexGrow: 1, borderStyle: "bold", borderColor: theme.borderFocus, children: [
|
|
1507
|
+
/* @__PURE__ */ jsx10(Box10, { gap: 0, children: /* @__PURE__ */ jsxs7(Text10, { color: theme.title, bold: true, children: [
|
|
1420
1508
|
" ",
|
|
1421
1509
|
isEdit ? "edit" : "create"
|
|
1422
1510
|
] }) }),
|
|
1423
|
-
/* @__PURE__ */
|
|
1511
|
+
/* @__PURE__ */ jsx10(Box10, { flexDirection: "column", paddingX: 1, paddingY: 0, children: FIELDS.map((field2, i) => {
|
|
1424
1512
|
const isFocused = i === focusIndex;
|
|
1425
1513
|
const value = field2.key === "dependsOn" ? depSummary : values[field2.key] ?? "";
|
|
1426
|
-
return /* @__PURE__ */
|
|
1427
|
-
/* @__PURE__ */
|
|
1514
|
+
return /* @__PURE__ */ jsxs7(Box10, { gap: 1, children: [
|
|
1515
|
+
/* @__PURE__ */ jsxs7(Text10, { color: isFocused ? theme.dialog.label : theme.yaml.key, bold: isFocused, children: [
|
|
1428
1516
|
isFocused ? ">" : " ",
|
|
1429
1517
|
" ",
|
|
1430
1518
|
field2.label.padEnd(14)
|
|
1431
1519
|
] }),
|
|
1432
|
-
field2.type === "inline" && /* @__PURE__ */
|
|
1520
|
+
field2.type === "inline" && /* @__PURE__ */ jsx10(Text10, { color: isFocused ? theme.yaml.value : theme.table.fg, children: isFocused ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
1433
1521
|
value.slice(0, cursorPos),
|
|
1434
|
-
/* @__PURE__ */
|
|
1522
|
+
/* @__PURE__ */ jsx10(Text10, { color: theme.titleHighlight, children: "_" }),
|
|
1435
1523
|
value.slice(cursorPos)
|
|
1436
1524
|
] }) : value }),
|
|
1437
|
-
field2.type === "picker" && /* @__PURE__ */
|
|
1438
|
-
value ? /* @__PURE__ */
|
|
1439
|
-
isFocused && /* @__PURE__ */
|
|
1525
|
+
field2.type === "picker" && /* @__PURE__ */ jsxs7(Text10, { children: [
|
|
1526
|
+
value ? /* @__PURE__ */ jsx10(Text10, { color: theme.status.added, children: value.length > 60 ? value.slice(0, 60) + "..." : value }) : /* @__PURE__ */ jsx10(Text10, { dimColor: true, children: isFocused ? "press enter to select" : "none" }),
|
|
1527
|
+
isFocused && /* @__PURE__ */ jsx10(Text10, { color: theme.menu.key, children: " [enter: open picker]" })
|
|
1440
1528
|
] }),
|
|
1441
|
-
field2.type === "editor" && /* @__PURE__ */
|
|
1442
|
-
value ? /* @__PURE__ */
|
|
1529
|
+
field2.type === "editor" && /* @__PURE__ */ jsxs7(Text10, { children: [
|
|
1530
|
+
value ? /* @__PURE__ */ jsxs7(Text10, { color: theme.status.added, children: [
|
|
1443
1531
|
value.split("\n")[0]?.slice(0, 50),
|
|
1444
1532
|
value.length > 50 || value.includes("\n") ? "..." : ""
|
|
1445
|
-
] }) : /* @__PURE__ */
|
|
1446
|
-
isFocused && /* @__PURE__ */
|
|
1533
|
+
] }) : /* @__PURE__ */ jsx10(Text10, { dimColor: true, children: isFocused ? "press enter" : "empty" }),
|
|
1534
|
+
isFocused && /* @__PURE__ */ jsx10(Text10, { color: theme.menu.key, children: " [enter: $EDITOR]" })
|
|
1447
1535
|
] }),
|
|
1448
|
-
field2.type === "select" && /* @__PURE__ */
|
|
1536
|
+
field2.type === "select" && /* @__PURE__ */ jsxs7(Text10, { color: isFocused ? theme.yaml.value : theme.table.fg, children: [
|
|
1449
1537
|
isFocused ? "< " : " ",
|
|
1450
1538
|
value,
|
|
1451
1539
|
isFocused ? " >" : ""
|
|
1452
1540
|
] })
|
|
1453
1541
|
] }, field2.key);
|
|
1454
1542
|
}) }),
|
|
1455
|
-
/* @__PURE__ */
|
|
1456
|
-
/* @__PURE__ */
|
|
1457
|
-
editorActive && /* @__PURE__ */
|
|
1543
|
+
/* @__PURE__ */ jsx10(Box10, { flexGrow: 1 }),
|
|
1544
|
+
/* @__PURE__ */ jsx10(Box10, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "\u2191\u2193/tab: navigate | \u2190\u2192: cursor | ctrl+s: save | esc: cancel" }) }),
|
|
1545
|
+
editorActive && /* @__PURE__ */ jsx10(Box10, { paddingX: 1, children: /* @__PURE__ */ jsx10(Text10, { color: theme.flash.warn, bold: true, children: "Editor open... save and close to return" }) })
|
|
1458
1546
|
] });
|
|
1459
1547
|
}
|
|
1460
1548
|
|
|
1461
1549
|
// src/tui/components/ProjectSelector.tsx
|
|
1462
|
-
import { useState as
|
|
1463
|
-
import { Box as
|
|
1464
|
-
import { jsx as
|
|
1550
|
+
import { useState as useState4 } from "react";
|
|
1551
|
+
import { Box as Box11, Text as Text11, useInput as useInput3 } from "ink";
|
|
1552
|
+
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1465
1553
|
function ProjectSelector({
|
|
1466
1554
|
projects,
|
|
1467
1555
|
activeProject,
|
|
@@ -1472,7 +1560,7 @@ function ProjectSelector({
|
|
|
1472
1560
|
onLink,
|
|
1473
1561
|
onCancel
|
|
1474
1562
|
}) {
|
|
1475
|
-
const [selectedIndex, setSelectedIndex] =
|
|
1563
|
+
const [selectedIndex, setSelectedIndex] = useState4(() => {
|
|
1476
1564
|
if (!activeProject) return 0;
|
|
1477
1565
|
const idx = projects.findIndex((p) => p.id === activeProject.id);
|
|
1478
1566
|
return idx >= 0 ? idx : 0;
|
|
@@ -1521,24 +1609,24 @@ function ProjectSelector({
|
|
|
1521
1609
|
setSelectedIndex((i) => Math.min(projects.length - 1, i + 1));
|
|
1522
1610
|
}
|
|
1523
1611
|
});
|
|
1524
|
-
return /* @__PURE__ */
|
|
1525
|
-
/* @__PURE__ */
|
|
1526
|
-
/* @__PURE__ */
|
|
1612
|
+
return /* @__PURE__ */ jsxs8(Box11, { flexDirection: "column", flexGrow: 1, borderStyle: "bold", borderColor: theme.borderFocus, children: [
|
|
1613
|
+
/* @__PURE__ */ jsxs8(Box11, { gap: 0, children: [
|
|
1614
|
+
/* @__PURE__ */ jsxs8(Text11, { color: theme.title, bold: true, children: [
|
|
1527
1615
|
" ",
|
|
1528
1616
|
"projects"
|
|
1529
1617
|
] }),
|
|
1530
|
-
/* @__PURE__ */
|
|
1618
|
+
/* @__PURE__ */ jsxs8(Text11, { color: theme.titleCounter, bold: true, children: [
|
|
1531
1619
|
"[",
|
|
1532
1620
|
projects.length,
|
|
1533
1621
|
"]"
|
|
1534
1622
|
] })
|
|
1535
1623
|
] }),
|
|
1536
|
-
/* @__PURE__ */
|
|
1537
|
-
/* @__PURE__ */
|
|
1538
|
-
/* @__PURE__ */
|
|
1539
|
-
/* @__PURE__ */
|
|
1624
|
+
/* @__PURE__ */ jsxs8(Box11, { paddingX: 1, children: [
|
|
1625
|
+
/* @__PURE__ */ jsx11(Text11, { color: theme.table.headerFg, bold: true, children: " NAME".padEnd(30) }),
|
|
1626
|
+
/* @__PURE__ */ jsx11(Text11, { color: theme.table.headerFg, bold: true, children: "GIT REMOTE".padEnd(40) }),
|
|
1627
|
+
/* @__PURE__ */ jsx11(Text11, { color: theme.table.headerFg, bold: true, children: "DESCRIPTION" })
|
|
1540
1628
|
] }),
|
|
1541
|
-
projects.length === 0 ? /* @__PURE__ */
|
|
1629
|
+
projects.length === 0 ? /* @__PURE__ */ jsx11(Box11, { paddingX: 1, paddingY: 1, children: /* @__PURE__ */ jsx11(Text11, { color: theme.fg, children: "No projects. Press 'c' to create one." }) }) : projects.map((project, i) => {
|
|
1542
1630
|
const isSelected = i === selectedIndex;
|
|
1543
1631
|
const isActive = project.id === activeProject?.id;
|
|
1544
1632
|
const activeMarker = isActive ? "*" : " ";
|
|
@@ -1546,7 +1634,7 @@ function ProjectSelector({
|
|
|
1546
1634
|
const marker = `${activeMarker}${defaultMarker}`;
|
|
1547
1635
|
const remoteDisplay = (project.gitRemote?.value ?? "").slice(0, 38).padEnd(40);
|
|
1548
1636
|
if (isSelected) {
|
|
1549
|
-
return /* @__PURE__ */
|
|
1637
|
+
return /* @__PURE__ */ jsx11(Box11, { paddingX: 1, children: /* @__PURE__ */ jsxs8(Text11, { backgroundColor: theme.table.cursorBg, color: theme.table.cursorFg, bold: true, children: [
|
|
1550
1638
|
marker,
|
|
1551
1639
|
" ",
|
|
1552
1640
|
project.name.padEnd(27),
|
|
@@ -1554,25 +1642,25 @@ function ProjectSelector({
|
|
|
1554
1642
|
project.description
|
|
1555
1643
|
] }) }, project.id);
|
|
1556
1644
|
}
|
|
1557
|
-
return /* @__PURE__ */
|
|
1558
|
-
/* @__PURE__ */
|
|
1645
|
+
return /* @__PURE__ */ jsxs8(Box11, { paddingX: 1, children: [
|
|
1646
|
+
/* @__PURE__ */ jsxs8(Text11, { color: isActive ? theme.status.modified : theme.table.fg, children: [
|
|
1559
1647
|
marker,
|
|
1560
1648
|
" ",
|
|
1561
1649
|
project.name.padEnd(27)
|
|
1562
1650
|
] }),
|
|
1563
|
-
/* @__PURE__ */
|
|
1564
|
-
/* @__PURE__ */
|
|
1651
|
+
/* @__PURE__ */ jsx11(Text11, { dimColor: true, children: remoteDisplay }),
|
|
1652
|
+
/* @__PURE__ */ jsx11(Text11, { dimColor: true, children: project.description })
|
|
1565
1653
|
] }, project.id);
|
|
1566
1654
|
}),
|
|
1567
|
-
/* @__PURE__ */
|
|
1568
|
-
/* @__PURE__ */
|
|
1655
|
+
/* @__PURE__ */ jsx11(Box11, { flexGrow: 1 }),
|
|
1656
|
+
/* @__PURE__ */ jsx11(Box11, { paddingX: 1, children: /* @__PURE__ */ jsx11(Text11, { dimColor: true, children: "enter: select | e: edit | d: set default | l: link git | c: create | esc: back" }) })
|
|
1569
1657
|
] });
|
|
1570
1658
|
}
|
|
1571
1659
|
|
|
1572
1660
|
// src/tui/components/ProjectForm.tsx
|
|
1573
|
-
import { useState as
|
|
1574
|
-
import { Box as
|
|
1575
|
-
import { Fragment as
|
|
1661
|
+
import { useState as useState5, useEffect as useEffect3, useRef as useRef2 } from "react";
|
|
1662
|
+
import { Box as Box12, Text as Text12, useInput as useInput4 } from "ink";
|
|
1663
|
+
import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1576
1664
|
var FIELDS2 = [
|
|
1577
1665
|
{ label: "Name", key: "name", type: "inline" },
|
|
1578
1666
|
{ label: "Key", key: "key", type: "inline" },
|
|
@@ -1582,8 +1670,8 @@ var FIELDS2 = [
|
|
|
1582
1670
|
];
|
|
1583
1671
|
function ProjectForm({ editingProject, initialGitRemote, onSave, onCancel }) {
|
|
1584
1672
|
const isEditing = !!editingProject;
|
|
1585
|
-
const [focusIndex, setFocusIndex] =
|
|
1586
|
-
const [values, setValues] =
|
|
1673
|
+
const [focusIndex, setFocusIndex] = useState5(0);
|
|
1674
|
+
const [values, setValues] = useState5(() => {
|
|
1587
1675
|
if (editingProject) {
|
|
1588
1676
|
return {
|
|
1589
1677
|
name: editingProject.name,
|
|
@@ -1601,10 +1689,10 @@ function ProjectForm({ editingProject, initialGitRemote, onSave, onCancel }) {
|
|
|
1601
1689
|
isDefault: "no"
|
|
1602
1690
|
};
|
|
1603
1691
|
});
|
|
1604
|
-
const [cursorPos, setCursorPos] =
|
|
1692
|
+
const [cursorPos, setCursorPos] = useState5(0);
|
|
1605
1693
|
const cursorRef = useRef2(cursorPos);
|
|
1606
1694
|
cursorRef.current = cursorPos;
|
|
1607
|
-
|
|
1695
|
+
useEffect3(() => {
|
|
1608
1696
|
const field2 = FIELDS2[focusIndex];
|
|
1609
1697
|
if (field2?.type === "inline") {
|
|
1610
1698
|
const pos = values[field2.key]?.length ?? 0;
|
|
@@ -1685,48 +1773,48 @@ function ProjectForm({ editingProject, initialGitRemote, onSave, onCancel }) {
|
|
|
1685
1773
|
}
|
|
1686
1774
|
}
|
|
1687
1775
|
});
|
|
1688
|
-
return /* @__PURE__ */
|
|
1689
|
-
/* @__PURE__ */
|
|
1776
|
+
return /* @__PURE__ */ jsxs9(Box12, { flexDirection: "column", flexGrow: 1, borderStyle: "bold", borderColor: theme.borderFocus, children: [
|
|
1777
|
+
/* @__PURE__ */ jsx12(Box12, { gap: 0, children: /* @__PURE__ */ jsxs9(Text12, { color: theme.title, bold: true, children: [
|
|
1690
1778
|
" ",
|
|
1691
1779
|
isEditing ? "edit project" : "new project"
|
|
1692
1780
|
] }) }),
|
|
1693
|
-
/* @__PURE__ */
|
|
1781
|
+
/* @__PURE__ */ jsx12(Box12, { flexDirection: "column", paddingX: 1, paddingY: 0, children: FIELDS2.map((field2, i) => {
|
|
1694
1782
|
const isFocused = i === focusIndex;
|
|
1695
1783
|
const value = values[field2.key] ?? "";
|
|
1696
|
-
return /* @__PURE__ */
|
|
1697
|
-
/* @__PURE__ */
|
|
1784
|
+
return /* @__PURE__ */ jsxs9(Box12, { gap: 1, children: [
|
|
1785
|
+
/* @__PURE__ */ jsxs9(Text12, { color: isFocused ? theme.dialog.label : theme.yaml.key, bold: isFocused, children: [
|
|
1698
1786
|
isFocused ? ">" : " ",
|
|
1699
1787
|
" ",
|
|
1700
1788
|
field2.label.padEnd(14)
|
|
1701
1789
|
] }),
|
|
1702
|
-
field2.type === "inline" && /* @__PURE__ */
|
|
1703
|
-
isFocused ? /* @__PURE__ */
|
|
1790
|
+
field2.type === "inline" && /* @__PURE__ */ jsxs9(Text12, { color: isFocused ? theme.yaml.value : theme.table.fg, children: [
|
|
1791
|
+
isFocused ? /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
1704
1792
|
value.slice(0, cursorPos),
|
|
1705
|
-
/* @__PURE__ */
|
|
1793
|
+
/* @__PURE__ */ jsx12(Text12, { color: theme.titleHighlight, children: "_" }),
|
|
1706
1794
|
value.slice(cursorPos)
|
|
1707
1795
|
] }) : value,
|
|
1708
|
-
field2.key === "key" && !value && !isEditing && /* @__PURE__ */
|
|
1709
|
-
field2.key === "key" && isEditing && isFocused && /* @__PURE__ */
|
|
1796
|
+
field2.key === "key" && !value && !isEditing && /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: isFocused ? " (auto from name)" : "" }),
|
|
1797
|
+
field2.key === "key" && isEditing && isFocused && /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: " (read-only)" })
|
|
1710
1798
|
] }),
|
|
1711
|
-
field2.type === "toggle" && /* @__PURE__ */
|
|
1799
|
+
field2.type === "toggle" && /* @__PURE__ */ jsxs9(Text12, { color: isFocused ? theme.yaml.value : theme.table.fg, children: [
|
|
1712
1800
|
isFocused ? "< " : " ",
|
|
1713
1801
|
value,
|
|
1714
1802
|
isFocused ? " >" : ""
|
|
1715
1803
|
] })
|
|
1716
1804
|
] }, field2.key);
|
|
1717
1805
|
}) }),
|
|
1718
|
-
/* @__PURE__ */
|
|
1719
|
-
/* @__PURE__ */
|
|
1806
|
+
/* @__PURE__ */ jsx12(Box12, { flexGrow: 1 }),
|
|
1807
|
+
/* @__PURE__ */ jsx12(Box12, { paddingX: 1, children: /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: "\u2191\u2193/tab: navigate | \u2190\u2192: cursor | ctrl+s: save | esc: cancel" }) })
|
|
1720
1808
|
] });
|
|
1721
1809
|
}
|
|
1722
1810
|
|
|
1723
1811
|
// src/tui/components/ProjectLinkForm.tsx
|
|
1724
|
-
import { useState as
|
|
1725
|
-
import { Box as
|
|
1726
|
-
import { jsx as
|
|
1812
|
+
import { useState as useState6, useRef as useRef3 } from "react";
|
|
1813
|
+
import { Box as Box13, Text as Text13, useInput as useInput5 } from "ink";
|
|
1814
|
+
import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1727
1815
|
function ProjectLinkForm({ project, onSave, onUnlink, onDetect, onCancel }) {
|
|
1728
|
-
const [remoteUrl, setRemoteUrl] =
|
|
1729
|
-
const [cursorPos, setCursorPos] =
|
|
1816
|
+
const [remoteUrl, setRemoteUrl] = useState6(project.gitRemote?.value ?? "");
|
|
1817
|
+
const [cursorPos, setCursorPos] = useState6(() => (project.gitRemote?.value ?? "").length);
|
|
1730
1818
|
const cursorRef = useRef3(cursorPos);
|
|
1731
1819
|
cursorRef.current = cursorPos;
|
|
1732
1820
|
useInput5((input, key) => {
|
|
@@ -1780,24 +1868,24 @@ function ProjectLinkForm({ project, onSave, onUnlink, onDetect, onCancel }) {
|
|
|
1780
1868
|
setCursorPos(pos + input.length);
|
|
1781
1869
|
}
|
|
1782
1870
|
});
|
|
1783
|
-
return /* @__PURE__ */
|
|
1784
|
-
/* @__PURE__ */
|
|
1785
|
-
/* @__PURE__ */
|
|
1871
|
+
return /* @__PURE__ */ jsxs10(Box13, { flexDirection: "column", flexGrow: 1, borderStyle: "bold", borderColor: theme.borderFocus, children: [
|
|
1872
|
+
/* @__PURE__ */ jsxs10(Box13, { gap: 0, children: [
|
|
1873
|
+
/* @__PURE__ */ jsxs10(Text13, { color: theme.title, bold: true, children: [
|
|
1786
1874
|
" ",
|
|
1787
1875
|
"link git remote"
|
|
1788
1876
|
] }),
|
|
1789
|
-
/* @__PURE__ */
|
|
1877
|
+
/* @__PURE__ */ jsxs10(Text13, { color: theme.titleCounter, bold: true, children: [
|
|
1790
1878
|
" ",
|
|
1791
1879
|
"[",
|
|
1792
1880
|
project.name,
|
|
1793
1881
|
"]"
|
|
1794
1882
|
] })
|
|
1795
1883
|
] }),
|
|
1796
|
-
/* @__PURE__ */
|
|
1797
|
-
/* @__PURE__ */
|
|
1798
|
-
/* @__PURE__ */
|
|
1799
|
-
/* @__PURE__ */
|
|
1800
|
-
|
|
1884
|
+
/* @__PURE__ */ jsxs10(Box13, { flexDirection: "column", paddingX: 1, paddingY: 1, children: [
|
|
1885
|
+
/* @__PURE__ */ jsxs10(Box13, { gap: 1, children: [
|
|
1886
|
+
/* @__PURE__ */ jsx13(Text13, { color: theme.dialog.label, bold: true, children: "Current:" }),
|
|
1887
|
+
/* @__PURE__ */ jsx13(
|
|
1888
|
+
Text13,
|
|
1801
1889
|
{
|
|
1802
1890
|
color: project.gitRemote ? theme.yaml.value : theme.table.fg,
|
|
1803
1891
|
dimColor: !project.gitRemote,
|
|
@@ -1805,17 +1893,17 @@ function ProjectLinkForm({ project, onSave, onUnlink, onDetect, onCancel }) {
|
|
|
1805
1893
|
}
|
|
1806
1894
|
)
|
|
1807
1895
|
] }),
|
|
1808
|
-
/* @__PURE__ */
|
|
1809
|
-
/* @__PURE__ */
|
|
1810
|
-
/* @__PURE__ */
|
|
1896
|
+
/* @__PURE__ */ jsxs10(Box13, { gap: 1, marginTop: 1, children: [
|
|
1897
|
+
/* @__PURE__ */ jsx13(Text13, { color: theme.dialog.label, bold: true, children: "Remote URL: " }),
|
|
1898
|
+
/* @__PURE__ */ jsxs10(Text13, { color: theme.yaml.value, children: [
|
|
1811
1899
|
remoteUrl.slice(0, cursorPos),
|
|
1812
|
-
/* @__PURE__ */
|
|
1900
|
+
/* @__PURE__ */ jsx13(Text13, { color: theme.titleHighlight, children: "_" }),
|
|
1813
1901
|
remoteUrl.slice(cursorPos)
|
|
1814
1902
|
] })
|
|
1815
1903
|
] })
|
|
1816
1904
|
] }),
|
|
1817
|
-
/* @__PURE__ */
|
|
1818
|
-
/* @__PURE__ */
|
|
1905
|
+
/* @__PURE__ */ jsx13(Box13, { flexGrow: 1 }),
|
|
1906
|
+
/* @__PURE__ */ jsx13(Box13, { paddingX: 1, children: /* @__PURE__ */ jsx13(Text13, { dimColor: true, children: "ctrl+s: save | ctrl+d: detect from cwd | ctrl+u: unlink | esc: cancel" }) })
|
|
1819
1907
|
] });
|
|
1820
1908
|
}
|
|
1821
1909
|
|
|
@@ -1847,13 +1935,16 @@ function dismissRemote(filePath, remote) {
|
|
|
1847
1935
|
writeFileSync3(filePath, JSON.stringify(list), "utf-8");
|
|
1848
1936
|
logger.info(`dismissRemote: persisted ${remote.value} to ${filePath}`);
|
|
1849
1937
|
} catch (e) {
|
|
1850
|
-
logger.error(
|
|
1938
|
+
logger.error(
|
|
1939
|
+
`dismissRemote: failed to write ${filePath}`,
|
|
1940
|
+
e instanceof Error ? e : new Error(String(e))
|
|
1941
|
+
);
|
|
1851
1942
|
}
|
|
1852
1943
|
}
|
|
1853
1944
|
|
|
1854
1945
|
// src/tui/components/HelpOverlay.tsx
|
|
1855
|
-
import { Box as
|
|
1856
|
-
import { jsx as
|
|
1946
|
+
import { Box as Box14, Text as Text14 } from "ink";
|
|
1947
|
+
import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1857
1948
|
var ROW1 = [
|
|
1858
1949
|
{
|
|
1859
1950
|
title: "NAVIGATION",
|
|
@@ -1939,21 +2030,21 @@ var ROW2 = [
|
|
|
1939
2030
|
}
|
|
1940
2031
|
];
|
|
1941
2032
|
function SectionRow({ sections }) {
|
|
1942
|
-
return /* @__PURE__ */
|
|
1943
|
-
/* @__PURE__ */
|
|
1944
|
-
section.keys.map(([key, desc]) => /* @__PURE__ */
|
|
1945
|
-
/* @__PURE__ */
|
|
2033
|
+
return /* @__PURE__ */ jsx14(Box14, { flexDirection: "row", gap: 4, children: sections.map((section) => /* @__PURE__ */ jsxs11(Box14, { flexDirection: "column", children: [
|
|
2034
|
+
/* @__PURE__ */ jsx14(Text14, { color: theme.table.headerFg, bold: true, children: section.title }),
|
|
2035
|
+
section.keys.map(([key, desc]) => /* @__PURE__ */ jsxs11(Box14, { gap: 1, children: [
|
|
2036
|
+
/* @__PURE__ */ jsxs11(Text14, { color: theme.menu.key, bold: true, children: [
|
|
1946
2037
|
"<",
|
|
1947
2038
|
key.padEnd(5),
|
|
1948
2039
|
">"
|
|
1949
2040
|
] }),
|
|
1950
|
-
/* @__PURE__ */
|
|
2041
|
+
/* @__PURE__ */ jsx14(Text14, { dimColor: true, children: desc })
|
|
1951
2042
|
] }, key))
|
|
1952
2043
|
] }, section.title)) });
|
|
1953
2044
|
}
|
|
1954
2045
|
function HelpOverlay() {
|
|
1955
|
-
return /* @__PURE__ */
|
|
1956
|
-
|
|
2046
|
+
return /* @__PURE__ */ jsxs11(
|
|
2047
|
+
Box14,
|
|
1957
2048
|
{
|
|
1958
2049
|
flexDirection: "column",
|
|
1959
2050
|
borderStyle: "bold",
|
|
@@ -1961,28 +2052,28 @@ function HelpOverlay() {
|
|
|
1961
2052
|
paddingX: 2,
|
|
1962
2053
|
paddingY: 1,
|
|
1963
2054
|
children: [
|
|
1964
|
-
/* @__PURE__ */
|
|
2055
|
+
/* @__PURE__ */ jsxs11(Text14, { color: theme.title, bold: true, children: [
|
|
1965
2056
|
" ",
|
|
1966
2057
|
"Help"
|
|
1967
2058
|
] }),
|
|
1968
|
-
/* @__PURE__ */
|
|
1969
|
-
/* @__PURE__ */
|
|
1970
|
-
/* @__PURE__ */
|
|
1971
|
-
/* @__PURE__ */
|
|
2059
|
+
/* @__PURE__ */ jsx14(Text14, { children: " " }),
|
|
2060
|
+
/* @__PURE__ */ jsxs11(Box14, { flexDirection: "column", gap: 1, children: [
|
|
2061
|
+
/* @__PURE__ */ jsx14(SectionRow, { sections: ROW1 }),
|
|
2062
|
+
/* @__PURE__ */ jsx14(SectionRow, { sections: ROW2 })
|
|
1972
2063
|
] }),
|
|
1973
|
-
/* @__PURE__ */
|
|
1974
|
-
/* @__PURE__ */
|
|
2064
|
+
/* @__PURE__ */ jsx14(Text14, { children: " " }),
|
|
2065
|
+
/* @__PURE__ */ jsx14(Text14, { dimColor: true, children: "Press any key to close" })
|
|
1975
2066
|
]
|
|
1976
2067
|
}
|
|
1977
2068
|
);
|
|
1978
2069
|
}
|
|
1979
2070
|
|
|
1980
2071
|
// src/tui/components/ConfirmDialog.tsx
|
|
1981
|
-
import { Box as
|
|
1982
|
-
import { jsx as
|
|
2072
|
+
import { Box as Box15, Text as Text15 } from "ink";
|
|
2073
|
+
import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1983
2074
|
function ConfirmDialog({ task }) {
|
|
1984
|
-
return /* @__PURE__ */
|
|
1985
|
-
|
|
2075
|
+
return /* @__PURE__ */ jsxs12(
|
|
2076
|
+
Box15,
|
|
1986
2077
|
{
|
|
1987
2078
|
flexDirection: "column",
|
|
1988
2079
|
borderStyle: "bold",
|
|
@@ -1991,17 +2082,17 @@ function ConfirmDialog({ task }) {
|
|
|
1991
2082
|
paddingY: 1,
|
|
1992
2083
|
alignSelf: "center",
|
|
1993
2084
|
children: [
|
|
1994
|
-
/* @__PURE__ */
|
|
1995
|
-
/* @__PURE__ */
|
|
1996
|
-
/* @__PURE__ */
|
|
2085
|
+
/* @__PURE__ */ jsx15(Text15, { color: theme.dialog.label, bold: true, children: "<Delete>" }),
|
|
2086
|
+
/* @__PURE__ */ jsx15(Text15, { children: " " }),
|
|
2087
|
+
/* @__PURE__ */ jsxs12(Text15, { color: theme.dialog.fg, children: [
|
|
1997
2088
|
'Delete task "',
|
|
1998
2089
|
task.name,
|
|
1999
2090
|
'"?'
|
|
2000
2091
|
] }),
|
|
2001
|
-
/* @__PURE__ */
|
|
2002
|
-
/* @__PURE__ */
|
|
2003
|
-
/* @__PURE__ */
|
|
2004
|
-
|
|
2092
|
+
/* @__PURE__ */ jsx15(Text15, { children: " " }),
|
|
2093
|
+
/* @__PURE__ */ jsxs12(Box15, { gap: 3, children: [
|
|
2094
|
+
/* @__PURE__ */ jsx15(Box15, { children: /* @__PURE__ */ jsx15(
|
|
2095
|
+
Text15,
|
|
2005
2096
|
{
|
|
2006
2097
|
backgroundColor: theme.dialog.buttonFocusBg,
|
|
2007
2098
|
color: theme.dialog.buttonFocusFg,
|
|
@@ -2009,7 +2100,7 @@ function ConfirmDialog({ task }) {
|
|
|
2009
2100
|
children: " y: OK "
|
|
2010
2101
|
}
|
|
2011
2102
|
) }),
|
|
2012
|
-
/* @__PURE__ */
|
|
2103
|
+
/* @__PURE__ */ jsx15(Box15, { children: /* @__PURE__ */ jsx15(Text15, { backgroundColor: theme.dialog.buttonBg, color: theme.dialog.buttonFg, children: " n: Cancel " }) })
|
|
2013
2104
|
] })
|
|
2014
2105
|
]
|
|
2015
2106
|
}
|
|
@@ -2017,11 +2108,11 @@ function ConfirmDialog({ task }) {
|
|
|
2017
2108
|
}
|
|
2018
2109
|
|
|
2019
2110
|
// src/tui/components/DetectedProjectDialog.tsx
|
|
2020
|
-
import { Box as
|
|
2021
|
-
import { jsx as
|
|
2111
|
+
import { Box as Box16, Text as Text16 } from "ink";
|
|
2112
|
+
import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2022
2113
|
function DetectedProjectDialog({ remote }) {
|
|
2023
|
-
return /* @__PURE__ */
|
|
2024
|
-
|
|
2114
|
+
return /* @__PURE__ */ jsxs13(
|
|
2115
|
+
Box16,
|
|
2025
2116
|
{
|
|
2026
2117
|
flexDirection: "column",
|
|
2027
2118
|
borderStyle: "bold",
|
|
@@ -2030,18 +2121,18 @@ function DetectedProjectDialog({ remote }) {
|
|
|
2030
2121
|
paddingY: 1,
|
|
2031
2122
|
alignSelf: "center",
|
|
2032
2123
|
children: [
|
|
2033
|
-
/* @__PURE__ */
|
|
2034
|
-
/* @__PURE__ */
|
|
2035
|
-
/* @__PURE__ */
|
|
2124
|
+
/* @__PURE__ */ jsx16(Text16, { color: theme.dialog.label, bold: true, children: "<New Repo Detected>" }),
|
|
2125
|
+
/* @__PURE__ */ jsx16(Text16, { children: " " }),
|
|
2126
|
+
/* @__PURE__ */ jsxs13(Text16, { color: theme.dialog.fg, children: [
|
|
2036
2127
|
"Git remote: ",
|
|
2037
|
-
/* @__PURE__ */
|
|
2128
|
+
/* @__PURE__ */ jsx16(Text16, { bold: true, children: remote.value })
|
|
2038
2129
|
] }),
|
|
2039
|
-
/* @__PURE__ */
|
|
2040
|
-
/* @__PURE__ */
|
|
2041
|
-
/* @__PURE__ */
|
|
2042
|
-
/* @__PURE__ */
|
|
2043
|
-
/* @__PURE__ */
|
|
2044
|
-
/* @__PURE__ */
|
|
2130
|
+
/* @__PURE__ */ jsx16(Text16, { color: theme.dialog.fg, children: "No project is linked to this repo yet." }),
|
|
2131
|
+
/* @__PURE__ */ jsx16(Text16, { color: theme.dialog.fg, children: "Would you like to create one and link it?" }),
|
|
2132
|
+
/* @__PURE__ */ jsx16(Text16, { children: " " }),
|
|
2133
|
+
/* @__PURE__ */ jsxs13(Box16, { gap: 3, children: [
|
|
2134
|
+
/* @__PURE__ */ jsx16(Text16, { backgroundColor: theme.dialog.buttonFocusBg, color: theme.dialog.buttonFocusFg, bold: true, children: " y: Create " }),
|
|
2135
|
+
/* @__PURE__ */ jsx16(Text16, { backgroundColor: theme.dialog.buttonBg, color: theme.dialog.buttonFg, children: " n: Skip " })
|
|
2045
2136
|
] })
|
|
2046
2137
|
]
|
|
2047
2138
|
}
|
|
@@ -2049,8 +2140,8 @@ function DetectedProjectDialog({ remote }) {
|
|
|
2049
2140
|
}
|
|
2050
2141
|
|
|
2051
2142
|
// src/tui/components/DependencyList.tsx
|
|
2052
|
-
import { Box as
|
|
2053
|
-
import { Fragment as
|
|
2143
|
+
import { Box as Box17, Text as Text17 } from "ink";
|
|
2144
|
+
import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2054
2145
|
function TaskRow({
|
|
2055
2146
|
task,
|
|
2056
2147
|
globalIndex,
|
|
@@ -2058,16 +2149,16 @@ function TaskRow({
|
|
|
2058
2149
|
}) {
|
|
2059
2150
|
const isSelected = globalIndex === selectedIndex;
|
|
2060
2151
|
const statusColor = STATUS_COLOR[task.status] ?? theme.table.fg;
|
|
2061
|
-
return /* @__PURE__ */
|
|
2152
|
+
return /* @__PURE__ */ jsx17(Box17, { children: isSelected ? /* @__PURE__ */ jsxs14(Text17, { backgroundColor: theme.table.cursorBg, color: theme.table.cursorFg, bold: true, children: [
|
|
2062
2153
|
"> ",
|
|
2063
2154
|
task.id.padEnd(12),
|
|
2064
2155
|
task.status.padEnd(14),
|
|
2065
2156
|
task.name
|
|
2066
|
-
] }) : /* @__PURE__ */
|
|
2067
|
-
/* @__PURE__ */
|
|
2068
|
-
/* @__PURE__ */
|
|
2069
|
-
/* @__PURE__ */
|
|
2070
|
-
/* @__PURE__ */
|
|
2157
|
+
] }) : /* @__PURE__ */ jsxs14(Fragment5, { children: [
|
|
2158
|
+
/* @__PURE__ */ jsx17(Text17, { children: " " }),
|
|
2159
|
+
/* @__PURE__ */ jsx17(Text17, { color: theme.yaml.value, children: task.id.padEnd(12) }),
|
|
2160
|
+
/* @__PURE__ */ jsx17(Text17, { color: statusColor, children: task.status.padEnd(14) }),
|
|
2161
|
+
/* @__PURE__ */ jsx17(Text17, { color: theme.table.fg, children: task.name })
|
|
2071
2162
|
] }) }, task.id);
|
|
2072
2163
|
}
|
|
2073
2164
|
function DependencyList({
|
|
@@ -2088,23 +2179,23 @@ function DependencyList({
|
|
|
2088
2179
|
const relatedOffset = offset;
|
|
2089
2180
|
offset += related.length;
|
|
2090
2181
|
const duplicatesOffset = offset;
|
|
2091
|
-
return /* @__PURE__ */
|
|
2092
|
-
/* @__PURE__ */
|
|
2093
|
-
/* @__PURE__ */
|
|
2182
|
+
return /* @__PURE__ */ jsxs14(Box17, { flexDirection: "column", flexGrow: 1, borderStyle: "bold", borderColor: theme.borderFocus, children: [
|
|
2183
|
+
/* @__PURE__ */ jsxs14(Box17, { gap: 0, children: [
|
|
2184
|
+
/* @__PURE__ */ jsxs14(Text17, { color: theme.title, bold: true, children: [
|
|
2094
2185
|
" ",
|
|
2095
2186
|
"dependencies"
|
|
2096
2187
|
] }),
|
|
2097
|
-
/* @__PURE__ */
|
|
2098
|
-
/* @__PURE__ */
|
|
2099
|
-
/* @__PURE__ */
|
|
2188
|
+
/* @__PURE__ */ jsx17(Text17, { color: theme.fg, children: "(" }),
|
|
2189
|
+
/* @__PURE__ */ jsx17(Text17, { color: theme.titleHighlight, bold: true, children: task.name }),
|
|
2190
|
+
/* @__PURE__ */ jsx17(Text17, { color: theme.fg, children: ")" })
|
|
2100
2191
|
] }),
|
|
2101
|
-
/* @__PURE__ */
|
|
2102
|
-
/* @__PURE__ */
|
|
2192
|
+
/* @__PURE__ */ jsxs14(Box17, { flexDirection: "column", paddingX: 1, paddingTop: 1, children: [
|
|
2193
|
+
/* @__PURE__ */ jsxs14(Text17, { color: theme.table.headerFg, bold: true, children: [
|
|
2103
2194
|
"BLOCKED BY (",
|
|
2104
2195
|
blockers.length,
|
|
2105
2196
|
")"
|
|
2106
2197
|
] }),
|
|
2107
|
-
blockers.length === 0 ? /* @__PURE__ */
|
|
2198
|
+
blockers.length === 0 ? /* @__PURE__ */ jsx17(Text17, { dimColor: true, children: " No blockers" }) : blockers.map((t, i) => /* @__PURE__ */ jsx17(
|
|
2108
2199
|
TaskRow,
|
|
2109
2200
|
{
|
|
2110
2201
|
task: t,
|
|
@@ -2114,13 +2205,13 @@ function DependencyList({
|
|
|
2114
2205
|
t.id
|
|
2115
2206
|
))
|
|
2116
2207
|
] }),
|
|
2117
|
-
/* @__PURE__ */
|
|
2118
|
-
/* @__PURE__ */
|
|
2208
|
+
/* @__PURE__ */ jsxs14(Box17, { flexDirection: "column", paddingX: 1, paddingTop: 1, children: [
|
|
2209
|
+
/* @__PURE__ */ jsxs14(Text17, { color: theme.table.headerFg, bold: true, children: [
|
|
2119
2210
|
"BLOCKS (",
|
|
2120
2211
|
dependents.length,
|
|
2121
2212
|
")"
|
|
2122
2213
|
] }),
|
|
2123
|
-
dependents.length === 0 ? /* @__PURE__ */
|
|
2214
|
+
dependents.length === 0 ? /* @__PURE__ */ jsx17(Text17, { dimColor: true, children: " No dependents" }) : dependents.map((t, i) => /* @__PURE__ */ jsx17(
|
|
2124
2215
|
TaskRow,
|
|
2125
2216
|
{
|
|
2126
2217
|
task: t,
|
|
@@ -2130,13 +2221,13 @@ function DependencyList({
|
|
|
2130
2221
|
t.id
|
|
2131
2222
|
))
|
|
2132
2223
|
] }),
|
|
2133
|
-
/* @__PURE__ */
|
|
2134
|
-
/* @__PURE__ */
|
|
2224
|
+
/* @__PURE__ */ jsxs14(Box17, { flexDirection: "column", paddingX: 1, paddingTop: 1, children: [
|
|
2225
|
+
/* @__PURE__ */ jsxs14(Text17, { color: theme.table.headerFg, bold: true, children: [
|
|
2135
2226
|
"RELATES TO (",
|
|
2136
2227
|
related.length,
|
|
2137
2228
|
")"
|
|
2138
2229
|
] }),
|
|
2139
|
-
related.length === 0 ? /* @__PURE__ */
|
|
2230
|
+
related.length === 0 ? /* @__PURE__ */ jsx17(Text17, { dimColor: true, children: " No related tasks" }) : related.map((t, i) => /* @__PURE__ */ jsx17(
|
|
2140
2231
|
TaskRow,
|
|
2141
2232
|
{
|
|
2142
2233
|
task: t,
|
|
@@ -2146,13 +2237,13 @@ function DependencyList({
|
|
|
2146
2237
|
t.id
|
|
2147
2238
|
))
|
|
2148
2239
|
] }),
|
|
2149
|
-
/* @__PURE__ */
|
|
2150
|
-
/* @__PURE__ */
|
|
2240
|
+
/* @__PURE__ */ jsxs14(Box17, { flexDirection: "column", paddingX: 1, paddingTop: 1, children: [
|
|
2241
|
+
/* @__PURE__ */ jsxs14(Text17, { color: theme.table.headerFg, bold: true, children: [
|
|
2151
2242
|
"DUPLICATES (",
|
|
2152
2243
|
duplicates.length,
|
|
2153
2244
|
")"
|
|
2154
2245
|
] }),
|
|
2155
|
-
duplicates.length === 0 ? /* @__PURE__ */
|
|
2246
|
+
duplicates.length === 0 ? /* @__PURE__ */ jsx17(Text17, { dimColor: true, children: " No duplicate tasks" }) : duplicates.map((t, i) => /* @__PURE__ */ jsx17(
|
|
2156
2247
|
TaskRow,
|
|
2157
2248
|
{
|
|
2158
2249
|
task: t,
|
|
@@ -2162,19 +2253,19 @@ function DependencyList({
|
|
|
2162
2253
|
t.id
|
|
2163
2254
|
))
|
|
2164
2255
|
] }),
|
|
2165
|
-
/* @__PURE__ */
|
|
2166
|
-
isAddingDep && /* @__PURE__ */
|
|
2167
|
-
/* @__PURE__ */
|
|
2168
|
-
/* @__PURE__ */
|
|
2169
|
-
/* @__PURE__ */
|
|
2256
|
+
/* @__PURE__ */ jsx17(Box17, { flexGrow: 1 }),
|
|
2257
|
+
isAddingDep && /* @__PURE__ */ jsxs14(Box17, { borderStyle: "round", borderColor: theme.prompt, paddingX: 1, children: [
|
|
2258
|
+
/* @__PURE__ */ jsx17(Text17, { color: theme.prompt, children: "depends on (id or id:type): " }),
|
|
2259
|
+
/* @__PURE__ */ jsx17(Text17, { color: theme.prompt, children: addDepInput }),
|
|
2260
|
+
/* @__PURE__ */ jsx17(Text17, { color: theme.promptSuggest, children: "_" })
|
|
2170
2261
|
] }),
|
|
2171
|
-
/* @__PURE__ */
|
|
2262
|
+
/* @__PURE__ */ jsx17(Box17, { paddingX: 1, children: /* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "a: add dep (id or id:relates-to) | x: remove selected | enter: go to task | esc: back" }) })
|
|
2172
2263
|
] });
|
|
2173
2264
|
}
|
|
2174
2265
|
|
|
2175
2266
|
// src/tui/components/EpicPanel.tsx
|
|
2176
|
-
import { Box as
|
|
2177
|
-
import { jsx as
|
|
2267
|
+
import { Box as Box18, Text as Text18 } from "ink";
|
|
2268
|
+
import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2178
2269
|
var PAGE_SIZE2 = 20;
|
|
2179
2270
|
function EpicPanel({
|
|
2180
2271
|
epics,
|
|
@@ -2187,34 +2278,34 @@ function EpicPanel({
|
|
|
2187
2278
|
const currentPage = Math.floor(selectedIndex / PAGE_SIZE2);
|
|
2188
2279
|
const viewStart = currentPage * PAGE_SIZE2;
|
|
2189
2280
|
const visibleEpics = epics.slice(viewStart, viewStart + PAGE_SIZE2);
|
|
2190
|
-
return /* @__PURE__ */
|
|
2191
|
-
|
|
2281
|
+
return /* @__PURE__ */ jsxs15(
|
|
2282
|
+
Box18,
|
|
2192
2283
|
{
|
|
2193
2284
|
flexDirection: "column",
|
|
2194
2285
|
width: 48,
|
|
2195
2286
|
borderStyle: "bold",
|
|
2196
2287
|
borderColor: isFocused ? theme.borderFocus : theme.border,
|
|
2197
2288
|
children: [
|
|
2198
|
-
/* @__PURE__ */
|
|
2199
|
-
/* @__PURE__ */
|
|
2289
|
+
/* @__PURE__ */ jsxs15(Box18, { children: [
|
|
2290
|
+
/* @__PURE__ */ jsxs15(Text18, { color: theme.title, bold: true, children: [
|
|
2200
2291
|
" ",
|
|
2201
2292
|
"epics"
|
|
2202
2293
|
] }),
|
|
2203
|
-
/* @__PURE__ */
|
|
2294
|
+
/* @__PURE__ */ jsxs15(Text18, { color: theme.titleCounter, bold: true, children: [
|
|
2204
2295
|
"[",
|
|
2205
2296
|
epics.length,
|
|
2206
2297
|
"]"
|
|
2207
2298
|
] }),
|
|
2208
|
-
isReordering && /* @__PURE__ */
|
|
2299
|
+
isReordering && /* @__PURE__ */ jsxs15(Text18, { color: theme.flash.warn, bold: true, children: [
|
|
2209
2300
|
" ",
|
|
2210
2301
|
"REORDER"
|
|
2211
2302
|
] }),
|
|
2212
|
-
filterActive && /* @__PURE__ */
|
|
2303
|
+
filterActive && /* @__PURE__ */ jsxs15(Text18, { color: theme.titleFilter, children: [
|
|
2213
2304
|
" *",
|
|
2214
2305
|
selectedEpicIds.size
|
|
2215
2306
|
] })
|
|
2216
2307
|
] }),
|
|
2217
|
-
/* @__PURE__ */
|
|
2308
|
+
/* @__PURE__ */ jsx18(Box18, { flexDirection: "column", flexGrow: 1, overflowY: "hidden", children: epics.length === 0 ? /* @__PURE__ */ jsx18(Box18, { paddingX: 1, children: /* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "No epics" }) }) : visibleEpics.map((epic, i) => {
|
|
2218
2309
|
const actualIndex = viewStart + i;
|
|
2219
2310
|
const isSelected = actualIndex === selectedIndex && isFocused;
|
|
2220
2311
|
const isChecked = selectedEpicIds.has(epic.id);
|
|
@@ -2222,21 +2313,21 @@ function EpicPanel({
|
|
|
2222
2313
|
const statusColor = STATUS_COLOR[epic.status] ?? theme.table.fg;
|
|
2223
2314
|
if (isSelected) {
|
|
2224
2315
|
const cursorBg = isReordering ? theme.flash.warn : theme.table.cursorBg;
|
|
2225
|
-
return /* @__PURE__ */
|
|
2316
|
+
return /* @__PURE__ */ jsx18(Box18, { children: /* @__PURE__ */ jsxs15(Text18, { backgroundColor: cursorBg, color: theme.table.cursorFg, bold: true, children: [
|
|
2226
2317
|
isReordering ? "~ " : " ",
|
|
2227
2318
|
marker,
|
|
2228
2319
|
" ",
|
|
2229
2320
|
epic.name
|
|
2230
2321
|
] }) }, epic.id);
|
|
2231
2322
|
}
|
|
2232
|
-
return /* @__PURE__ */
|
|
2323
|
+
return /* @__PURE__ */ jsx18(Box18, { children: /* @__PURE__ */ jsxs15(Text18, { color: isChecked ? theme.titleHighlight : statusColor, children: [
|
|
2233
2324
|
" ",
|
|
2234
2325
|
marker,
|
|
2235
2326
|
" ",
|
|
2236
2327
|
epic.name
|
|
2237
2328
|
] }) }, epic.id);
|
|
2238
2329
|
}) }),
|
|
2239
|
-
epics.length > PAGE_SIZE2 && /* @__PURE__ */
|
|
2330
|
+
epics.length > PAGE_SIZE2 && /* @__PURE__ */ jsx18(Box18, { justifyContent: "flex-end", paddingRight: 1, children: /* @__PURE__ */ jsxs15(Text18, { dimColor: true, children: [
|
|
2240
2331
|
"[",
|
|
2241
2332
|
viewStart + 1,
|
|
2242
2333
|
"-",
|
|
@@ -2251,16 +2342,16 @@ function EpicPanel({
|
|
|
2251
2342
|
}
|
|
2252
2343
|
|
|
2253
2344
|
// src/tui/components/EpicPicker.tsx
|
|
2254
|
-
import { useState as
|
|
2255
|
-
import { Box as
|
|
2256
|
-
import { Fragment as
|
|
2345
|
+
import { useState as useState7 } from "react";
|
|
2346
|
+
import { Box as Box19, Text as Text19, useInput as useInput6, useStdout as useStdout3 } from "ink";
|
|
2347
|
+
import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2257
2348
|
function EpicPicker({ epics, currentEpicId, onSelect, onCancel }) {
|
|
2258
2349
|
const { stdout } = useStdout3();
|
|
2259
2350
|
const termHeight = stdout.rows > 0 ? stdout.rows : 24;
|
|
2260
2351
|
const maxVisible = Math.max(3, termHeight - 10);
|
|
2261
|
-
const [searchQuery, setSearchQuery] =
|
|
2262
|
-
const [isSearching, setIsSearching] =
|
|
2263
|
-
const [cursorIndex, setCursorIndex] =
|
|
2352
|
+
const [searchQuery, setSearchQuery] = useState7("");
|
|
2353
|
+
const [isSearching, setIsSearching] = useState7(false);
|
|
2354
|
+
const [cursorIndex, setCursorIndex] = useState7(0);
|
|
2264
2355
|
const filtered = epics.filter((e) => {
|
|
2265
2356
|
if (!searchQuery.trim()) return true;
|
|
2266
2357
|
const q = searchQuery.toLowerCase();
|
|
@@ -2326,53 +2417,53 @@ function EpicPicker({ epics, currentEpicId, onSelect, onCancel }) {
|
|
|
2326
2417
|
return;
|
|
2327
2418
|
}
|
|
2328
2419
|
});
|
|
2329
|
-
return /* @__PURE__ */
|
|
2330
|
-
/* @__PURE__ */
|
|
2331
|
-
/* @__PURE__ */
|
|
2420
|
+
return /* @__PURE__ */ jsxs16(Box19, { flexDirection: "column", borderStyle: "bold", borderColor: theme.borderFocus, flexGrow: 1, children: [
|
|
2421
|
+
/* @__PURE__ */ jsxs16(Box19, { gap: 0, children: [
|
|
2422
|
+
/* @__PURE__ */ jsxs16(Text19, { color: theme.title, bold: true, children: [
|
|
2332
2423
|
" ",
|
|
2333
2424
|
"assign to epic"
|
|
2334
2425
|
] }),
|
|
2335
|
-
/* @__PURE__ */
|
|
2426
|
+
/* @__PURE__ */ jsxs16(Text19, { color: theme.titleCounter, bold: true, children: [
|
|
2336
2427
|
" ",
|
|
2337
2428
|
"[",
|
|
2338
2429
|
epics.length,
|
|
2339
2430
|
"]"
|
|
2340
2431
|
] })
|
|
2341
2432
|
] }),
|
|
2342
|
-
isSearching ? /* @__PURE__ */
|
|
2343
|
-
/* @__PURE__ */
|
|
2344
|
-
/* @__PURE__ */
|
|
2345
|
-
/* @__PURE__ */
|
|
2346
|
-
] }) : searchQuery ? /* @__PURE__ */
|
|
2433
|
+
isSearching ? /* @__PURE__ */ jsxs16(Box19, { borderStyle: "round", borderColor: theme.prompt, paddingX: 1, children: [
|
|
2434
|
+
/* @__PURE__ */ jsx19(Text19, { color: theme.prompt, children: "/" }),
|
|
2435
|
+
/* @__PURE__ */ jsx19(Text19, { color: theme.prompt, children: searchQuery }),
|
|
2436
|
+
/* @__PURE__ */ jsx19(Text19, { color: theme.promptSuggest, children: "_" })
|
|
2437
|
+
] }) : searchQuery ? /* @__PURE__ */ jsx19(Box19, { paddingX: 1, children: /* @__PURE__ */ jsxs16(Text19, { color: theme.titleFilter, children: [
|
|
2347
2438
|
"/",
|
|
2348
2439
|
searchQuery
|
|
2349
2440
|
] }) }) : null,
|
|
2350
|
-
/* @__PURE__ */
|
|
2441
|
+
/* @__PURE__ */ jsx19(Box19, { paddingX: 1, children: /* @__PURE__ */ jsxs16(Text19, { color: theme.table.headerFg, bold: true, children: [
|
|
2351
2442
|
" ",
|
|
2352
2443
|
"ID".padEnd(14),
|
|
2353
2444
|
"STATUS".padEnd(14),
|
|
2354
2445
|
"NAME"
|
|
2355
2446
|
] }) }),
|
|
2356
|
-
filtered.length === 0 ? /* @__PURE__ */
|
|
2447
|
+
filtered.length === 0 ? /* @__PURE__ */ jsx19(Box19, { paddingX: 2, paddingY: 1, children: /* @__PURE__ */ jsx19(Text19, { dimColor: true, children: "No epics match the filter" }) }) : visible.map((epic, i) => {
|
|
2357
2448
|
const actualIndex = viewStart + i;
|
|
2358
2449
|
const isCursor = actualIndex === cursorIndex;
|
|
2359
2450
|
const isCurrent = epic.id === currentEpicId;
|
|
2360
2451
|
const marker = isCurrent ? "* " : " ";
|
|
2361
2452
|
const statusColor = STATUS_COLOR[epic.status] ?? theme.table.fg;
|
|
2362
|
-
return /* @__PURE__ */
|
|
2453
|
+
return /* @__PURE__ */ jsx19(Box19, { paddingX: 1, children: isCursor ? /* @__PURE__ */ jsxs16(Text19, { backgroundColor: theme.table.cursorBg, color: theme.table.cursorFg, bold: true, children: [
|
|
2363
2454
|
"> ",
|
|
2364
2455
|
epic.id.padEnd(14),
|
|
2365
2456
|
epic.status.padEnd(14),
|
|
2366
2457
|
epic.name
|
|
2367
|
-
] }) : /* @__PURE__ */
|
|
2368
|
-
/* @__PURE__ */
|
|
2369
|
-
/* @__PURE__ */
|
|
2370
|
-
/* @__PURE__ */
|
|
2371
|
-
/* @__PURE__ */
|
|
2458
|
+
] }) : /* @__PURE__ */ jsxs16(Fragment6, { children: [
|
|
2459
|
+
/* @__PURE__ */ jsx19(Text19, { color: isCurrent ? theme.titleHighlight : theme.table.fg, children: marker }),
|
|
2460
|
+
/* @__PURE__ */ jsx19(Text19, { color: theme.yaml.value, children: epic.id.padEnd(14) }),
|
|
2461
|
+
/* @__PURE__ */ jsx19(Text19, { color: statusColor, children: epic.status.padEnd(14) }),
|
|
2462
|
+
/* @__PURE__ */ jsx19(Text19, { color: isCurrent ? theme.titleHighlight : theme.table.fg, children: epic.name })
|
|
2372
2463
|
] }) }, epic.id);
|
|
2373
2464
|
}),
|
|
2374
|
-
/* @__PURE__ */
|
|
2375
|
-
filtered.length > maxVisible && /* @__PURE__ */
|
|
2465
|
+
/* @__PURE__ */ jsx19(Box19, { flexGrow: 1 }),
|
|
2466
|
+
filtered.length > maxVisible && /* @__PURE__ */ jsx19(Box19, { justifyContent: "flex-end", paddingRight: 1, children: /* @__PURE__ */ jsxs16(Text19, { dimColor: true, children: [
|
|
2376
2467
|
"[",
|
|
2377
2468
|
viewStart + 1,
|
|
2378
2469
|
"-",
|
|
@@ -2381,19 +2472,52 @@ function EpicPicker({ epics, currentEpicId, onSelect, onCancel }) {
|
|
|
2381
2472
|
filtered.length,
|
|
2382
2473
|
"]"
|
|
2383
2474
|
] }) }),
|
|
2384
|
-
/* @__PURE__ */
|
|
2475
|
+
/* @__PURE__ */ jsx19(Box19, { paddingX: 1, children: /* @__PURE__ */ jsx19(Text19, { dimColor: true, children: "enter: assign | x: unassign | /: search | esc: cancel" }) })
|
|
2385
2476
|
] });
|
|
2386
2477
|
}
|
|
2387
2478
|
|
|
2479
|
+
// src/tui/components/ChangelogBanner.tsx
|
|
2480
|
+
import { Box as Box20, Text as Text20 } from "ink";
|
|
2481
|
+
import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2482
|
+
function ChangelogBanner({ entries, currentIndex }) {
|
|
2483
|
+
const entry = entries[currentIndex];
|
|
2484
|
+
if (!entry) return null;
|
|
2485
|
+
const total = entries.length;
|
|
2486
|
+
return /* @__PURE__ */ jsxs17(
|
|
2487
|
+
Box20,
|
|
2488
|
+
{
|
|
2489
|
+
flexDirection: "column",
|
|
2490
|
+
borderStyle: "bold",
|
|
2491
|
+
borderColor: theme.borderFocus,
|
|
2492
|
+
paddingX: 3,
|
|
2493
|
+
paddingY: 1,
|
|
2494
|
+
gap: 1,
|
|
2495
|
+
alignSelf: "center",
|
|
2496
|
+
children: [
|
|
2497
|
+
/* @__PURE__ */ jsx20(Text20, { color: theme.dialog.label, bold: true, children: `<What's New \u2014 v${entry.version}${entry.date ? ` (${entry.date})` : ""}>` }),
|
|
2498
|
+
entry.sections.map((section) => /* @__PURE__ */ jsxs17(Box20, { flexDirection: "column", children: [
|
|
2499
|
+
/* @__PURE__ */ jsx20(Text20, { color: theme.table.headerFg, bold: true, children: `### ${section.heading}` }),
|
|
2500
|
+
section.items.map((item, i) => /* @__PURE__ */ jsx20(Text20, { color: theme.dialog.fg, children: `- ${item}` }, `${section.heading}-${i}`))
|
|
2501
|
+
] }, section.heading)),
|
|
2502
|
+
/* @__PURE__ */ jsxs17(Box20, { gap: 2, children: [
|
|
2503
|
+
/* @__PURE__ */ jsx20(Text20, { color: theme.fg, children: `[${currentIndex + 1}/${total}]` }),
|
|
2504
|
+
/* @__PURE__ */ jsx20(Text20, { color: theme.menu.desc, children: "\u2191/\u2193: navigate" }),
|
|
2505
|
+
/* @__PURE__ */ jsx20(Text20, { color: theme.menu.desc, children: "esc: close" })
|
|
2506
|
+
] })
|
|
2507
|
+
]
|
|
2508
|
+
}
|
|
2509
|
+
);
|
|
2510
|
+
}
|
|
2511
|
+
|
|
2388
2512
|
// src/tui/useAutoRefetch.ts
|
|
2389
|
-
import { useEffect as
|
|
2513
|
+
import { useEffect as useEffect4, useRef as useRef4 } from "react";
|
|
2390
2514
|
import { watchFile, unwatchFile } from "fs";
|
|
2391
2515
|
var POLL_INTERVAL_MS = 1e3;
|
|
2392
2516
|
var DEBOUNCE_MS = 200;
|
|
2393
2517
|
function useAutoRefetch(dbPath, onRefetch) {
|
|
2394
2518
|
const callbackRef = useRef4(onRefetch);
|
|
2395
2519
|
callbackRef.current = onRefetch;
|
|
2396
|
-
|
|
2520
|
+
useEffect4(() => {
|
|
2397
2521
|
let debounceTimer = null;
|
|
2398
2522
|
const handleChange = () => {
|
|
2399
2523
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
@@ -2420,8 +2544,47 @@ function useAutoRefetch(dbPath, onRefetch) {
|
|
|
2420
2544
|
}, [dbPath]);
|
|
2421
2545
|
}
|
|
2422
2546
|
|
|
2547
|
+
// src/changelog.ts
|
|
2548
|
+
var CHANGELOG_ENTRIES = typeof define_CHANGELOG_ENTRIES_default !== "undefined" ? define_CHANGELOG_ENTRIES_default : [];
|
|
2549
|
+
|
|
2550
|
+
// src/utils/changelog-seen.ts
|
|
2551
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
2552
|
+
function isValidSeenCache(value) {
|
|
2553
|
+
if (typeof value !== "object" || value === null) return false;
|
|
2554
|
+
return typeof value["changelogSeenVersion"] === "string";
|
|
2555
|
+
}
|
|
2556
|
+
function readSeenVersion(cachePath) {
|
|
2557
|
+
try {
|
|
2558
|
+
const raw = readFileSync3(cachePath, "utf-8");
|
|
2559
|
+
const parsed = JSON.parse(raw);
|
|
2560
|
+
if (isValidSeenCache(parsed)) return parsed.changelogSeenVersion;
|
|
2561
|
+
return null;
|
|
2562
|
+
} catch {
|
|
2563
|
+
logger.info("changelog-seen: cache not available", { path: cachePath });
|
|
2564
|
+
return null;
|
|
2565
|
+
}
|
|
2566
|
+
}
|
|
2567
|
+
function writeSeenVersion(cachePath, version) {
|
|
2568
|
+
try {
|
|
2569
|
+
let existing = {};
|
|
2570
|
+
try {
|
|
2571
|
+
const raw = readFileSync3(cachePath, "utf-8");
|
|
2572
|
+
const parsed = JSON.parse(raw);
|
|
2573
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
2574
|
+
existing = parsed;
|
|
2575
|
+
}
|
|
2576
|
+
} catch {
|
|
2577
|
+
}
|
|
2578
|
+
existing["changelogSeenVersion"] = version;
|
|
2579
|
+
writeFileSync4(cachePath, JSON.stringify(existing), "utf-8");
|
|
2580
|
+
logger.info("changelog-seen: persisted seen version", { version, path: cachePath });
|
|
2581
|
+
} catch {
|
|
2582
|
+
logger.warn("changelog-seen: failed to write seen version", { path: cachePath });
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
|
|
2423
2586
|
// src/tui/components/App.tsx
|
|
2424
|
-
import { jsx as
|
|
2587
|
+
import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2425
2588
|
var STATUS_CYCLE = [
|
|
2426
2589
|
TaskStatus.Backlog,
|
|
2427
2590
|
TaskStatus.Todo,
|
|
@@ -2434,8 +2597,8 @@ function App({ container, initialProject, latestVersion }) {
|
|
|
2434
2597
|
const { exit } = useApp();
|
|
2435
2598
|
const { stdout } = useStdout4();
|
|
2436
2599
|
const [state, dispatch] = useReducer(appReducer, initialState);
|
|
2437
|
-
const [, setResizeTick] =
|
|
2438
|
-
|
|
2600
|
+
const [, setResizeTick] = useState8(0);
|
|
2601
|
+
useEffect5(() => {
|
|
2439
2602
|
const onResize = () => {
|
|
2440
2603
|
setResizeTick((n) => n + 1);
|
|
2441
2604
|
};
|
|
@@ -2600,10 +2763,10 @@ function App({ container, initialProject, latestVersion }) {
|
|
|
2600
2763
|
loadEpics();
|
|
2601
2764
|
}, [loadProjects, loadTasks, loadEpics]);
|
|
2602
2765
|
useAutoRefetch(container.dbPath, refetchAll);
|
|
2603
|
-
|
|
2766
|
+
useEffect5(() => {
|
|
2604
2767
|
loadProjects();
|
|
2605
2768
|
}, [loadProjects]);
|
|
2606
|
-
|
|
2769
|
+
useEffect5(() => {
|
|
2607
2770
|
if (state.projects.length > 0 && !state.activeProject) {
|
|
2608
2771
|
logger.info(`TUI.resolveProject: resolving initialProject=${initialProject ?? "(default)"}`);
|
|
2609
2772
|
const result = container.projectService.resolveProject(initialProject);
|
|
@@ -2621,7 +2784,7 @@ function App({ container, initialProject, latestVersion }) {
|
|
|
2621
2784
|
}
|
|
2622
2785
|
}, [state.projects, state.activeProject, initialProject, container]);
|
|
2623
2786
|
const gitRemoteCheckedRef = useRef5(false);
|
|
2624
|
-
|
|
2787
|
+
useEffect5(() => {
|
|
2625
2788
|
if (state.projects.length > 0 && !gitRemoteCheckedRef.current && !initialProject) {
|
|
2626
2789
|
gitRemoteCheckedRef.current = true;
|
|
2627
2790
|
const remoteResult = detectGitRemote();
|
|
@@ -2636,13 +2799,31 @@ function App({ container, initialProject, latestVersion }) {
|
|
|
2636
2799
|
}
|
|
2637
2800
|
}
|
|
2638
2801
|
}, [state.projects, initialProject]);
|
|
2639
|
-
|
|
2802
|
+
const changelogCheckedRef = useRef5(false);
|
|
2803
|
+
useEffect5(() => {
|
|
2804
|
+
if (changelogCheckedRef.current) return;
|
|
2805
|
+
changelogCheckedRef.current = true;
|
|
2806
|
+
const seenVersion = readSeenVersion(container.updateCachePath);
|
|
2807
|
+
if (seenVersion !== APP_VERSION) {
|
|
2808
|
+
const newEntries = CHANGELOG_ENTRIES.filter(
|
|
2809
|
+
(e) => isNewerVersion(e.version, seenVersion ?? "0.0.0") && !isNewerVersion(e.version, APP_VERSION)
|
|
2810
|
+
);
|
|
2811
|
+
if (newEntries.length > 0) {
|
|
2812
|
+
logger.info(
|
|
2813
|
+
`TUI.changelog: showing ticker for [${newEntries.map((e) => e.version).join(", ")}] (last seen: ${seenVersion ?? "none"})`
|
|
2814
|
+
);
|
|
2815
|
+
dispatch({ type: "SET_CHANGELOG", entries: newEntries });
|
|
2816
|
+
writeSeenVersion(container.updateCachePath, APP_VERSION);
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
}, [container.updateCachePath]);
|
|
2820
|
+
useEffect5(() => {
|
|
2640
2821
|
if (state.activeProject) {
|
|
2641
2822
|
loadTasks();
|
|
2642
2823
|
loadEpics();
|
|
2643
2824
|
}
|
|
2644
2825
|
}, [state.activeProject, state.filter, loadTasks, loadEpics]);
|
|
2645
|
-
|
|
2826
|
+
useEffect5(() => {
|
|
2646
2827
|
if (state.flash) {
|
|
2647
2828
|
const timer = setTimeout(() => {
|
|
2648
2829
|
dispatch({ type: "CLEAR_FLASH" });
|
|
@@ -2654,6 +2835,21 @@ function App({ container, initialProject, latestVersion }) {
|
|
|
2654
2835
|
return void 0;
|
|
2655
2836
|
}, [state.flash]);
|
|
2656
2837
|
useInput7((input, key) => {
|
|
2838
|
+
if (state.changelogDialogOpen) {
|
|
2839
|
+
if (key.upArrow || input === "k") {
|
|
2840
|
+
dispatch({ type: "CHANGELOG_NAVIGATE", direction: "up" });
|
|
2841
|
+
return;
|
|
2842
|
+
}
|
|
2843
|
+
if (key.downArrow || input === "j") {
|
|
2844
|
+
dispatch({ type: "CHANGELOG_NAVIGATE", direction: "down" });
|
|
2845
|
+
return;
|
|
2846
|
+
}
|
|
2847
|
+
if (key.escape || input === "q" || input === "W") {
|
|
2848
|
+
dispatch({ type: "CLOSE_CHANGELOG_DIALOG" });
|
|
2849
|
+
return;
|
|
2850
|
+
}
|
|
2851
|
+
return;
|
|
2852
|
+
}
|
|
2657
2853
|
if (state.confirmDelete) {
|
|
2658
2854
|
if (input === "y") {
|
|
2659
2855
|
const result = container.taskService.deleteTask(state.confirmDelete.id);
|
|
@@ -3015,6 +3211,10 @@ function App({ container, initialProject, latestVersion }) {
|
|
|
3015
3211
|
dispatch({ type: "CLEAR_FILTER" });
|
|
3016
3212
|
return;
|
|
3017
3213
|
}
|
|
3214
|
+
if (input === "W" && state.changelogEntries) {
|
|
3215
|
+
dispatch({ type: "OPEN_CHANGELOG_DIALOG" });
|
|
3216
|
+
return;
|
|
3217
|
+
}
|
|
3018
3218
|
}
|
|
3019
3219
|
if (state.activeView === ViewType.TaskList && state.focusedPanel === "detail" && previewTask) {
|
|
3020
3220
|
if (key.upArrow || input === "k") {
|
|
@@ -3367,7 +3567,7 @@ ${state.selectedTask.additionalRequirements}`;
|
|
|
3367
3567
|
dispatch({ type: "GO_BACK" });
|
|
3368
3568
|
}, []);
|
|
3369
3569
|
const previewTask = state.tasks[state.selectedIndex] ?? null;
|
|
3370
|
-
const initialDepsForEdit =
|
|
3570
|
+
const initialDepsForEdit = useMemo3(() => {
|
|
3371
3571
|
return [
|
|
3372
3572
|
...state.depBlockers.map((t) => ({ id: t.id, name: t.name, type: DependencyType.Blocks })),
|
|
3373
3573
|
...state.depRelated.map((t) => ({ id: t.id, name: t.name, type: DependencyType.RelatesTo })),
|
|
@@ -3378,23 +3578,24 @@ ${state.selectedTask.additionalRequirements}`;
|
|
|
3378
3578
|
}))
|
|
3379
3579
|
];
|
|
3380
3580
|
}, [state.depBlockers, state.depRelated, state.depDuplicates]);
|
|
3381
|
-
const allProjectTasks =
|
|
3581
|
+
const allProjectTasks = useMemo3(() => {
|
|
3382
3582
|
if (!state.activeProject) return [];
|
|
3383
3583
|
const result = container.taskService.listTasks(state.activeProject, {});
|
|
3384
3584
|
return result.ok ? result.value : [];
|
|
3385
3585
|
}, [container, state.activeProject, state.tasks]);
|
|
3386
3586
|
const previewTaskId = previewTask?.id ?? null;
|
|
3387
|
-
|
|
3587
|
+
useEffect5(() => {
|
|
3388
3588
|
if (state.activeView === ViewType.TaskList && previewTaskId) {
|
|
3389
3589
|
loadDeps(previewTaskId);
|
|
3390
3590
|
}
|
|
3391
3591
|
}, [state.activeView, previewTaskId, loadDeps]);
|
|
3392
|
-
return /* @__PURE__ */
|
|
3393
|
-
/* @__PURE__ */
|
|
3394
|
-
/* @__PURE__ */
|
|
3395
|
-
state.confirmDelete && /* @__PURE__ */
|
|
3396
|
-
!state.confirmDelete && state.activeView === ViewType.TaskList &&
|
|
3397
|
-
|
|
3592
|
+
return /* @__PURE__ */ jsxs18(Box21, { flexDirection: "column", height: stdout.rows, children: [
|
|
3593
|
+
/* @__PURE__ */ jsx21(Header, { state, latestVersion }),
|
|
3594
|
+
/* @__PURE__ */ jsxs18(Box21, { flexDirection: "column", flexGrow: 1, overflowY: "hidden", children: [
|
|
3595
|
+
state.confirmDelete && /* @__PURE__ */ jsx21(ConfirmDialog, { task: state.confirmDelete }),
|
|
3596
|
+
!state.confirmDelete && state.changelogEntries && state.changelogDialogOpen && state.activeView === ViewType.TaskList && /* @__PURE__ */ jsx21(ChangelogBanner, { entries: state.changelogEntries, currentIndex: state.changelogIndex }),
|
|
3597
|
+
!state.confirmDelete && !state.changelogDialogOpen && state.activeView === ViewType.TaskList && (state.detectedGitRemote ? /* @__PURE__ */ jsx21(DetectedProjectDialog, { remote: state.detectedGitRemote }) : /* @__PURE__ */ jsxs18(Box21, { flexDirection: "row", flexGrow: 1, children: [
|
|
3598
|
+
/* @__PURE__ */ jsx21(
|
|
3398
3599
|
EpicPanel,
|
|
3399
3600
|
{
|
|
3400
3601
|
epics: state.epics,
|
|
@@ -3404,7 +3605,7 @@ ${state.selectedTask.additionalRequirements}`;
|
|
|
3404
3605
|
isReordering: state.isEpicReordering
|
|
3405
3606
|
}
|
|
3406
3607
|
),
|
|
3407
|
-
/* @__PURE__ */
|
|
3608
|
+
/* @__PURE__ */ jsx21(Box21, { width: taskListWidth, children: /* @__PURE__ */ jsx21(
|
|
3408
3609
|
TaskList,
|
|
3409
3610
|
{
|
|
3410
3611
|
tasks: state.tasks,
|
|
@@ -3425,7 +3626,7 @@ ${state.selectedTask.additionalRequirements}`;
|
|
|
3425
3626
|
epicFilterActive: state.selectedEpicIds.size > 0
|
|
3426
3627
|
}
|
|
3427
3628
|
) }),
|
|
3428
|
-
/* @__PURE__ */
|
|
3629
|
+
/* @__PURE__ */ jsx21(Box21, { width: taskDetailWidth, children: previewTask ? /* @__PURE__ */ jsx21(
|
|
3429
3630
|
TaskDetail,
|
|
3430
3631
|
{
|
|
3431
3632
|
task: previewTask,
|
|
@@ -3436,24 +3637,24 @@ ${state.selectedTask.additionalRequirements}`;
|
|
|
3436
3637
|
isFocused: state.focusedPanel === "detail",
|
|
3437
3638
|
scrollOffset: state.detailScrollOffset
|
|
3438
3639
|
}
|
|
3439
|
-
) : /* @__PURE__ */
|
|
3440
|
-
|
|
3640
|
+
) : /* @__PURE__ */ jsxs18(
|
|
3641
|
+
Box21,
|
|
3441
3642
|
{
|
|
3442
3643
|
flexDirection: "column",
|
|
3443
3644
|
flexGrow: 1,
|
|
3444
3645
|
borderStyle: "bold",
|
|
3445
3646
|
borderColor: theme.border,
|
|
3446
3647
|
children: [
|
|
3447
|
-
/* @__PURE__ */
|
|
3648
|
+
/* @__PURE__ */ jsx21(Box21, { children: /* @__PURE__ */ jsxs18(Text21, { color: theme.title, bold: true, children: [
|
|
3448
3649
|
" ",
|
|
3449
3650
|
"detail"
|
|
3450
3651
|
] }) }),
|
|
3451
|
-
/* @__PURE__ */
|
|
3652
|
+
/* @__PURE__ */ jsx21(Box21, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsx21(Text21, { dimColor: true, children: "No task selected" }) })
|
|
3452
3653
|
]
|
|
3453
3654
|
}
|
|
3454
3655
|
) })
|
|
3455
3656
|
] })),
|
|
3456
|
-
!state.confirmDelete && state.activeView === ViewType.TaskDetail && state.selectedTask && /* @__PURE__ */
|
|
3657
|
+
!state.confirmDelete && state.activeView === ViewType.TaskDetail && state.selectedTask && /* @__PURE__ */ jsx21(
|
|
3457
3658
|
TaskDetail,
|
|
3458
3659
|
{
|
|
3459
3660
|
task: state.selectedTask,
|
|
@@ -3464,7 +3665,7 @@ ${state.selectedTask.additionalRequirements}`;
|
|
|
3464
3665
|
scrollOffset: state.detailScrollOffset
|
|
3465
3666
|
}
|
|
3466
3667
|
),
|
|
3467
|
-
!state.confirmDelete && state.activeView === ViewType.DependencyList && state.selectedTask && /* @__PURE__ */
|
|
3668
|
+
!state.confirmDelete && state.activeView === ViewType.DependencyList && state.selectedTask && /* @__PURE__ */ jsx21(
|
|
3468
3669
|
DependencyList,
|
|
3469
3670
|
{
|
|
3470
3671
|
task: state.selectedTask,
|
|
@@ -3477,7 +3678,7 @@ ${state.selectedTask.additionalRequirements}`;
|
|
|
3477
3678
|
addDepInput: state.addDepInput
|
|
3478
3679
|
}
|
|
3479
3680
|
),
|
|
3480
|
-
!state.confirmDelete && (state.activeView === ViewType.TaskCreate || state.activeView === ViewType.TaskEdit) && /* @__PURE__ */
|
|
3681
|
+
!state.confirmDelete && (state.activeView === ViewType.TaskCreate || state.activeView === ViewType.TaskEdit) && /* @__PURE__ */ jsx21(
|
|
3481
3682
|
TaskForm,
|
|
3482
3683
|
{
|
|
3483
3684
|
editingTask: state.activeView === ViewType.TaskEdit ? state.selectedTask : null,
|
|
@@ -3487,7 +3688,7 @@ ${state.selectedTask.additionalRequirements}`;
|
|
|
3487
3688
|
onCancel: handleFormCancel
|
|
3488
3689
|
}
|
|
3489
3690
|
),
|
|
3490
|
-
!state.confirmDelete && state.activeView === ViewType.EpicPicker && state.selectedTask && /* @__PURE__ */
|
|
3691
|
+
!state.confirmDelete && state.activeView === ViewType.EpicPicker && state.selectedTask && /* @__PURE__ */ jsx21(
|
|
3491
3692
|
EpicPicker,
|
|
3492
3693
|
{
|
|
3493
3694
|
epics: state.epics,
|
|
@@ -3496,7 +3697,7 @@ ${state.selectedTask.additionalRequirements}`;
|
|
|
3496
3697
|
onCancel: handleEpicPickerCancel
|
|
3497
3698
|
}
|
|
3498
3699
|
),
|
|
3499
|
-
!state.confirmDelete && state.activeView === ViewType.ProjectSelector && /* @__PURE__ */
|
|
3700
|
+
!state.confirmDelete && state.activeView === ViewType.ProjectSelector && /* @__PURE__ */ jsx21(
|
|
3500
3701
|
ProjectSelector,
|
|
3501
3702
|
{
|
|
3502
3703
|
projects: state.projects,
|
|
@@ -3509,7 +3710,7 @@ ${state.selectedTask.additionalRequirements}`;
|
|
|
3509
3710
|
onCancel: handleProjectCancel
|
|
3510
3711
|
}
|
|
3511
3712
|
),
|
|
3512
|
-
!state.confirmDelete && state.activeView === ViewType.ProjectCreate && /* @__PURE__ */
|
|
3713
|
+
!state.confirmDelete && state.activeView === ViewType.ProjectCreate && /* @__PURE__ */ jsx21(
|
|
3513
3714
|
ProjectForm,
|
|
3514
3715
|
{
|
|
3515
3716
|
initialGitRemote: state.detectedGitRemote ?? void 0,
|
|
@@ -3517,7 +3718,7 @@ ${state.selectedTask.additionalRequirements}`;
|
|
|
3517
3718
|
onCancel: handleProjectFormCancel
|
|
3518
3719
|
}
|
|
3519
3720
|
),
|
|
3520
|
-
!state.confirmDelete && state.activeView === ViewType.ProjectEdit && state.editingProject && /* @__PURE__ */
|
|
3721
|
+
!state.confirmDelete && state.activeView === ViewType.ProjectEdit && state.editingProject && /* @__PURE__ */ jsx21(
|
|
3521
3722
|
ProjectForm,
|
|
3522
3723
|
{
|
|
3523
3724
|
editingProject: state.editingProject,
|
|
@@ -3525,7 +3726,7 @@ ${state.selectedTask.additionalRequirements}`;
|
|
|
3525
3726
|
onCancel: handleProjectFormCancel
|
|
3526
3727
|
}
|
|
3527
3728
|
),
|
|
3528
|
-
!state.confirmDelete && state.activeView === ViewType.ProjectLink && state.linkingProject && /* @__PURE__ */
|
|
3729
|
+
!state.confirmDelete && state.activeView === ViewType.ProjectLink && state.linkingProject && /* @__PURE__ */ jsx21(
|
|
3529
3730
|
ProjectLinkForm,
|
|
3530
3731
|
{
|
|
3531
3732
|
project: state.linkingProject,
|
|
@@ -3535,18 +3736,18 @@ ${state.selectedTask.additionalRequirements}`;
|
|
|
3535
3736
|
onCancel: handleLinkCancel
|
|
3536
3737
|
}
|
|
3537
3738
|
),
|
|
3538
|
-
!state.confirmDelete && state.activeView === ViewType.Help && /* @__PURE__ */
|
|
3739
|
+
!state.confirmDelete && state.activeView === ViewType.Help && /* @__PURE__ */ jsx21(HelpOverlay, {})
|
|
3539
3740
|
] }),
|
|
3540
|
-
/* @__PURE__ */
|
|
3541
|
-
state.flash && /* @__PURE__ */
|
|
3741
|
+
/* @__PURE__ */ jsx21(Crumbs, { breadcrumbs: state.breadcrumbs }),
|
|
3742
|
+
state.flash && /* @__PURE__ */ jsx21(FlashMessage, { message: state.flash.message, level: state.flash.level })
|
|
3542
3743
|
] });
|
|
3543
3744
|
}
|
|
3544
3745
|
|
|
3545
3746
|
// src/tui/index.tsx
|
|
3546
|
-
import { jsx as
|
|
3747
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
3547
3748
|
async function launchTUI(container, initialProject, latestVersion) {
|
|
3548
3749
|
const instance = render(
|
|
3549
|
-
/* @__PURE__ */
|
|
3750
|
+
/* @__PURE__ */ jsx22(App, { container, initialProject, latestVersion }),
|
|
3550
3751
|
{
|
|
3551
3752
|
exitOnCtrlC: true
|
|
3552
3753
|
}
|
|
@@ -3556,4 +3757,4 @@ async function launchTUI(container, initialProject, latestVersion) {
|
|
|
3556
3757
|
export {
|
|
3557
3758
|
launchTUI
|
|
3558
3759
|
};
|
|
3559
|
-
//# sourceMappingURL=tui-
|
|
3760
|
+
//# sourceMappingURL=tui-APMSKU4E.js.map
|