kandown 0.4.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/tui.js CHANGED
@@ -27895,7 +27895,7 @@ var require_backend = __commonJS({
27895
27895
  });
27896
27896
  return value;
27897
27897
  },
27898
- useEffect: function useEffect9(create3) {
27898
+ useEffect: function useEffect10(create3) {
27899
27899
  nextHook();
27900
27900
  hookLog.push({
27901
27901
  displayName: null,
@@ -27968,7 +27968,7 @@ var require_backend = __commonJS({
27968
27968
  return [initialArg, function() {
27969
27969
  }];
27970
27970
  },
27971
- useRef: function useRef5(initialValue) {
27971
+ useRef: function useRef6(initialValue) {
27972
27972
  var hook = nextHook();
27973
27973
  initialValue = null !== hook ? hook.memoizedState : {
27974
27974
  current: initialValue
@@ -27983,7 +27983,7 @@ var require_backend = __commonJS({
27983
27983
  });
27984
27984
  return initialValue;
27985
27985
  },
27986
- useState: function useState9(initialState) {
27986
+ useState: function useState10(initialState) {
27987
27987
  var hook = nextHook();
27988
27988
  initialState = null !== hook ? hook.memoizedState : "function" === typeof initialState ? initialState() : initialState;
27989
27989
  hookLog.push({
@@ -54326,7 +54326,7 @@ function ValueDisplay({ setting, value, focused }) {
54326
54326
  }
54327
54327
 
54328
54328
  // src/cli/screens/board.tsx
54329
- var import_react36 = __toESM(require_react(), 1);
54329
+ var import_react38 = __toESM(require_react(), 1);
54330
54330
 
54331
54331
  // src/cli/lib/board-reader.ts
54332
54332
  import { existsSync as existsSync3, readdirSync, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
@@ -56755,8 +56755,224 @@ function AgentPicker({ agents, taskId, onSelect, onCancel }) {
56755
56755
  );
56756
56756
  }
56757
56757
 
56758
- // src/cli/screens/board.tsx
56758
+ // src/cli/hooks/use-mouse.ts
56759
+ var import_react36 = __toESM(require_react(), 1);
56760
+ var MOUSE_ENABLE_X10 = "\x1B[?1000h";
56761
+ var MOUSE_DISABLE_X10 = "\x1B[?1000l";
56762
+ var MOUSE_ENABLE_SGR = "\x1B[?1006h";
56763
+ var MOUSE_DISABLE_SGR = "\x1B[?1006l";
56764
+ function parseSGRMouse(buffer) {
56765
+ const sgrRegex = /^\x1b\[<(\d+);(\d+);(\d+)([Mm])/;
56766
+ const match = buffer.match(sgrRegex);
56767
+ if (!match) return null;
56768
+ const cb = parseInt(match[1], 10);
56769
+ const cx = parseInt(match[2], 10);
56770
+ const cy = parseInt(match[3], 10);
56771
+ const isPress = match[4] === "M";
56772
+ const button = cb & 3;
56773
+ const shift = (cb & 4) !== 0;
56774
+ const meta = (cb & 8) !== 0;
56775
+ const ctrl = (cb & 16) !== 0;
56776
+ return {
56777
+ event: {
56778
+ x: cx,
56779
+ y: cy,
56780
+ button,
56781
+ action: isPress ? "press" : "release",
56782
+ shift,
56783
+ meta,
56784
+ ctrl
56785
+ },
56786
+ endIndex: match[0].length
56787
+ };
56788
+ }
56789
+ function parseX10Mouse(buffer) {
56790
+ if (!buffer.startsWith("\x1B[M")) return null;
56791
+ if (buffer.length < 6) return null;
56792
+ const cb = buffer.charCodeAt(3) - 32;
56793
+ const cx = buffer.charCodeAt(4) - 32;
56794
+ const cy = buffer.charCodeAt(5) - 32;
56795
+ if (cb < 0 || cx < 0 || cy < 0) return null;
56796
+ const button = cb & 3;
56797
+ const shift = (cb & 4) !== 0;
56798
+ const meta = (cb & 8) !== 0;
56799
+ const ctrl = (cb & 16) !== 0;
56800
+ return {
56801
+ event: {
56802
+ x: cx,
56803
+ y: cy,
56804
+ button,
56805
+ action: "press",
56806
+ // X10 only reports press
56807
+ shift,
56808
+ meta,
56809
+ ctrl
56810
+ },
56811
+ endIndex: 6
56812
+ };
56813
+ }
56814
+ function useMouse(handler, options = {}) {
56815
+ const { enabled = true, pressOnly = true } = options;
56816
+ const handlerRef = (0, import_react36.useRef)(handler);
56817
+ handlerRef.current = handler;
56818
+ (0, import_react36.useEffect)(() => {
56819
+ if (!enabled) return;
56820
+ const stdin = process.stdin;
56821
+ if (!stdin.isTTY) return;
56822
+ process.stdout.write(MOUSE_ENABLE_SGR + MOUSE_ENABLE_X10);
56823
+ let buffer = "";
56824
+ const onData = (data) => {
56825
+ buffer += data.toString("utf8");
56826
+ while (buffer.length > 0) {
56827
+ let parsed = parseSGRMouse(buffer);
56828
+ if (!parsed) {
56829
+ parsed = parseX10Mouse(buffer);
56830
+ }
56831
+ if (parsed) {
56832
+ const { event, endIndex } = parsed;
56833
+ buffer = buffer.slice(endIndex);
56834
+ if (pressOnly && event.action === "release") continue;
56835
+ if (event.button === 3 && event.action === "press") continue;
56836
+ handlerRef.current(event);
56837
+ } else if (buffer.startsWith("\x1B[")) {
56838
+ if (buffer.length >= 3 && buffer[2] !== "<" && buffer[2] !== "M") {
56839
+ const leftover = buffer;
56840
+ buffer = "";
56841
+ stdin.unshift(Buffer.from(leftover, "utf8"));
56842
+ break;
56843
+ }
56844
+ if (buffer.length > 32) {
56845
+ const leftover = buffer;
56846
+ buffer = "";
56847
+ stdin.unshift(Buffer.from(leftover, "utf8"));
56848
+ }
56849
+ break;
56850
+ } else if (buffer.startsWith("\x1B") && buffer.length > 1 && buffer[1] !== "[") {
56851
+ const leftover = buffer;
56852
+ buffer = "";
56853
+ stdin.unshift(Buffer.from(leftover, "utf8"));
56854
+ break;
56855
+ } else if (buffer.startsWith("\x1B") && buffer.length === 1) {
56856
+ break;
56857
+ } else {
56858
+ const leftover = buffer;
56859
+ buffer = "";
56860
+ stdin.unshift(Buffer.from(leftover, "utf8"));
56861
+ break;
56862
+ }
56863
+ }
56864
+ if (buffer.length > 256) {
56865
+ const leftover = buffer;
56866
+ buffer = "";
56867
+ stdin.unshift(Buffer.from(leftover, "utf8"));
56868
+ }
56869
+ };
56870
+ stdin.prependListener("data", onData);
56871
+ const cleanup = () => {
56872
+ process.stdout.write(MOUSE_DISABLE_SGR + MOUSE_DISABLE_X10);
56873
+ };
56874
+ process.on("exit", cleanup);
56875
+ return () => {
56876
+ stdin.removeListener("data", onData);
56877
+ process.removeListener("exit", cleanup);
56878
+ process.stdout.write(MOUSE_DISABLE_SGR + MOUSE_DISABLE_X10);
56879
+ };
56880
+ }, [enabled, pressOnly]);
56881
+ }
56882
+
56883
+ // src/cli/components/task-context-menu.tsx
56884
+ var import_react37 = __toESM(require_react(), 1);
56759
56885
  var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
56886
+ function TaskContextMenu({
56887
+ taskId,
56888
+ options,
56889
+ onSelect,
56890
+ onCancel,
56891
+ mouseX,
56892
+ mouseY,
56893
+ onMouseClick,
56894
+ menuStartRow
56895
+ }) {
56896
+ const [cursor, setCursor] = (0, import_react37.useState)(0);
56897
+ use_input_default((input, key) => {
56898
+ if (key.escape || input === "q") {
56899
+ onCancel();
56900
+ return;
56901
+ }
56902
+ if (key.downArrow || input === "j") {
56903
+ setCursor((c) => Math.min(c + 1, options.length - 1));
56904
+ return;
56905
+ }
56906
+ if (key.upArrow || input === "k") {
56907
+ setCursor((c) => Math.max(c - 1, 0));
56908
+ return;
56909
+ }
56910
+ if (key.return) {
56911
+ const opt = options[cursor];
56912
+ if (opt) onSelect(opt.id);
56913
+ return;
56914
+ }
56915
+ });
56916
+ const maxLabelLen = Math.max(...options.map((o) => o.label.length));
56917
+ const menuWidth = Math.max(24, maxLabelLen + 8);
56918
+ const lines = [];
56919
+ const startRow = menuStartRow ?? 0;
56920
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
56921
+ Box_default,
56922
+ {
56923
+ flexDirection: "column",
56924
+ paddingLeft: 2,
56925
+ marginTop: 0,
56926
+ children: [
56927
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { children: [
56928
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "gray", dimColor: true, children: "\u250C\u2500 " }),
56929
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "cyan", bold: true, children: taskId }),
56930
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "gray", dimColor: true, children: " \u2500\u2510" })
56931
+ ] }),
56932
+ options.map((opt, idx) => {
56933
+ const focused = idx === cursor;
56934
+ const lineY = startRow + 1 + idx;
56935
+ lines.push({ optionId: opt.id, y: lineY });
56936
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { children: [
56937
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "gray", dimColor: true, children: "\u2502 " }),
56938
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
56939
+ Text,
56940
+ {
56941
+ color: focused ? "black" : "gray",
56942
+ backgroundColor: focused ? "cyan" : void 0,
56943
+ bold: focused,
56944
+ children: [
56945
+ focused ? "\u25B8" : " ",
56946
+ " ",
56947
+ opt.icon,
56948
+ " ",
56949
+ opt.label
56950
+ ]
56951
+ }
56952
+ ),
56953
+ !focused && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: "gray", dimColor: true, children: [
56954
+ " ".repeat(Math.max(0, menuWidth - opt.label.length - 4)),
56955
+ "\u2502"
56956
+ ] }),
56957
+ focused && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: "gray", dimColor: true, children: [
56958
+ " ".repeat(Math.max(0, menuWidth - opt.label.length - 4)),
56959
+ "\u2502"
56960
+ ] })
56961
+ ] }, opt.id);
56962
+ }),
56963
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: "gray", dimColor: true, children: [
56964
+ "\u2514",
56965
+ "\u2500".repeat(menuWidth),
56966
+ "\u2518"
56967
+ ] }) })
56968
+ ]
56969
+ }
56970
+ );
56971
+ }
56972
+
56973
+ // src/cli/screens/board.tsx
56974
+ var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
56975
+ var HEADER_LINES = 4;
56760
56976
  function truncate(str, maxLen) {
56761
56977
  if (str.length <= maxLen) return str;
56762
56978
  return str.slice(0, maxLen - 1) + "\u2026";
@@ -56791,44 +57007,65 @@ function TaskRow({
56791
57007
  const tagChars = tag ? tag.length + 1 : 0;
56792
57008
  const available = colWidth - fixedChars - tagChars;
56793
57009
  const titleStr = truncate(titleWithoutTag, Math.max(4, available));
56794
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { children: [
56795
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: focused ? "cyan" : void 0, bold: focused, children: [
57010
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { children: [
57011
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: focused ? "cyan" : void 0, bold: focused, children: [
56796
57012
  cursor,
56797
57013
  " "
56798
57014
  ] }),
56799
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: task.checked ? "green" : focused ? "white" : "gray", children: [
57015
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: task.checked ? "green" : focused ? "white" : "gray", children: [
56800
57016
  check2,
56801
57017
  " "
56802
57018
  ] }),
56803
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: focused ? "cyan" : "yellow", bold: focused, children: idStr }),
56804
- tag && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: focused ? "white" : "magenta", bold: true, children: [
57019
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: focused ? "cyan" : "yellow", bold: focused, children: idStr }),
57020
+ tag && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: focused ? "white" : "magenta", bold: true, children: [
56805
57021
  " ",
56806
57022
  tag
56807
57023
  ] }),
56808
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: focused ? "white" : "gray", children: [
57024
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: focused ? "white" : "gray", children: [
56809
57025
  " ",
56810
57026
  titleStr
56811
57027
  ] })
56812
57028
  ] });
56813
57029
  }
57030
+ function MovePlaceholder({
57031
+ name,
57032
+ focused,
57033
+ colWidth
57034
+ }) {
57035
+ const label = `\u2193 ${name}`;
57036
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
57037
+ Text,
57038
+ {
57039
+ color: focused ? "black" : "yellow",
57040
+ backgroundColor: focused ? "yellow" : void 0,
57041
+ bold: focused,
57042
+ children: [
57043
+ " ",
57044
+ pad(label, colWidth - 2)
57045
+ ]
57046
+ }
57047
+ ) });
57048
+ }
56814
57049
  function KanbanColumn({
56815
57050
  name,
56816
57051
  tasks,
56817
57052
  focusedRow,
56818
57053
  isFocused,
56819
- colWidth
57054
+ colWidth,
57055
+ showMoveTarget,
57056
+ isMoveFocused
56820
57057
  }) {
56821
57058
  const headerBg = isFocused ? "cyan" : void 0;
56822
57059
  const headerColor = isFocused ? "black" : "cyan";
56823
57060
  const countStr = tasks.length > 0 ? ` (${tasks.length})` : "";
56824
57061
  const headerText = truncate(`${name}${countStr}`, colWidth);
56825
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { flexDirection: "column", width: colWidth, marginRight: 1, children: [
56826
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { backgroundColor: headerBg, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: headerColor, bold: true, children: pad(headerText, colWidth) }) }),
56827
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: isFocused ? "cyan" : "gray", children: "\u2500".repeat(colWidth) }),
56828
- tasks.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: "gray", dimColor: true, children: [
57062
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { flexDirection: "column", width: colWidth, marginRight: 1, children: [
57063
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { backgroundColor: headerBg, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: headerColor, bold: true, children: pad(headerText, colWidth) }) }),
57064
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: isFocused ? "cyan" : "gray", children: "\u2500".repeat(colWidth) }),
57065
+ tasks.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: "gray", dimColor: true, children: [
56829
57066
  " ".repeat(2),
56830
57067
  "(empty)"
56831
- ] }) : tasks.map((task, idx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
57068
+ ] }) : tasks.map((task, idx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
56832
57069
  TaskRow,
56833
57070
  {
56834
57071
  task,
@@ -56836,28 +57073,32 @@ function KanbanColumn({
56836
57073
  colWidth
56837
57074
  },
56838
57075
  task.id
56839
- ))
57076
+ )),
57077
+ showMoveTarget && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MovePlaceholder, { name, focused: !!isMoveFocused, colWidth })
56840
57078
  ] });
56841
57079
  }
56842
- function BoardHeader({ title, inTmux }) {
57080
+ function BoardHeader({ title, inTmux, modeHint, version }) {
56843
57081
  const tmuxHint = inTmux ? " tmux" : "";
56844
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { marginBottom: 1, justifyContent: "space-between", children: [
56845
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { bold: true, color: "cyan", children: [
57082
+ const hint = modeHint || "h/l cols j/k tasks Enter detail a agent r reload q quit";
57083
+ const versionTag = version ? ` v${version}` : "";
57084
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { marginBottom: 1, justifyContent: "space-between", children: [
57085
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { bold: true, color: "cyan", children: [
56846
57086
  " ",
56847
57087
  "KANDOWN",
56848
57088
  tmuxHint,
57089
+ versionTag,
56849
57090
  " ",
56850
57091
  title
56851
57092
  ] }),
56852
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "gray", dimColor: true, children: "h/l cols j/k tasks Enter detail a agent r reload q quit" })
57093
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "gray", dimColor: true, children: hint })
56853
57094
  ] });
56854
57095
  }
56855
57096
  function StatusBar({ message, task }) {
56856
57097
  if (message) {
56857
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "yellow", children: message }) });
57098
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "yellow", children: message }) });
56858
57099
  }
56859
- if (!task) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "gray", children: " " }) });
56860
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: "gray", children: [
57100
+ if (!task) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "gray", children: " " }) });
57101
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: "gray", children: [
56861
57102
  task.id.replace(/^t/, ""),
56862
57103
  task.progress ? ` (${task.progress.done}/${task.progress.total})` : "",
56863
57104
  " ",
@@ -56873,27 +57114,27 @@ function TaskDetail({
56873
57114
  const bodyLines = task.body.split("\n");
56874
57115
  const maxVisible = (process.stdout.rows || 24) - 10;
56875
57116
  const visibleLines = bodyLines.slice(scrollOffset, scrollOffset + maxVisible);
56876
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { flexDirection: "column", paddingX: 2, children: [
56877
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { marginBottom: 1, children: [
56878
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { bold: true, color: "cyan", children: taskId }),
56879
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: "white", bold: true, children: [
57117
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { flexDirection: "column", paddingX: 2, children: [
57118
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { marginBottom: 1, children: [
57119
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { bold: true, color: "cyan", children: taskId }),
57120
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: "white", bold: true, children: [
56880
57121
  " ",
56881
57122
  fm.title
56882
57123
  ] })
56883
57124
  ] }),
56884
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: "gray", children: [
57125
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: "gray", children: [
56885
57126
  "status: ",
56886
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "yellow", children: fm.status ?? "\u2014" }),
57127
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "yellow", children: fm.status ?? "\u2014" }),
56887
57128
  fm.priority ? ` priority: ${fm.priority}` : "",
56888
57129
  fm.assignee ? ` assignee: ${fm.assignee}` : "",
56889
57130
  fm.due ? ` due: ${fm.due}` : ""
56890
57131
  ] }) }),
56891
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "gray", children: "\u2500".repeat(termWidth() - 4) }),
57132
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "gray", children: "\u2500".repeat(termWidth() - 4) }),
56892
57133
  visibleLines.map((line, idx) => {
56893
57134
  const isHeader = RE_HEADER.test(line);
56894
57135
  const isSubtask = RE_SUBTASK.test(line);
56895
57136
  const isDone = RE_DONE_SUBTASK.test(line);
56896
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
57137
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
56897
57138
  Text,
56898
57139
  {
56899
57140
  color: isHeader ? "cyan" : isDone ? "green" : isSubtask ? "white" : "gray",
@@ -56903,7 +57144,7 @@ function TaskDetail({
56903
57144
  scrollOffset + idx
56904
57145
  );
56905
57146
  }),
56906
- bodyLines.length > maxVisible && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: "gray", dimColor: true, children: [
57147
+ bodyLines.length > maxVisible && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: "gray", dimColor: true, children: [
56907
57148
  " ",
56908
57149
  "\u2191\u2193 scroll (",
56909
57150
  scrollOffset + 1,
@@ -56915,66 +57156,92 @@ function TaskDetail({
56915
57156
  ] })
56916
57157
  ] });
56917
57158
  }
56918
- function Board({ kandownDir }) {
57159
+ function Board({ kandownDir, version }) {
56919
57160
  const { exit } = use_app_default();
56920
- const [board, setBoard] = (0, import_react36.useState)(null);
56921
- const [colIndex, setColIndex] = (0, import_react36.useState)(0);
56922
- const [rowIndex, setRowIndex] = (0, import_react36.useState)(0);
56923
- const [mode, setMode] = (0, import_react36.useState)("browse");
56924
- const [detailTask, setDetailTask] = (0, import_react36.useState)(null);
56925
- const [detailTaskId, setDetailTaskId] = (0, import_react36.useState)("");
56926
- const [detailScroll, setDetailScroll] = (0, import_react36.useState)(0);
56927
- const [installedAgents, setInstalledAgents] = (0, import_react36.useState)([]);
56928
- const [statusMsg, setStatusMsg] = (0, import_react36.useState)("");
57161
+ const [board, setBoard] = (0, import_react38.useState)(null);
57162
+ const [colIndex, setColIndex] = (0, import_react38.useState)(0);
57163
+ const [rowIndex, setRowIndex] = (0, import_react38.useState)(0);
57164
+ const [mode, setMode] = (0, import_react38.useState)("browse");
57165
+ const [detailTask, setDetailTask] = (0, import_react38.useState)(null);
57166
+ const [detailTaskId, setDetailTaskId] = (0, import_react38.useState)("");
57167
+ const [detailScroll, setDetailScroll] = (0, import_react38.useState)(0);
57168
+ const [installedAgents, setInstalledAgents] = (0, import_react38.useState)([]);
57169
+ const [statusMsg, setStatusMsg] = (0, import_react38.useState)("");
57170
+ const [contextTaskId, setContextTaskId] = (0, import_react38.useState)(null);
57171
+ const [moveTaskId, setMoveTaskId] = (0, import_react38.useState)(null);
57172
+ const [moveTargetCol, setMoveTargetCol] = (0, import_react38.useState)(0);
56929
57173
  const inTmux = isInTmux();
56930
- (0, import_react36.useEffect)(() => {
57174
+ const layoutRef = (0, import_react38.useRef)({
57175
+ colStarts: [],
57176
+ colWidth: 0,
57177
+ colTaskCounts: []
57178
+ });
57179
+ const updateLayout = (0, import_react38.useCallback)((b) => {
57180
+ if (!b) return;
57181
+ const cw = calcColWidth(b.columns.length);
57182
+ const starts = [];
57183
+ let x = 1;
57184
+ for (let i = 0; i < b.columns.length; i++) {
57185
+ starts.push(x);
57186
+ x += cw + 1;
57187
+ }
57188
+ layoutRef.current = {
57189
+ colStarts: starts,
57190
+ colWidth: cw,
57191
+ colTaskCounts: b.columns.map((c) => c.tasks.length)
57192
+ };
57193
+ }, []);
57194
+ (0, import_react38.useEffect)(() => {
56931
57195
  const loaded = readBoard(kandownDir);
56932
57196
  setBoard(loaded);
57197
+ updateLayout(loaded);
56933
57198
  setInstalledAgents(detectInstalledAgents());
56934
- }, [kandownDir]);
56935
- const colIndexRef = (0, import_react36.useRef)(0);
56936
- const rowIndexRef = (0, import_react36.useRef)(0);
56937
- (0, import_react36.useEffect)(() => {
57199
+ }, [kandownDir, updateLayout]);
57200
+ (0, import_react38.useEffect)(() => {
56938
57201
  const watcher = createWatcher();
56939
57202
  watcher.on("taskChanged", () => {
56940
57203
  const loaded = readBoard(kandownDir);
56941
57204
  setBoard(loaded);
57205
+ updateLayout(loaded);
56942
57206
  });
56943
57207
  watcher.on("newTaskDetected", (taskId) => {
56944
57208
  const loaded = readBoard(kandownDir);
56945
57209
  setBoard(loaded);
57210
+ updateLayout(loaded);
56946
57211
  setStatusMsg(`New task: ${taskId}`);
56947
57212
  setTimeout(() => setStatusMsg(""), 2e3);
56948
57213
  });
56949
57214
  watcher.on("configChanged", () => {
56950
57215
  const loaded = readBoard(kandownDir);
56951
57216
  setBoard(loaded);
57217
+ updateLayout(loaded);
56952
57218
  });
56953
57219
  watcher.start(kandownDir);
56954
57220
  return () => {
56955
57221
  watcher.stop();
56956
57222
  };
56957
- }, [kandownDir]);
56958
- const reloadBoard = (0, import_react36.useCallback)(() => {
57223
+ }, [kandownDir, updateLayout]);
57224
+ const reloadBoard = (0, import_react38.useCallback)(() => {
56959
57225
  const loaded = readBoard(kandownDir);
56960
57226
  setBoard(loaded);
57227
+ updateLayout(loaded);
56961
57228
  setStatusMsg("Board reloaded");
56962
57229
  setTimeout(() => setStatusMsg(""), 1500);
56963
- }, [kandownDir]);
56964
- const getFocusedTask = (0, import_react36.useCallback)(() => {
57230
+ }, [kandownDir, updateLayout]);
57231
+ const getFocusedTask = (0, import_react38.useCallback)(() => {
56965
57232
  if (!board) return null;
56966
57233
  const col = board.columns[colIndex];
56967
57234
  if (!col || col.tasks.length === 0) return null;
56968
57235
  return col.tasks[Math.min(rowIndex, col.tasks.length - 1)] ?? null;
56969
57236
  }, [board, colIndex, rowIndex]);
56970
- const openDetail = (0, import_react36.useCallback)((taskId) => {
57237
+ const openDetail = (0, import_react38.useCallback)((taskId) => {
56971
57238
  const task = readTask(kandownDir, taskId);
56972
57239
  setDetailTask(task);
56973
57240
  setDetailTaskId(taskId);
56974
57241
  setDetailScroll(0);
56975
57242
  setMode("detail");
56976
57243
  }, [kandownDir]);
56977
- const handleAgentSelect = (0, import_react36.useCallback)((agentId) => {
57244
+ const handleAgentSelect = (0, import_react38.useCallback)((agentId) => {
56978
57245
  const task = getFocusedTask();
56979
57246
  const taskId = mode === "detail" ? detailTaskId : task?.id;
56980
57247
  if (!taskId) return;
@@ -56997,6 +57264,121 @@ function Board({ kandownDir }) {
56997
57264
  }
56998
57265
  }, 50);
56999
57266
  }, [mode, detailTaskId, getFocusedTask, kandownDir, exit, reloadBoard]);
57267
+ const handleMouseClick = (0, import_react38.useCallback)((evt) => {
57268
+ if (evt.button !== 0) return;
57269
+ if (!board) return;
57270
+ const { x, y } = evt;
57271
+ const layout = layoutRef.current;
57272
+ if (mode === "browse") {
57273
+ for (let c = 0; c < board.columns.length; c++) {
57274
+ const colStart = layout.colStarts[c] || 0;
57275
+ const colEnd = colStart + layout.colWidth;
57276
+ if (x >= colStart && x <= colEnd) {
57277
+ const taskRow = y - HEADER_LINES;
57278
+ if (taskRow >= 0 && taskRow < board.columns[c].tasks.length) {
57279
+ setColIndex(c);
57280
+ setRowIndex(taskRow);
57281
+ const task = board.columns[c].tasks[taskRow];
57282
+ if (task) {
57283
+ setContextTaskId(task.id);
57284
+ setMode("context-menu");
57285
+ }
57286
+ return;
57287
+ }
57288
+ }
57289
+ }
57290
+ return;
57291
+ }
57292
+ if (mode === "context-menu") {
57293
+ const maxTasks = Math.max(...board.columns.map((c) => c.tasks.length), 0);
57294
+ const menuStartY = HEADER_LINES + maxTasks + 1;
57295
+ const menuRow = y - menuStartY;
57296
+ if (menuRow === 1) {
57297
+ if (contextTaskId) {
57298
+ setContextTaskId(null);
57299
+ openDetail(contextTaskId);
57300
+ }
57301
+ return;
57302
+ }
57303
+ if (menuRow === 2) {
57304
+ if (contextTaskId) {
57305
+ const taskId = contextTaskId;
57306
+ setContextTaskId(null);
57307
+ setMoveTaskId(taskId);
57308
+ const target = colIndex === 0 ? Math.min(1, board.columns.length - 1) : 0;
57309
+ setMoveTargetCol(target);
57310
+ setMode("move-target");
57311
+ }
57312
+ return;
57313
+ }
57314
+ if (menuRow < 0 || menuRow > 3) {
57315
+ for (let c = 0; c < board.columns.length; c++) {
57316
+ const colStart = layout.colStarts[c] || 0;
57317
+ const colEnd = colStart + layout.colWidth;
57318
+ if (x >= colStart && x <= colEnd) {
57319
+ const taskRow = y - HEADER_LINES;
57320
+ if (taskRow >= 0 && taskRow < board.columns[c].tasks.length) {
57321
+ setColIndex(c);
57322
+ setRowIndex(taskRow);
57323
+ const task = board.columns[c].tasks[taskRow];
57324
+ if (task) {
57325
+ setContextTaskId(task.id);
57326
+ }
57327
+ return;
57328
+ }
57329
+ }
57330
+ }
57331
+ setContextTaskId(null);
57332
+ setMode("browse");
57333
+ }
57334
+ return;
57335
+ }
57336
+ if (mode === "move-target") {
57337
+ let clickedPlaceholder = false;
57338
+ for (let c = 0; c < board.columns.length; c++) {
57339
+ if (c === colIndex) continue;
57340
+ const colStart = layout.colStarts[c] || 0;
57341
+ const colEnd = colStart + layout.colWidth;
57342
+ const colTaskCount = board.columns[c].tasks.length;
57343
+ const placeholderRow = HEADER_LINES + colTaskCount;
57344
+ if (x >= colStart && x <= colEnd && y === placeholderRow) {
57345
+ const targetColName = board.columns[c].name;
57346
+ if (moveTaskId && targetColName) {
57347
+ moveTaskToColumn(kandownDir, moveTaskId, targetColName);
57348
+ const loaded = readBoard(kandownDir);
57349
+ setBoard(loaded);
57350
+ updateLayout(loaded);
57351
+ setStatusMsg(`Moved ${moveTaskId} \u2192 ${targetColName}`);
57352
+ setTimeout(() => setStatusMsg(""), 2e3);
57353
+ }
57354
+ setMoveTaskId(null);
57355
+ setMode("browse");
57356
+ clickedPlaceholder = true;
57357
+ break;
57358
+ }
57359
+ }
57360
+ if (!clickedPlaceholder) {
57361
+ let clickedTask = false;
57362
+ for (let c = 0; c < board.columns.length; c++) {
57363
+ const colStart = layout.colStarts[c] || 0;
57364
+ const colEnd = colStart + layout.colWidth;
57365
+ if (x >= colStart && x <= colEnd) {
57366
+ const taskRow = y - HEADER_LINES;
57367
+ if (taskRow >= 0 && taskRow < board.columns[c].tasks.length) {
57368
+ clickedTask = true;
57369
+ break;
57370
+ }
57371
+ }
57372
+ }
57373
+ if (!clickedTask) {
57374
+ setMoveTaskId(null);
57375
+ setMode("browse");
57376
+ }
57377
+ }
57378
+ return;
57379
+ }
57380
+ }, [board, mode, colIndex, contextTaskId, moveTaskId, kandownDir, updateLayout, openDetail]);
57381
+ useMouse(handleMouseClick, { enabled: mode !== "agent-picker" });
57000
57382
  use_input_default((input, key) => {
57001
57383
  if (mode === "browse") {
57002
57384
  if (input === "q" || key.escape) {
@@ -57045,6 +57427,47 @@ function Board({ kandownDir }) {
57045
57427
  return;
57046
57428
  }
57047
57429
  }
57430
+ if (mode === "context-menu") {
57431
+ return;
57432
+ }
57433
+ if (mode === "move-target") {
57434
+ if (key.escape || input === "q") {
57435
+ setMoveTaskId(null);
57436
+ setMode("browse");
57437
+ return;
57438
+ }
57439
+ if (input === "l" || key.rightArrow) {
57440
+ if (!board) return;
57441
+ const otherCols = board.columns.map((_, i) => i).filter((i) => i !== colIndex);
57442
+ const currentIdx = otherCols.indexOf(moveTargetCol);
57443
+ const nextIdx = Math.min(currentIdx + 1, otherCols.length - 1);
57444
+ setMoveTargetCol(otherCols[nextIdx] ?? 0);
57445
+ return;
57446
+ }
57447
+ if (input === "h" || key.leftArrow) {
57448
+ if (!board) return;
57449
+ const otherCols = board.columns.map((_, i) => i).filter((i) => i !== colIndex);
57450
+ const currentIdx = otherCols.indexOf(moveTargetCol);
57451
+ const prevIdx = Math.max(currentIdx - 1, 0);
57452
+ setMoveTargetCol(otherCols[prevIdx] ?? 0);
57453
+ return;
57454
+ }
57455
+ if (key.return) {
57456
+ if (!board || !moveTaskId) return;
57457
+ const targetColName = board.columns[moveTargetCol]?.name;
57458
+ if (targetColName) {
57459
+ moveTaskToColumn(kandownDir, moveTaskId, targetColName);
57460
+ const loaded = readBoard(kandownDir);
57461
+ setBoard(loaded);
57462
+ updateLayout(loaded);
57463
+ setStatusMsg(`Moved ${moveTaskId} \u2192 ${targetColName}`);
57464
+ setTimeout(() => setStatusMsg(""), 2e3);
57465
+ }
57466
+ setMoveTaskId(null);
57467
+ setMode("browse");
57468
+ return;
57469
+ }
57470
+ }
57048
57471
  if (mode === "detail") {
57049
57472
  if (key.escape || input === "q") {
57050
57473
  setMode("browse");
@@ -57070,17 +57493,17 @@ function Board({ kandownDir }) {
57070
57493
  }
57071
57494
  });
57072
57495
  if (!board) {
57073
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { padding: 2, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "gray", children: "Loading board\u2026" }) });
57496
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { padding: 2, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "gray", children: "Loading board\u2026" }) });
57074
57497
  }
57075
57498
  if (board.columns.length === 0) {
57076
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { flexDirection: "column", padding: 2, children: [
57077
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: "red", bold: true, children: [
57499
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { flexDirection: "column", padding: 2, children: [
57500
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: "red", bold: true, children: [
57078
57501
  "No board found at ",
57079
57502
  kandownDir
57080
57503
  ] }),
57081
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: "gray", children: [
57504
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: "gray", children: [
57082
57505
  "Run ",
57083
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "cyan", children: "kandown init" }),
57506
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "cyan", children: "kandown init" }),
57084
57507
  " to set up kandown in this project."
57085
57508
  ] })
57086
57509
  ] });
@@ -57089,9 +57512,9 @@ function Board({ kandownDir }) {
57089
57512
  const focusedTask = getFocusedTask();
57090
57513
  if (mode === "agent-picker") {
57091
57514
  const taskId = detailTaskId || focusedTask?.id || "";
57092
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { flexDirection: "column", children: [
57093
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(BoardHeader, { title: board.title, inTmux }),
57094
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
57515
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { flexDirection: "column", children: [
57516
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(BoardHeader, { title: board.title, inTmux, version }),
57517
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
57095
57518
  AgentPicker,
57096
57519
  {
57097
57520
  agents: installedAgents,
@@ -57103,45 +57526,89 @@ function Board({ kandownDir }) {
57103
57526
  ] });
57104
57527
  }
57105
57528
  if (mode === "detail" && detailTask) {
57106
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { flexDirection: "column", children: [
57107
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { marginBottom: 1, justifyContent: "space-between", children: [
57108
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "gray", children: "Esc back a launch agent j/k scroll" }),
57109
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: "gray", dimColor: true, children: [
57529
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { flexDirection: "column", children: [
57530
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { marginBottom: 1, justifyContent: "space-between", children: [
57531
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "gray", children: "Esc back a launch agent j/k scroll" }),
57532
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: "gray", dimColor: true, children: [
57110
57533
  "KANDOWN ",
57111
57534
  board.title
57112
57535
  ] })
57113
57536
  ] }),
57114
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TaskDetail, { task: detailTask, taskId: detailTaskId, scrollOffset: detailScroll }),
57115
- statusMsg && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "yellow", children: statusMsg }) })
57537
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(TaskDetail, { task: detailTask, taskId: detailTaskId, scrollOffset: detailScroll }),
57538
+ statusMsg && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "yellow", children: statusMsg }) })
57116
57539
  ] });
57117
57540
  }
57118
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { flexDirection: "column", children: [
57119
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(BoardHeader, { title: board.title, inTmux }),
57120
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { flexDirection: "row", children: board.columns.map((col, cIdx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
57541
+ const contextMenuOptions = [
57542
+ { id: "open", label: "Open task", icon: "\u{1F4D6}" },
57543
+ { id: "move", label: "Move task", icon: "\u2197" }
57544
+ ];
57545
+ let modeHint;
57546
+ if (mode === "context-menu") {
57547
+ modeHint = "\u2191/\u2193 navigate Enter confirm Esc cancel (or click)";
57548
+ } else if (mode === "move-target") {
57549
+ modeHint = "\u2190/\u2192 pick column Enter confirm Esc cancel (or click \u2193 placeholder)";
57550
+ }
57551
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { flexDirection: "column", children: [
57552
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(BoardHeader, { title: board.title, inTmux, modeHint, version }),
57553
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { flexDirection: "row", children: board.columns.map((col, cIdx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
57121
57554
  KanbanColumn,
57122
57555
  {
57123
57556
  name: col.name,
57124
57557
  tasks: col.tasks,
57125
57558
  focusedRow: cIdx === colIndex ? rowIndex : -1,
57126
57559
  isFocused: cIdx === colIndex,
57127
- colWidth
57560
+ colWidth,
57561
+ showMoveTarget: mode === "move-target" && cIdx !== colIndex,
57562
+ isMoveFocused: mode === "move-target" && cIdx === moveTargetCol
57128
57563
  },
57129
57564
  col.name
57130
57565
  )) }),
57131
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(StatusBar, { message: statusMsg, task: focusedTask })
57566
+ mode === "context-menu" && contextTaskId && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { marginTop: 0, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
57567
+ TaskContextMenu,
57568
+ {
57569
+ taskId: contextTaskId,
57570
+ options: contextMenuOptions,
57571
+ onSelect: (optionId) => {
57572
+ if (optionId === "open") {
57573
+ setContextTaskId(null);
57574
+ openDetail(contextTaskId);
57575
+ } else if (optionId === "move") {
57576
+ setContextTaskId(null);
57577
+ setMoveTaskId(contextTaskId);
57578
+ const target = colIndex === 0 ? Math.min(1, board.columns.length - 1) : 0;
57579
+ setMoveTargetCol(target);
57580
+ setMode("move-target");
57581
+ }
57582
+ },
57583
+ onCancel: () => {
57584
+ setContextTaskId(null);
57585
+ setMode("browse");
57586
+ },
57587
+ mouseX: layoutRef.current.colStarts[colIndex],
57588
+ mouseY: HEADER_LINES + rowIndex
57589
+ }
57590
+ ) }),
57591
+ mode === "move-target" && moveTaskId && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: "yellow", bold: true, children: [
57592
+ "Moving ",
57593
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "cyan", children: moveTaskId }),
57594
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "gray", children: " \u2014 click a " }),
57595
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "yellow", bold: true, children: "\u2193" }),
57596
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "gray", children: " placeholder or use \u2190/\u2192 + Enter" })
57597
+ ] }) }),
57598
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(StatusBar, { message: statusMsg, task: focusedTask })
57132
57599
  ] });
57133
57600
  }
57134
57601
 
57135
57602
  // src/cli/app.tsx
57136
- var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
57603
+ var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
57137
57604
  function App2({ screen, kandownDir, version }) {
57138
57605
  switch (screen) {
57139
57606
  case "settings":
57140
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Settings, { kandownDir, version });
57607
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Settings, { kandownDir, version });
57141
57608
  case "board":
57142
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Board, { kandownDir });
57609
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Board, { kandownDir, version });
57143
57610
  default:
57144
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { padding: 2, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: "red", bold: true, children: [
57611
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { padding: 2, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "red", bold: true, children: [
57145
57612
  "Unknown screen: ",
57146
57613
  screen
57147
57614
  ] }) });
@@ -57149,7 +57616,7 @@ function App2({ screen, kandownDir, version }) {
57149
57616
  }
57150
57617
 
57151
57618
  // src/cli/tui.tsx
57152
- var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
57619
+ var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
57153
57620
  async function run(screen, kandownDir, version) {
57154
57621
  if (!process.stdin.isTTY) {
57155
57622
  throw new Error(
@@ -57157,7 +57624,7 @@ async function run(screen, kandownDir, version) {
57157
57624
  );
57158
57625
  }
57159
57626
  process.stdout.write("\x1B[?1049h\x1B[H");
57160
- const instance = render_default(/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(App2, { screen, kandownDir, version }), {
57627
+ const instance = render_default(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(App2, { screen, kandownDir, version }), {
57161
57628
  exitOnCtrlC: true
57162
57629
  });
57163
57630
  try {