@brainfile/cli 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/commands/add.d.ts.map +1 -1
  3. package/dist/commands/add.js +8 -24
  4. package/dist/commands/add.js.map +1 -1
  5. package/dist/commands/archive.d.ts.map +1 -1
  6. package/dist/commands/archive.js +8 -23
  7. package/dist/commands/archive.js.map +1 -1
  8. package/dist/commands/delete.d.ts.map +1 -1
  9. package/dist/commands/delete.js +8 -23
  10. package/dist/commands/delete.js.map +1 -1
  11. package/dist/commands/list.d.ts.map +1 -1
  12. package/dist/commands/list.js +4 -12
  13. package/dist/commands/list.js.map +1 -1
  14. package/dist/commands/mcp.d.ts.map +1 -1
  15. package/dist/commands/mcp.js +29 -2
  16. package/dist/commands/mcp.js.map +1 -1
  17. package/dist/commands/move.d.ts.map +1 -1
  18. package/dist/commands/move.js +12 -35
  19. package/dist/commands/move.js.map +1 -1
  20. package/dist/commands/patch.d.ts.map +1 -1
  21. package/dist/commands/patch.js +9 -27
  22. package/dist/commands/patch.js.map +1 -1
  23. package/dist/commands/restore.d.ts.map +1 -1
  24. package/dist/commands/restore.js +10 -26
  25. package/dist/commands/restore.js.map +1 -1
  26. package/dist/commands/subtask.d.ts.map +1 -1
  27. package/dist/commands/subtask.js +16 -60
  28. package/dist/commands/subtask.js.map +1 -1
  29. package/dist/commands/tui.d.ts.map +1 -1
  30. package/dist/commands/tui.js +6 -701
  31. package/dist/commands/tui.js.map +1 -1
  32. package/dist/tui/BrainfileTUI.d.ts +4 -0
  33. package/dist/tui/BrainfileTUI.d.ts.map +1 -0
  34. package/dist/tui/BrainfileTUI.js +198 -0
  35. package/dist/tui/BrainfileTUI.js.map +1 -0
  36. package/dist/tui/actions.d.ts +49 -0
  37. package/dist/tui/actions.d.ts.map +1 -0
  38. package/dist/tui/actions.js +569 -0
  39. package/dist/tui/actions.js.map +1 -0
  40. package/dist/tui/components/ColumnTabs.d.ts +9 -0
  41. package/dist/tui/components/ColumnTabs.d.ts.map +1 -0
  42. package/dist/tui/components/ColumnTabs.js +30 -0
  43. package/dist/tui/components/ColumnTabs.js.map +1 -0
  44. package/dist/tui/components/Header.d.ts +12 -0
  45. package/dist/tui/components/Header.d.ts.map +1 -0
  46. package/dist/tui/components/Header.js +24 -0
  47. package/dist/tui/components/Header.js.map +1 -0
  48. package/dist/tui/components/HelpOverlay.d.ts +7 -0
  49. package/dist/tui/components/HelpOverlay.d.ts.map +1 -0
  50. package/dist/tui/components/HelpOverlay.js +56 -0
  51. package/dist/tui/components/HelpOverlay.js.map +1 -0
  52. package/dist/tui/components/Overlays.d.ts +41 -0
  53. package/dist/tui/components/Overlays.d.ts.map +1 -0
  54. package/dist/tui/components/Overlays.js +127 -0
  55. package/dist/tui/components/Overlays.js.map +1 -0
  56. package/dist/tui/components/ProgressBar.d.ts +8 -0
  57. package/dist/tui/components/ProgressBar.d.ts.map +1 -0
  58. package/dist/tui/components/ProgressBar.js +35 -0
  59. package/dist/tui/components/ProgressBar.js.map +1 -0
  60. package/dist/tui/components/SearchBar.d.ts +7 -0
  61. package/dist/tui/components/SearchBar.d.ts.map +1 -0
  62. package/dist/tui/components/SearchBar.js +22 -0
  63. package/dist/tui/components/SearchBar.js.map +1 -0
  64. package/dist/tui/components/StatusBar.d.ts +12 -0
  65. package/dist/tui/components/StatusBar.d.ts.map +1 -0
  66. package/dist/tui/components/StatusBar.js +37 -0
  67. package/dist/tui/components/StatusBar.js.map +1 -0
  68. package/dist/tui/components/TaskCard.d.ts +19 -0
  69. package/dist/tui/components/TaskCard.d.ts.map +1 -0
  70. package/dist/tui/components/TaskCard.js +105 -0
  71. package/dist/tui/components/TaskCard.js.map +1 -0
  72. package/dist/tui/components/TaskList.d.ts +11 -0
  73. package/dist/tui/components/TaskList.d.ts.map +1 -0
  74. package/dist/tui/components/TaskList.js +56 -0
  75. package/dist/tui/components/TaskList.js.map +1 -0
  76. package/dist/tui/components/index.d.ts +19 -0
  77. package/dist/tui/components/index.d.ts.map +1 -0
  78. package/dist/tui/components/index.js +26 -0
  79. package/dist/tui/components/index.js.map +1 -0
  80. package/dist/tui/hooks/index.d.ts +3 -0
  81. package/dist/tui/hooks/index.d.ts.map +1 -0
  82. package/dist/tui/hooks/index.js +8 -0
  83. package/dist/tui/hooks/index.js.map +1 -0
  84. package/dist/tui/hooks/useBrainfileLoader.d.ts +5 -0
  85. package/dist/tui/hooks/useBrainfileLoader.d.ts.map +1 -0
  86. package/dist/tui/hooks/useBrainfileLoader.js +171 -0
  87. package/dist/tui/hooks/useBrainfileLoader.js.map +1 -0
  88. package/dist/tui/hooks/useKeyboardNavigation.d.ts +16 -0
  89. package/dist/tui/hooks/useKeyboardNavigation.d.ts.map +1 -0
  90. package/dist/tui/hooks/useKeyboardNavigation.js +434 -0
  91. package/dist/tui/hooks/useKeyboardNavigation.js.map +1 -0
  92. package/dist/tui/index.d.ts +9 -0
  93. package/dist/tui/index.d.ts.map +1 -0
  94. package/dist/tui/index.js +36 -0
  95. package/dist/tui/index.js.map +1 -0
  96. package/dist/tui/theme.d.ts +113 -0
  97. package/dist/tui/theme.d.ts.map +1 -0
  98. package/dist/tui/theme.js +132 -0
  99. package/dist/tui/theme.js.map +1 -0
  100. package/dist/tui/types.d.ts +30 -0
  101. package/dist/tui/types.d.ts.map +1 -0
  102. package/dist/tui/types.js +6 -0
  103. package/dist/tui/types.js.map +1 -0
  104. package/dist/tui/utils.d.ts +3 -0
  105. package/dist/tui/utils.d.ts.map +1 -0
  106. package/dist/tui/utils.js +31 -0
  107. package/dist/tui/utils.js.map +1 -0
  108. package/dist/utils/errorHandler.d.ts +106 -0
  109. package/dist/utils/errorHandler.d.ts.map +1 -0
  110. package/dist/utils/errorHandler.js +228 -0
  111. package/dist/utils/errorHandler.js.map +1 -0
  112. package/package.json +1 -1
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TaskList = TaskList;
7
+ const react_1 = __importDefault(require("react"));
8
+ const ink_1 = require("ink");
9
+ const theme_js_1 = require("../theme.js");
10
+ const TaskCard_js_1 = require("./TaskCard.js");
11
+ function TaskList({ tasks, selectedIndex, expandedIds, viewportHeight, termWidth }) {
12
+ // Calculate scroll offset to keep selection visible
13
+ const scrollOffset = Math.max(0, Math.min(selectedIndex - Math.floor(viewportHeight / 3), Math.max(0, tasks.length - Math.floor(viewportHeight / 2))));
14
+ const cardWidth = termWidth - 4;
15
+ // Build visible items with expansion
16
+ const visibleItems = [];
17
+ let linesUsed = 0;
18
+ for (let i = scrollOffset; i < tasks.length && linesUsed < viewportHeight; i++) {
19
+ const task = tasks[i];
20
+ const isSelected = i === selectedIndex;
21
+ const isExpanded = expandedIds.has(task.id);
22
+ // Calculate how many lines this task will take with rounded border card
23
+ // Base: top border(1) + title(1) + metadata(1) + bottom border(1) + margin(1) = 5
24
+ const subtaskLines = isExpanded ? Math.min((task.subtasks?.length || 0), 5) : 0;
25
+ const hasDescription = isExpanded && task.description;
26
+ const hasFiles = isExpanded && task.relatedFiles?.length;
27
+ const expandedLines = isExpanded ? 1 + (hasDescription ? 2 : 0) + subtaskLines + (hasFiles ? 2 : 0) : 0;
28
+ const taskLines = 5 + expandedLines;
29
+ if (linesUsed + taskLines <= viewportHeight) {
30
+ visibleItems.push({ task, isSelected, isExpanded });
31
+ linesUsed += taskLines;
32
+ }
33
+ else if (visibleItems.length === 0) {
34
+ // Always show at least one item
35
+ visibleItems.push({ task, isSelected, isExpanded });
36
+ linesUsed += taskLines;
37
+ break;
38
+ }
39
+ else {
40
+ break;
41
+ }
42
+ }
43
+ // Calculate remaining empty lines to fill viewport
44
+ const emptyLines = Math.max(0, viewportHeight - linesUsed);
45
+ if (tasks.length === 0) {
46
+ return (react_1.default.createElement(ink_1.Box, { flexGrow: 1, flexDirection: "column", paddingLeft: 2 },
47
+ react_1.default.createElement(ink_1.Text, { color: theme_js_1.PALETTE.textMuted, dimColor: true }, "No tasks in this column"),
48
+ Array.from({ length: viewportHeight - 1 }).map((_, i) => (react_1.default.createElement(ink_1.Box, { key: `empty-${i}` },
49
+ react_1.default.createElement(ink_1.Text, null, ' '))))));
50
+ }
51
+ return (react_1.default.createElement(ink_1.Box, { flexGrow: 1, flexDirection: "column", paddingLeft: 1 },
52
+ visibleItems.map(({ task, isSelected, isExpanded }) => (react_1.default.createElement(TaskCard_js_1.TaskCard, { key: task.id, task: task, isSelected: isSelected, isExpanded: isExpanded, width: cardWidth }))),
53
+ Array.from({ length: emptyLines }).map((_, i) => (react_1.default.createElement(ink_1.Box, { key: `empty-${i}` },
54
+ react_1.default.createElement(ink_1.Text, null, ' '))))));
55
+ }
56
+ //# sourceMappingURL=TaskList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskList.js","sourceRoot":"","sources":["../../../src/tui/components/TaskList.tsx"],"names":[],"mappings":";;;;;AAcA,4BA0EC;AAxFD,kDAA0B;AAC1B,6BAAgC;AAEhC,0CAAsC;AACtC,+CAAyC;AAUzC,SAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAiB;IACtG,oDAAoD;IACpD,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAC3B,CAAC,EACD,IAAI,CAAC,GAAG,CACN,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC,EAC9C,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,CAC3D,CACF,CAAC;IAEF,MAAM,SAAS,GAAG,SAAS,GAAG,CAAC,CAAC;IAEhC,qCAAqC;IACrC,MAAM,YAAY,GAA+D,EAAE,CAAC;IACpF,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,IAAI,CAAC,GAAG,YAAY,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,SAAS,GAAG,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/E,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,UAAU,GAAG,CAAC,KAAK,aAAa,CAAC;QACvC,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAE5C,wEAAwE;QACxE,kFAAkF;QAClF,MAAM,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChF,MAAM,cAAc,GAAG,UAAU,IAAI,IAAI,CAAC,WAAW,CAAC;QACtD,MAAM,QAAQ,GAAG,UAAU,IAAI,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC;QACzD,MAAM,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,YAAY,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACxG,MAAM,SAAS,GAAG,CAAC,GAAG,aAAa,CAAC;QAEpC,IAAI,SAAS,GAAG,SAAS,IAAI,cAAc,EAAE,CAAC;YAC5C,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;YACpD,SAAS,IAAI,SAAS,CAAC;QACzB,CAAC;aAAM,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrC,gCAAgC;YAChC,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;YACpD,SAAS,IAAI,SAAS,CAAC;YACvB,MAAM;QACR,CAAC;aAAM,CAAC;YACN,MAAM;QACR,CAAC;IACH,CAAC;IAED,mDAAmD;IACnD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC,CAAC;IAE3D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CACL,8BAAC,SAAG,IAAC,QAAQ,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ,EAAC,WAAW,EAAE,CAAC;YACrD,8BAAC,UAAI,IAAC,KAAK,EAAE,kBAAO,CAAC,SAAS,EAAE,QAAQ,oCAA+B;YAEtE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,cAAc,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CACxD,8BAAC,SAAG,IAAC,GAAG,EAAE,SAAS,CAAC,EAAE;gBAAE,8BAAC,UAAI,QAAE,GAAG,CAAQ,CAAM,CACjD,CAAC,CACE,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,8BAAC,SAAG,IAAC,QAAQ,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ,EAAC,WAAW,EAAE,CAAC;QACpD,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CACtD,8BAAC,sBAAQ,IACP,GAAG,EAAE,IAAI,CAAC,EAAE,EACZ,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,SAAS,GAChB,CACH,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAChD,8BAAC,SAAG,IAAC,GAAG,EAAE,SAAS,CAAC,EAAE;YAAE,8BAAC,UAAI,QAAE,GAAG,CAAQ,CAAM,CACjD,CAAC,CACE,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,19 @@
1
+ export { Header } from './Header.js';
2
+ export type { HeaderProps } from './Header.js';
3
+ export { ProgressBar } from './ProgressBar.js';
4
+ export type { ProgressBarProps } from './ProgressBar.js';
5
+ export { SearchBar } from './SearchBar.js';
6
+ export type { SearchBarProps } from './SearchBar.js';
7
+ export { ColumnTabs } from './ColumnTabs.js';
8
+ export type { ColumnTabsProps } from './ColumnTabs.js';
9
+ export { TaskCard } from './TaskCard.js';
10
+ export type { TaskCardProps } from './TaskCard.js';
11
+ export { TaskList } from './TaskList.js';
12
+ export type { TaskListProps } from './TaskList.js';
13
+ export { StatusBar } from './StatusBar.js';
14
+ export type { StatusBarProps } from './StatusBar.js';
15
+ export { HelpOverlay } from './HelpOverlay.js';
16
+ export type { HelpOverlayProps } from './HelpOverlay.js';
17
+ export { StatusMessageDisplay, MoveOverlay, DeleteConfirmOverlay, SubtaskOverlay, NewTaskOverlay, } from './Overlays.js';
18
+ export type { StatusMessageProps, MoveOverlayProps, DeleteConfirmOverlayProps, SubtaskOverlayProps, NewTaskOverlayProps, } from './Overlays.js';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tui/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EACL,oBAAoB,EACpB,WAAW,EACX,oBAAoB,EACpB,cAAc,EACd,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,yBAAyB,EACzB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NewTaskOverlay = exports.SubtaskOverlay = exports.DeleteConfirmOverlay = exports.MoveOverlay = exports.StatusMessageDisplay = exports.HelpOverlay = exports.StatusBar = exports.TaskList = exports.TaskCard = exports.ColumnTabs = exports.SearchBar = exports.ProgressBar = exports.Header = void 0;
4
+ var Header_js_1 = require("./Header.js");
5
+ Object.defineProperty(exports, "Header", { enumerable: true, get: function () { return Header_js_1.Header; } });
6
+ var ProgressBar_js_1 = require("./ProgressBar.js");
7
+ Object.defineProperty(exports, "ProgressBar", { enumerable: true, get: function () { return ProgressBar_js_1.ProgressBar; } });
8
+ var SearchBar_js_1 = require("./SearchBar.js");
9
+ Object.defineProperty(exports, "SearchBar", { enumerable: true, get: function () { return SearchBar_js_1.SearchBar; } });
10
+ var ColumnTabs_js_1 = require("./ColumnTabs.js");
11
+ Object.defineProperty(exports, "ColumnTabs", { enumerable: true, get: function () { return ColumnTabs_js_1.ColumnTabs; } });
12
+ var TaskCard_js_1 = require("./TaskCard.js");
13
+ Object.defineProperty(exports, "TaskCard", { enumerable: true, get: function () { return TaskCard_js_1.TaskCard; } });
14
+ var TaskList_js_1 = require("./TaskList.js");
15
+ Object.defineProperty(exports, "TaskList", { enumerable: true, get: function () { return TaskList_js_1.TaskList; } });
16
+ var StatusBar_js_1 = require("./StatusBar.js");
17
+ Object.defineProperty(exports, "StatusBar", { enumerable: true, get: function () { return StatusBar_js_1.StatusBar; } });
18
+ var HelpOverlay_js_1 = require("./HelpOverlay.js");
19
+ Object.defineProperty(exports, "HelpOverlay", { enumerable: true, get: function () { return HelpOverlay_js_1.HelpOverlay; } });
20
+ var Overlays_js_1 = require("./Overlays.js");
21
+ Object.defineProperty(exports, "StatusMessageDisplay", { enumerable: true, get: function () { return Overlays_js_1.StatusMessageDisplay; } });
22
+ Object.defineProperty(exports, "MoveOverlay", { enumerable: true, get: function () { return Overlays_js_1.MoveOverlay; } });
23
+ Object.defineProperty(exports, "DeleteConfirmOverlay", { enumerable: true, get: function () { return Overlays_js_1.DeleteConfirmOverlay; } });
24
+ Object.defineProperty(exports, "SubtaskOverlay", { enumerable: true, get: function () { return Overlays_js_1.SubtaskOverlay; } });
25
+ Object.defineProperty(exports, "NewTaskOverlay", { enumerable: true, get: function () { return Overlays_js_1.NewTaskOverlay; } });
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tui/components/index.ts"],"names":[],"mappings":";;;AAAA,yCAAqC;AAA5B,mGAAA,MAAM,OAAA;AAGf,mDAA+C;AAAtC,6GAAA,WAAW,OAAA;AAGpB,+CAA2C;AAAlC,yGAAA,SAAS,OAAA;AAGlB,iDAA6C;AAApC,2GAAA,UAAU,OAAA;AAGnB,6CAAyC;AAAhC,uGAAA,QAAQ,OAAA;AAGjB,6CAAyC;AAAhC,uGAAA,QAAQ,OAAA;AAGjB,+CAA2C;AAAlC,yGAAA,SAAS,OAAA;AAGlB,mDAA+C;AAAtC,6GAAA,WAAW,OAAA;AAGpB,6CAMuB;AALrB,mHAAA,oBAAoB,OAAA;AACpB,0GAAA,WAAW,OAAA;AACX,mHAAA,oBAAoB,OAAA;AACpB,6GAAA,cAAc,OAAA;AACd,6GAAA,cAAc,OAAA"}
@@ -0,0 +1,3 @@
1
+ export { useBrainfileLoader } from './useBrainfileLoader.js';
2
+ export { useKeyboardNavigation } from './useKeyboardNavigation.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useKeyboardNavigation = exports.useBrainfileLoader = void 0;
4
+ var useBrainfileLoader_js_1 = require("./useBrainfileLoader.js");
5
+ Object.defineProperty(exports, "useBrainfileLoader", { enumerable: true, get: function () { return useBrainfileLoader_js_1.useBrainfileLoader; } });
6
+ var useKeyboardNavigation_js_1 = require("./useKeyboardNavigation.js");
7
+ Object.defineProperty(exports, "useKeyboardNavigation", { enumerable: true, get: function () { return useKeyboardNavigation_js_1.useKeyboardNavigation; } });
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tui/hooks/index.ts"],"names":[],"mappings":";;;AAAA,iEAA6D;AAApD,2HAAA,kBAAkB,OAAA;AAC3B,uEAAmE;AAA1D,iIAAA,qBAAqB,OAAA"}
@@ -0,0 +1,5 @@
1
+ import type { AppState } from '../types.js';
2
+ export declare function useBrainfileLoader(filePath: string, state: AppState, setState: React.Dispatch<React.SetStateAction<AppState>>): {
3
+ loadBrainfile: (forceRefresh?: any) => void;
4
+ };
5
+ //# sourceMappingURL=useBrainfileLoader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBrainfileLoader.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/useBrainfileLoader.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,QAAQ,EACf,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;;EA2IzD"}
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.useBrainfileLoader = useBrainfileLoader;
37
+ const react_1 = require("react");
38
+ const fs = __importStar(require("fs"));
39
+ const chokidar = __importStar(require("chokidar"));
40
+ const core_1 = require("@brainfile/core");
41
+ function useBrainfileLoader(filePath, state, setState) {
42
+ // Track flash timeout for cleanup
43
+ const flashTimeoutRef = (0, react_1.useRef)(null);
44
+ const loadBrainfile = (0, react_1.useCallback)((forceRefresh = false) => {
45
+ try {
46
+ const content = fs.readFileSync(filePath, 'utf-8');
47
+ const contentHash = (0, core_1.hashBoardContent)(content);
48
+ const result = core_1.Brainfile.parseWithErrors(content);
49
+ setState(prev => {
50
+ // Skip redundant refreshes using content hash
51
+ if (!forceRefresh && prev.lastContentHash === contentHash) {
52
+ return prev; // No state change
53
+ }
54
+ if (result.board) {
55
+ // Preserve selection by task ID and column ID if possible
56
+ const prevColumn = prev.board?.columns[prev.activeColumnIndex];
57
+ const prevTaskId = prevColumn?.tasks[prev.selectedTaskIndex]?.id;
58
+ let newColumnIndex = prev.activeColumnIndex;
59
+ let newTaskIndex = 0;
60
+ // Try to find the same column by ID
61
+ if (prevColumn && result.board) {
62
+ const colIdx = result.board.columns.findIndex(c => c.id === prevColumn.id);
63
+ if (colIdx >= 0) {
64
+ newColumnIndex = colIdx;
65
+ // Try to find the same task
66
+ if (prevTaskId) {
67
+ const taskIdx = result.board.columns[colIdx].tasks.findIndex(t => t.id === prevTaskId);
68
+ if (taskIdx >= 0)
69
+ newTaskIndex = taskIdx;
70
+ }
71
+ }
72
+ }
73
+ // Bounds check
74
+ newColumnIndex = Math.min(newColumnIndex, Math.max(0, result.board.columns.length - 1));
75
+ const col = result.board.columns[newColumnIndex];
76
+ newTaskIndex = Math.min(newTaskIndex, Math.max(0, (col?.tasks.length || 1) - 1));
77
+ return {
78
+ ...prev,
79
+ board: result.board,
80
+ error: null,
81
+ lastUpdated: new Date(),
82
+ activeColumnIndex: newColumnIndex,
83
+ selectedTaskIndex: newTaskIndex,
84
+ reloadFlash: true,
85
+ lastContentHash: contentHash,
86
+ };
87
+ }
88
+ else {
89
+ // Distinguish between different error cases
90
+ let errorMessage;
91
+ if (result.data && result.type) {
92
+ errorMessage = `This is a '${result.type}' brainfile. The TUI currently only supports 'board' type files.`;
93
+ }
94
+ else if (result.error) {
95
+ errorMessage = result.error;
96
+ }
97
+ else {
98
+ errorMessage = 'Not a valid brainfile';
99
+ }
100
+ return {
101
+ ...prev,
102
+ error: errorMessage,
103
+ lastContentHash: contentHash,
104
+ };
105
+ }
106
+ });
107
+ // Clear reload flash after 1 second (cleanup previous timeout)
108
+ if (flashTimeoutRef.current)
109
+ clearTimeout(flashTimeoutRef.current);
110
+ flashTimeoutRef.current = setTimeout(() => {
111
+ setState(prev => ({ ...prev, reloadFlash: false }));
112
+ }, 1000);
113
+ }
114
+ catch (err) {
115
+ const errorMsg = err instanceof Error ? err.message : String(err);
116
+ // Provide more specific error messages
117
+ let userMessage = errorMsg;
118
+ if (errorMsg.includes('ENOENT')) {
119
+ userMessage = `File not found: ${filePath}`;
120
+ }
121
+ else if (errorMsg.includes('EACCES')) {
122
+ userMessage = `Permission denied: ${filePath}`;
123
+ }
124
+ else if (errorMsg.includes('EISDIR')) {
125
+ userMessage = `Path is a directory: ${filePath}`;
126
+ }
127
+ setState(prev => ({
128
+ ...prev,
129
+ error: userMessage,
130
+ }));
131
+ }
132
+ }, [filePath, setState]);
133
+ // Initial load
134
+ (0, react_1.useEffect)(() => {
135
+ loadBrainfile();
136
+ }, [loadBrainfile]);
137
+ // Cleanup timeout on unmount
138
+ (0, react_1.useEffect)(() => {
139
+ return () => {
140
+ if (flashTimeoutRef.current)
141
+ clearTimeout(flashTimeoutRef.current);
142
+ };
143
+ }, []);
144
+ // File watcher
145
+ (0, react_1.useEffect)(() => {
146
+ const watcher = chokidar.watch(filePath, {
147
+ persistent: true,
148
+ ignoreInitial: true,
149
+ usePolling: true,
150
+ interval: 750,
151
+ awaitWriteFinish: {
152
+ stabilityThreshold: 250,
153
+ pollInterval: 100,
154
+ },
155
+ depth: 0,
156
+ });
157
+ watcher.on('change', () => loadBrainfile());
158
+ watcher.on('error', (err) => {
159
+ const message = err instanceof Error ? err.message : String(err);
160
+ setState(prev => ({
161
+ ...prev,
162
+ error: `File watcher error: ${message}`,
163
+ }));
164
+ });
165
+ return () => {
166
+ watcher.close();
167
+ };
168
+ }, [filePath, loadBrainfile, setState]);
169
+ return { loadBrainfile };
170
+ }
171
+ //# sourceMappingURL=useBrainfileLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBrainfileLoader.js","sourceRoot":"","sources":["../../../src/tui/hooks/useBrainfileLoader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { AppState, BoardColumn } from '../types.js';
2
+ import type { Task } from '@brainfile/core';
3
+ interface UseKeyboardNavigationProps {
4
+ state: AppState;
5
+ setState: React.Dispatch<React.SetStateAction<AppState>>;
6
+ currentTasks: Task[];
7
+ maxTaskIndex: number;
8
+ filteredColumnsLength: number;
9
+ viewportHeight: number;
10
+ loadBrainfile: (forceRefresh?: boolean) => void;
11
+ filePath: string;
12
+ allColumns: BoardColumn[];
13
+ }
14
+ export declare function useKeyboardNavigation({ state, setState, currentTasks, maxTaskIndex, filteredColumnsLength, viewportHeight, loadBrainfile, filePath, allColumns, }: UseKeyboardNavigationProps): void;
15
+ export {};
16
+ //# sourceMappingURL=useKeyboardNavigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useKeyboardNavigation.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/useKeyboardNavigation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAiB,WAAW,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAa5C,UAAU,0BAA0B;IAClC,KAAK,EAAE,QAAQ,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;IACzD,YAAY,EAAE,IAAI,EAAE,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,CAAC,YAAY,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,WAAW,EAAE,CAAC;CAC3B;AAyBD,wBAAgB,qBAAqB,CAAC,EACpC,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,qBAAqB,EACrB,cAAc,EACd,aAAa,EACb,QAAQ,EACR,UAAU,GACX,EAAE,0BAA0B,QA8a5B"}