@tomkapa/tayto 0.5.4 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -425,53 +425,114 @@ var Logo = React.memo(function Logo2() {
425
425
 
426
426
  // src/tui/components/Header.tsx
427
427
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
428
- function getKeyHints(view, isSearchActive, focusedPanel) {
428
+ function getKeyHints(state) {
429
+ const { activeView, isSearchActive, isReordering, isEpicReordering, isAddingDep, focusedPanel } = state;
430
+ if (isAddingDep) {
431
+ return [
432
+ { key: "type", desc: "search" },
433
+ { key: "enter", desc: "confirm" },
434
+ { key: "esc", desc: "cancel" }
435
+ ];
436
+ }
437
+ const REORDER_SUFFIX = [
438
+ { key: "\u2192", desc: "save" },
439
+ { key: "t", desc: "top" },
440
+ { key: "b", desc: "bottom" },
441
+ { key: "esc/\u2190", desc: "cancel" }
442
+ ];
443
+ if (isReordering) return [{ key: "\u2191/\u2193", desc: "move" }, ...REORDER_SUFFIX];
444
+ if (isEpicReordering) return [{ key: "\u2191/\u2193", desc: "move epic" }, ...REORDER_SUFFIX];
429
445
  if (isSearchActive) {
430
446
  return [
447
+ { key: "type", desc: "query" },
431
448
  { key: "enter", desc: "apply" },
432
449
  { key: "esc", desc: "cancel" }
433
450
  ];
434
451
  }
435
- if (view === "task-list" && focusedPanel === "epic") {
452
+ if (activeView === ViewType.TaskList && focusedPanel === "epic") {
436
453
  return [
437
454
  { key: "j/k", desc: "nav" },
438
455
  { key: "space", desc: "toggle" },
439
- { key: "\u2190", desc: "reorder" },
440
456
  { key: "0", desc: "clear" },
441
- { key: "tab", desc: "tasks" },
457
+ { key: "\u2190", desc: "reorder" },
458
+ { key: "tab/S-tab", desc: "panel" },
442
459
  { key: "?", desc: "help" },
443
460
  { key: "q", desc: "quit" }
444
461
  ];
445
462
  }
446
- if (view === "task-list") {
463
+ if (activeView === ViewType.TaskList && focusedPanel === "detail") {
464
+ return [
465
+ { key: "j/k", desc: "scroll" },
466
+ { key: "e", desc: "edit" },
467
+ { key: "s", desc: "status" },
468
+ { key: "d", desc: "del" },
469
+ { key: "m", desc: "mermaid" },
470
+ { key: "D", desc: "deps" },
471
+ { key: "tab/S-tab", desc: "panel" },
472
+ { key: "?", desc: "help" }
473
+ ];
474
+ }
475
+ if (activeView === ViewType.TaskList) {
447
476
  return [
448
477
  { key: "enter", desc: "view" },
449
478
  { key: "c", desc: "create" },
450
479
  { key: "e", desc: "edit" },
451
480
  { key: "d", desc: "del" },
452
481
  { key: "s", desc: "status" },
453
- { key: "a", desc: "assign" },
454
- { key: "A", desc: "unassign" },
482
+ { key: "a/A", desc: "assign" },
455
483
  { key: "\u2190", desc: "reorder" },
456
484
  { key: "/", desc: "search" },
457
485
  { key: "p", desc: "project" },
458
- { key: "f", desc: "status-f" },
459
- { key: "t", desc: "type-f" },
486
+ { key: "f/t", desc: "filter" },
460
487
  { key: "PgDn/Up", desc: "page" },
461
- { key: "tab", desc: "panel" },
488
+ { key: "tab/S-tab", desc: "panel" },
462
489
  { key: "?", desc: "help" },
463
490
  { key: "q", desc: "quit" }
464
491
  ];
465
492
  }
466
- if (view === "task-detail") {
493
+ if (activeView === ViewType.TaskDetail) {
467
494
  return [
468
495
  { key: "e", desc: "edit" },
469
496
  { key: "s", desc: "status" },
470
497
  { key: "d", desc: "del" },
471
498
  { key: "m", desc: "mermaid" },
499
+ { key: "D", desc: "deps" },
500
+ { key: "j/k", desc: "scroll" },
472
501
  { key: "esc", desc: "back" },
473
- { key: "?", desc: "help" },
474
- { key: "q", desc: "quit" }
502
+ { key: "?", desc: "help" }
503
+ ];
504
+ }
505
+ if (activeView === ViewType.DependencyList) {
506
+ return [
507
+ { key: "a", desc: "add blocker" },
508
+ { key: "x", desc: "remove" },
509
+ { key: "enter", desc: "goto task" },
510
+ { key: "esc", desc: "back" },
511
+ { key: "?", desc: "help" }
512
+ ];
513
+ }
514
+ if (activeView === ViewType.TaskCreate || activeView === ViewType.TaskEdit) {
515
+ return [
516
+ { key: "tab", desc: "next field" },
517
+ { key: "ctrl+s", desc: "save" },
518
+ { key: "esc", desc: "cancel" }
519
+ ];
520
+ }
521
+ if (activeView === ViewType.ProjectSelector) {
522
+ return [
523
+ { key: "j/k", desc: "nav" },
524
+ { key: "enter", desc: "select" },
525
+ { key: "c", desc: "create" },
526
+ { key: "l", desc: "link" },
527
+ { key: "d", desc: "default" },
528
+ { key: "esc", desc: "back" }
529
+ ];
530
+ }
531
+ if (activeView === ViewType.EpicPicker) {
532
+ return [
533
+ { key: "j/k", desc: "nav" },
534
+ { key: "enter", desc: "select" },
535
+ { key: "esc", desc: "cancel" }
475
536
  ];
476
537
  }
477
538
  return [
@@ -488,10 +549,10 @@ function chunkHints(hints, cols) {
488
549
  }
489
550
  return result;
490
551
  }
491
- function Header({ state }) {
552
+ function Header({ state, latestVersion }) {
492
553
  const projectName = state.activeProject?.name ?? "none";
493
554
  const taskCount = state.tasks.length;
494
- const hints = getKeyHints(state.activeView, state.isSearchActive, state.focusedPanel);
555
+ const hints = getKeyHints(state);
495
556
  const hintCols = hints.length <= 7 ? 2 : hints.length <= 12 ? 3 : 4;
496
557
  const columns = chunkHints(hints, hintCols);
497
558
  return /* @__PURE__ */ jsxs(Box2, { flexDirection: "row", gap: 1, children: [
@@ -505,6 +566,13 @@ function Header({ state }) {
505
566
  /* @__PURE__ */ jsxs(Box2, { gap: 1, children: [
506
567
  /* @__PURE__ */ jsx2(Text2, { color: theme.fg, children: "Tasks:" }),
507
568
  /* @__PURE__ */ jsx2(Text2, { color: theme.titleCounter, bold: true, children: taskCount })
569
+ ] }),
570
+ latestVersion && /* @__PURE__ */ jsxs(Box2, { gap: 1, children: [
571
+ /* @__PURE__ */ jsxs(Text2, { color: theme.flash.warn, children: [
572
+ "Update ",
573
+ latestVersion
574
+ ] }),
575
+ /* @__PURE__ */ jsx2(Text2, { color: theme.fg, children: "\u2014 tayto upgrade" })
508
576
  ] })
509
577
  ] }),
510
578
  /* @__PURE__ */ jsx2(Box2, { flexGrow: 1, justifyContent: "flex-end", children: /* @__PURE__ */ jsx2(Box2, { flexDirection: "row", gap: 2, children: columns.map((col, ci) => /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", children: col.map((h) => /* @__PURE__ */ jsxs(Box2, { children: [
@@ -514,7 +582,7 @@ function Header({ state }) {
514
582
  ">"
515
583
  ] }),
516
584
  /* @__PURE__ */ jsx2(Text2, { color: theme.menu.desc, children: h.desc })
517
- ] }, h.key)) }, ci)) }) })
585
+ ] }, h.key)) }, col[0]?.key ?? String(ci))) }) })
518
586
  ] });
519
587
  }
520
588
 
@@ -1619,15 +1687,16 @@ function ProjectLinkForm({ project, onSave, onUnlink, onDetect, onCancel }) {
1619
1687
  // src/tui/components/HelpOverlay.tsx
1620
1688
  import { Box as Box13, Text as Text13 } from "ink";
1621
1689
  import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
1622
- var SECTIONS = [
1690
+ var ROW1 = [
1623
1691
  {
1624
1692
  title: "NAVIGATION",
1625
1693
  keys: [
1626
1694
  ["j/k", "Up/Down"],
1627
1695
  ["g/G", "Top/Bottom"],
1628
- ["PgDn", "Page down"],
1629
- ["PgUp", "Page up"],
1630
- ["enter", "View"],
1696
+ ["PgDn/Up", "Page"],
1697
+ ["tab", "Next panel"],
1698
+ ["S-tab", "Prev panel"],
1699
+ ["enter", "View/select"],
1631
1700
  ["esc", "Back"]
1632
1701
  ]
1633
1702
  },
@@ -1638,14 +1707,16 @@ var SECTIONS = [
1638
1707
  ["e", "Edit"],
1639
1708
  ["d", "Delete"],
1640
1709
  ["s", "Status cycle"],
1641
- ["D", "Dependencies"]
1710
+ ["a/A", "Assign/unassign"],
1711
+ ["D", "Dependencies"],
1712
+ ["m", "Mermaid"]
1642
1713
  ]
1643
1714
  },
1644
1715
  {
1645
1716
  title: "REORDER",
1646
1717
  keys: [
1647
1718
  ["\u2190", "Enter reorder"],
1648
- ["\u2191\u2193", "Move task"],
1719
+ ["\u2191\u2193", "Move item"],
1649
1720
  ["t", "Jump to top"],
1650
1721
  ["b", "Jump to bottom"],
1651
1722
  ["\u2192", "Save position"],
@@ -1660,6 +1731,17 @@ var SECTIONS = [
1660
1731
  ["t", "Type filter"],
1661
1732
  ["0", "Clear filters"]
1662
1733
  ]
1734
+ }
1735
+ ];
1736
+ var ROW2 = [
1737
+ {
1738
+ title: "EPIC PANEL",
1739
+ keys: [
1740
+ ["j/k", "Navigate"],
1741
+ ["space", "Toggle filter"],
1742
+ ["0", "Clear filter"],
1743
+ ["\u2190", "Reorder epics"]
1744
+ ]
1663
1745
  },
1664
1746
  {
1665
1747
  title: "DEPS VIEW",
@@ -1670,6 +1752,16 @@ var SECTIONS = [
1670
1752
  ["esc", "Back"]
1671
1753
  ]
1672
1754
  },
1755
+ {
1756
+ title: "FORMS",
1757
+ keys: [
1758
+ ["tab", "Next field"],
1759
+ ["shift+tab", "Prev field"],
1760
+ ["ctrl+s", "Save"],
1761
+ ["enter", "Open editor"],
1762
+ ["esc", "Cancel"]
1763
+ ]
1764
+ },
1673
1765
  {
1674
1766
  title: "GENERAL",
1675
1767
  keys: [
@@ -1679,6 +1771,19 @@ var SECTIONS = [
1679
1771
  ]
1680
1772
  }
1681
1773
  ];
1774
+ function SectionRow({ sections }) {
1775
+ return /* @__PURE__ */ jsx13(Box13, { flexDirection: "row", gap: 4, children: sections.map((section) => /* @__PURE__ */ jsxs10(Box13, { flexDirection: "column", children: [
1776
+ /* @__PURE__ */ jsx13(Text13, { color: theme.table.headerFg, bold: true, children: section.title }),
1777
+ section.keys.map(([key, desc]) => /* @__PURE__ */ jsxs10(Box13, { gap: 1, children: [
1778
+ /* @__PURE__ */ jsxs10(Text13, { color: theme.menu.key, bold: true, children: [
1779
+ "<",
1780
+ key.padEnd(5),
1781
+ ">"
1782
+ ] }),
1783
+ /* @__PURE__ */ jsx13(Text13, { dimColor: true, children: desc })
1784
+ ] }, key))
1785
+ ] }, section.title)) });
1786
+ }
1682
1787
  function HelpOverlay() {
1683
1788
  return /* @__PURE__ */ jsxs10(
1684
1789
  Box13,
@@ -1694,17 +1799,10 @@ function HelpOverlay() {
1694
1799
  "Help"
1695
1800
  ] }),
1696
1801
  /* @__PURE__ */ jsx13(Text13, { children: " " }),
1697
- /* @__PURE__ */ jsx13(Box13, { flexDirection: "row", gap: 4, children: SECTIONS.map((section) => /* @__PURE__ */ jsxs10(Box13, { flexDirection: "column", children: [
1698
- /* @__PURE__ */ jsx13(Text13, { color: theme.table.headerFg, bold: true, children: section.title }),
1699
- section.keys.map(([key, desc]) => /* @__PURE__ */ jsxs10(Box13, { gap: 1, children: [
1700
- /* @__PURE__ */ jsxs10(Text13, { color: theme.menu.key, bold: true, children: [
1701
- "<",
1702
- (key ?? "").padEnd(5),
1703
- ">"
1704
- ] }),
1705
- /* @__PURE__ */ jsx13(Text13, { dimColor: true, children: desc })
1706
- ] }, key))
1707
- ] }, section.title)) }),
1802
+ /* @__PURE__ */ jsxs10(Box13, { flexDirection: "column", gap: 1, children: [
1803
+ /* @__PURE__ */ jsx13(SectionRow, { sections: ROW1 }),
1804
+ /* @__PURE__ */ jsx13(SectionRow, { sections: ROW2 })
1805
+ ] }),
1708
1806
  /* @__PURE__ */ jsx13(Text13, { children: " " }),
1709
1807
  /* @__PURE__ */ jsx13(Text13, { dimColor: true, children: "Press any key to close" })
1710
1808
  ]
@@ -2133,7 +2231,7 @@ var STATUS_CYCLE = [
2133
2231
  TaskStatus.Done
2134
2232
  ];
2135
2233
  var EPIC_PANEL_WIDTH = 48;
2136
- function App({ container, initialProject }) {
2234
+ function App({ container, initialProject, latestVersion }) {
2137
2235
  const { exit } = useApp();
2138
2236
  const { stdout } = useStdout4();
2139
2237
  const [state, dispatch] = useReducer(appReducer, initialState);
@@ -2511,7 +2609,8 @@ function App({ container, initialProject }) {
2511
2609
  if (key.tab && state.activeView === ViewType.TaskList) {
2512
2610
  const panels = previewTask ? ["epic", "list", "detail"] : ["epic", "list"];
2513
2611
  const curIdx = panels.indexOf(state.focusedPanel);
2514
- const nextPanel = panels[(curIdx + 1) % panels.length] ?? "list";
2612
+ const delta = key.shift ? -1 : 1;
2613
+ const nextPanel = panels[(curIdx + delta + panels.length) % panels.length] ?? "list";
2515
2614
  dispatch({ type: "SET_PANEL_FOCUS", panel: nextPanel });
2516
2615
  return;
2517
2616
  }
@@ -3045,7 +3144,7 @@ ${state.selectedTask.additionalRequirements}`;
3045
3144
  }
3046
3145
  }, [state.activeView, previewTaskId, loadDeps]);
3047
3146
  return /* @__PURE__ */ jsxs15(Box18, { flexDirection: "column", height: stdout.rows, children: [
3048
- /* @__PURE__ */ jsx18(Header, { state }),
3147
+ /* @__PURE__ */ jsx18(Header, { state, latestVersion }),
3049
3148
  /* @__PURE__ */ jsxs15(Box18, { flexDirection: "column", flexGrow: 1, overflowY: "hidden", children: [
3050
3149
  state.confirmDelete && /* @__PURE__ */ jsx18(ConfirmDialog, { task: state.confirmDelete }),
3051
3150
  !state.confirmDelete && state.activeView === ViewType.TaskList && /* @__PURE__ */ jsxs15(Box18, { flexDirection: "row", flexGrow: 1, children: [
@@ -3183,13 +3282,16 @@ ${state.selectedTask.additionalRequirements}`;
3183
3282
 
3184
3283
  // src/tui/index.tsx
3185
3284
  import { jsx as jsx19 } from "react/jsx-runtime";
3186
- async function launchTUI(container, initialProject) {
3187
- const instance = render(/* @__PURE__ */ jsx19(App, { container, initialProject }), {
3188
- exitOnCtrlC: true
3189
- });
3285
+ async function launchTUI(container, initialProject, latestVersion) {
3286
+ const instance = render(
3287
+ /* @__PURE__ */ jsx19(App, { container, initialProject, latestVersion }),
3288
+ {
3289
+ exitOnCtrlC: true
3290
+ }
3291
+ );
3190
3292
  await instance.waitUntilExit();
3191
3293
  }
3192
3294
  export {
3193
3295
  launchTUI
3194
3296
  };
3195
- //# sourceMappingURL=tui-24ZW56Q6.js.map
3297
+ //# sourceMappingURL=tui-WMESKCRD.js.map