claude-launchpad 1.2.3 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +2 -2
  2. package/dist/{chunk-UJP5PJTA.js → chunk-ADZ45KHX.js} +3 -3
  3. package/dist/{chunk-V4NXT4KB.js → chunk-DXDOVWOA.js} +64 -8
  4. package/dist/chunk-DXDOVWOA.js.map +1 -0
  5. package/dist/{chunk-N6X3E5AX.js → chunk-F6SLV2FR.js} +24 -5
  6. package/dist/chunk-F6SLV2FR.js.map +1 -0
  7. package/dist/{chunk-AR64LWGW.js → chunk-RJEPJ4JE.js} +25 -4
  8. package/dist/chunk-RJEPJ4JE.js.map +1 -0
  9. package/dist/{chunk-YXPJDIMK.js → chunk-UQOBOHKN.js} +33 -2
  10. package/dist/chunk-UQOBOHKN.js.map +1 -0
  11. package/dist/{chunk-J765H3HZ.js → chunk-WOC2PKT2.js} +2 -2
  12. package/dist/{chunk-F5PNKQKW.js → chunk-YZ53W47Z.js} +7 -2
  13. package/dist/chunk-YZ53W47Z.js.map +1 -0
  14. package/dist/cli.js +25 -14
  15. package/dist/cli.js.map +1 -1
  16. package/dist/commands/memory/server.js +12 -13
  17. package/dist/commands/memory/server.js.map +1 -1
  18. package/dist/{context-VAXF3EW3.js → context-NCV46PTY.js} +6 -6
  19. package/dist/{install-M3JWBGMK.js → install-DORMJYCU.js} +6 -6
  20. package/dist/install-DORMJYCU.js.map +1 -0
  21. package/dist/{pull-RKFE5ZXV.js → pull-UYLUGILU.js} +45 -20
  22. package/dist/pull-UYLUGILU.js.map +1 -0
  23. package/dist/{push-5ZJNWAE7.js → push-HWXJGSTL.js} +40 -17
  24. package/dist/push-HWXJGSTL.js.map +1 -0
  25. package/dist/{require-deps-QW2IU6I3.js → require-deps-RUXTMQUV.js} +3 -3
  26. package/dist/{stats-NPXPJNBO.js → stats-DFV24AJW.js} +7 -7
  27. package/dist/{sync-clean-JQLVE4WU.js → sync-clean-GFX5F55E.js} +2 -2
  28. package/dist/{sync-status-IYG7ZYC5.js → sync-status-VXMDWDRG.js} +9 -9
  29. package/dist/{tui-56GQMXXT.js → tui-ELOJ37ZA.js} +208 -40
  30. package/dist/tui-ELOJ37ZA.js.map +1 -0
  31. package/package.json +1 -1
  32. package/dist/chunk-AR64LWGW.js.map +0 -1
  33. package/dist/chunk-F5PNKQKW.js.map +0 -1
  34. package/dist/chunk-N6X3E5AX.js.map +0 -1
  35. package/dist/chunk-V4NXT4KB.js.map +0 -1
  36. package/dist/chunk-YXPJDIMK.js.map +0 -1
  37. package/dist/install-M3JWBGMK.js.map +0 -1
  38. package/dist/pull-RKFE5ZXV.js.map +0 -1
  39. package/dist/push-5ZJNWAE7.js.map +0 -1
  40. package/dist/tui-56GQMXXT.js.map +0 -1
  41. /package/dist/{chunk-UJP5PJTA.js.map → chunk-ADZ45KHX.js.map} +0 -0
  42. /package/dist/{chunk-J765H3HZ.js.map → chunk-WOC2PKT2.js.map} +0 -0
  43. /package/dist/{context-VAXF3EW3.js.map → context-NCV46PTY.js.map} +0 -0
  44. /package/dist/{require-deps-QW2IU6I3.js.map → require-deps-RUXTMQUV.js.map} +0 -0
  45. /package/dist/{stats-NPXPJNBO.js.map → stats-DFV24AJW.js.map} +0 -0
  46. /package/dist/{sync-clean-JQLVE4WU.js.map → sync-clean-GFX5F55E.js.map} +0 -0
  47. /package/dist/{sync-status-IYG7ZYC5.js.map → sync-status-VXMDWDRG.js.map} +0 -0
@@ -3,7 +3,7 @@ import {
3
3
  MemoryRepo,
4
4
  RelationRepo,
5
5
  SearchRepo
6
- } from "./chunk-V4NXT4KB.js";
6
+ } from "./chunk-DXDOVWOA.js";
7
7
  import {
8
8
  DEFAULT_DECAY_PARAMS,
9
9
  closeDatabase,
@@ -11,9 +11,9 @@ import {
11
11
  loadConfig,
12
12
  migrate,
13
13
  resolveDataDir
14
- } from "./chunk-AR64LWGW.js";
15
- import "./chunk-J765H3HZ.js";
16
- import "./chunk-YXPJDIMK.js";
14
+ } from "./chunk-RJEPJ4JE.js";
15
+ import "./chunk-WOC2PKT2.js";
16
+ import "./chunk-UQOBOHKN.js";
17
17
 
18
18
  // src/commands/memory/dashboard/tui.tsx
19
19
  import { render } from "ink";
@@ -129,7 +129,7 @@ var DashboardDataSource = class {
129
129
  };
130
130
 
131
131
  // src/commands/memory/dashboard/app.tsx
132
- import { Box as Box12, useApp } from "ink";
132
+ import { Box as Box13, useApp } from "ink";
133
133
 
134
134
  // src/commands/memory/dashboard/hooks/use-dashboard-state.ts
135
135
  import { useState, useMemo, useEffect, useCallback } from "react";
@@ -231,6 +231,7 @@ function useDashboardState(dataSource) {
231
231
  const [showProjectPicker, setShowProjectPicker] = useState(false);
232
232
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
233
233
  const [showPurgeConfirm, setShowPurgeConfirm] = useState(false);
234
+ const [showExpand, setShowExpand] = useState(false);
234
235
  useEffect(() => {
235
236
  dataSource.refresh();
236
237
  setRevision((r) => r + 1);
@@ -329,6 +330,10 @@ function useDashboardState(dataSource) {
329
330
  setRevision((r) => r + 1);
330
331
  }, [dataSource, currentProject]);
331
332
  const cancelPurge = useCallback(() => setShowPurgeConfirm(false), []);
333
+ const expandMemory = useCallback(() => {
334
+ if (selectedMemory) setShowExpand(true);
335
+ }, [selectedMemory]);
336
+ const closeExpand = useCallback(() => setShowExpand(false), []);
332
337
  return {
333
338
  typeFilter,
334
339
  lifespanFilter,
@@ -342,6 +347,7 @@ function useDashboardState(dataSource) {
342
347
  showProjectPicker,
343
348
  showDeleteConfirm,
344
349
  showPurgeConfirm,
350
+ showExpand,
345
351
  filteredMemories,
346
352
  selectedMemory,
347
353
  relations,
@@ -367,7 +373,9 @@ function useDashboardState(dataSource) {
367
373
  cancelDelete,
368
374
  promptPurge,
369
375
  confirmPurge,
370
- cancelPurge
376
+ cancelPurge,
377
+ expandMemory,
378
+ closeExpand
371
379
  };
372
380
  }
373
381
  function sortMemories(memories, mode) {
@@ -393,6 +401,7 @@ var TYPE_KEYS = {
393
401
  };
394
402
  function useKeybindings(actions, opts) {
395
403
  useInput((input, key) => {
404
+ if (opts.expandOpen) return;
396
405
  if (opts.searchActive) {
397
406
  if (key.escape) actions.closeSearch();
398
407
  return;
@@ -416,6 +425,7 @@ function useKeybindings(actions, opts) {
416
425
  if (input === "r") actions.removeMemory();
417
426
  if (input === "d") actions.purgeProject();
418
427
  if (input === "?") actions.showHelp();
428
+ if (key.return) actions.expandMemory();
419
429
  if (input === "q") actions.quit();
420
430
  });
421
431
  }
@@ -446,6 +456,7 @@ import { Box, Text } from "ink";
446
456
  import { jsx, jsxs } from "react/jsx-runtime";
447
457
  var HINTS = [
448
458
  ["j/k", "navigate"],
459
+ ["Enter", "expand"],
449
460
  ["/", "search"],
450
461
  ["p", "projects"],
451
462
  ["1-5", "type"],
@@ -549,7 +560,7 @@ var LIFE_COLORS = {
549
560
  session: "magenta"
550
561
  };
551
562
  function MemoryList({ memories, selectedIndex, isFocused, height }) {
552
- const viewportHeight = Math.max(1, height - 2);
563
+ const viewportHeight = Math.max(1, height - 3);
553
564
  const scrollOffset = useMemo2(() => {
554
565
  if (selectedIndex < 0) return 0;
555
566
  if (memories.length <= viewportHeight) return 0;
@@ -565,6 +576,7 @@ function MemoryList({ memories, selectedIndex, isFocused, height }) {
565
576
  flexDirection: "column",
566
577
  borderStyle: "round",
567
578
  borderColor: isFocused ? "cyan" : "gray",
579
+ height,
568
580
  children: [
569
581
  /* @__PURE__ */ jsx4(Text4, { bold: true, color: isFocused ? "cyan" : "gray", children: label }),
570
582
  visible.length === 0 && /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: " No memories found" }),
@@ -608,8 +620,29 @@ function MemoryRow({ memory, isSelected }) {
608
620
 
609
621
  // src/commands/memory/dashboard/components/memory-detail.tsx
610
622
  import { Box as Box5, Text as Text5 } from "ink";
623
+
624
+ // src/commands/memory/dashboard/data/wrap.ts
625
+ function wrapContent(content, width) {
626
+ if (width <= 0) return content.split("\n");
627
+ const out = [];
628
+ for (const rawLine of content.split("\n")) {
629
+ if (rawLine.length === 0) {
630
+ out.push("");
631
+ continue;
632
+ }
633
+ for (let i = 0; i < rawLine.length; i += width) {
634
+ out.push(rawLine.slice(i, i + width));
635
+ }
636
+ }
637
+ return out;
638
+ }
639
+
640
+ // src/commands/memory/dashboard/components/memory-detail.tsx
611
641
  import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
612
- function MemoryDetail({ memory, relations, isFocused }) {
642
+ var METADATA_ROWS = 18;
643
+ var BORDER_ROWS = 2;
644
+ var MIN_CONTENT_ROWS = 2;
645
+ function MemoryDetail({ memory, relations, isFocused, height, width }) {
613
646
  return /* @__PURE__ */ jsxs5(
614
647
  Box5,
615
648
  {
@@ -617,16 +650,21 @@ function MemoryDetail({ memory, relations, isFocused }) {
617
650
  borderStyle: "round",
618
651
  borderColor: isFocused ? "blue" : "gray",
619
652
  paddingX: 1,
653
+ height,
620
654
  children: [
621
655
  /* @__PURE__ */ jsx5(Text5, { bold: true, color: isFocused ? "blue" : "gray", children: " Detail " }),
622
- !memory ? /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "Select a memory to view details" }) : /* @__PURE__ */ jsx5(DetailContent, { memory, relations })
656
+ !memory ? /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "Select a memory to view details" }) : /* @__PURE__ */ jsx5(DetailContent, { memory, relations, height, width })
623
657
  ]
624
658
  }
625
659
  );
626
660
  }
627
- function DetailContent({ memory, relations }) {
661
+ function DetailContent({ memory, relations, height, width }) {
628
662
  const life = computeLifespan(memory);
629
663
  const typeColor = TYPE_COLORS[memory.type] ?? "white";
664
+ const relationRows = relations.length > 0 ? relations.length + 2 : 0;
665
+ const contentRows = Math.max(MIN_CONTENT_ROWS, height - METADATA_ROWS - BORDER_ROWS - relationRows);
666
+ const contentWidth = Math.max(10, width - 4);
667
+ const preview = truncateContent(memory.content, contentRows, contentWidth);
630
668
  return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
631
669
  /* @__PURE__ */ jsx5(Text5, { bold: true, children: memory.title ?? "(untitled)" }),
632
670
  /* @__PURE__ */ jsx5(Text5, { children: " " }),
@@ -690,11 +728,30 @@ function DetailContent({ memory, relations }) {
690
728
  ] }),
691
729
  /* @__PURE__ */ jsx5(Text5, { children: " " }),
692
730
  /* @__PURE__ */ jsx5(Text5, { bold: true, children: "Content" }),
693
- /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "\u2500".repeat(40) }),
694
- /* @__PURE__ */ jsx5(Text5, { children: memory.content }),
731
+ /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "\u2500".repeat(Math.min(contentWidth, 40)) }),
732
+ preview.lines.map((line, i) => /* @__PURE__ */ jsx5(Text5, { children: line === "" ? " " : line }, `line-${i}`)),
733
+ preview.truncated && /* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
734
+ "\u2026 +",
735
+ preview.remainingLines,
736
+ " line",
737
+ preview.remainingLines === 1 ? "" : "s",
738
+ " \xB7 press Enter to view full"
739
+ ] }),
695
740
  relations.length > 0 && /* @__PURE__ */ jsx5(RelationsList, { relations, memoryId: memory.id })
696
741
  ] });
697
742
  }
743
+ function truncateContent(content, maxRows, wrapWidth) {
744
+ const allLines = wrapContent(content, wrapWidth);
745
+ if (allLines.length <= maxRows) {
746
+ return { lines: allLines, truncated: false, remainingLines: 0 };
747
+ }
748
+ const visible = Math.max(1, maxRows - 1);
749
+ return {
750
+ lines: allLines.slice(0, visible),
751
+ truncated: true,
752
+ remainingLines: allLines.length - visible
753
+ };
754
+ }
698
755
  function RelationsList({ relations, memoryId }) {
699
756
  return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginTop: 1, children: [
700
757
  /* @__PURE__ */ jsx5(Text5, { bold: true, children: "Relations" }),
@@ -719,17 +776,22 @@ function RelationsList({ relations, memoryId }) {
719
776
  import { useMemo as useMemo3 } from "react";
720
777
  import { Box as Box6, Text as Text6 } from "ink";
721
778
  import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
722
- function ProjectList({ memories, activeProject, isFocused }) {
779
+ function ProjectList({ memories, activeProject, isFocused, height }) {
723
780
  const rows = useMemo3(() => buildProjectRows(memories), [memories]);
781
+ const visibleRows = Math.max(1, height - 3);
782
+ const truncated = rows.length > visibleRows;
783
+ const displayed = truncated ? rows.slice(0, visibleRows - 1) : rows;
784
+ const hidden = rows.length - displayed.length;
724
785
  return /* @__PURE__ */ jsxs6(
725
786
  Box6,
726
787
  {
727
788
  flexDirection: "column",
728
789
  borderStyle: "round",
729
790
  borderColor: isFocused ? "magenta" : "gray",
791
+ height,
730
792
  children: [
731
793
  /* @__PURE__ */ jsx6(Text6, { bold: true, color: isFocused ? "magenta" : "gray", children: " Projects " }),
732
- rows.map((row) => {
794
+ displayed.map((row) => {
733
795
  const isActive = row.project === activeProject || row.project === void 0 && !activeProject;
734
796
  const name = (row.project ?? "All projects").padEnd(20).slice(0, 20);
735
797
  const healthColor = row.healthPct > 62 ? "green" : row.healthPct > 32 ? "yellow" : "red";
@@ -746,7 +808,12 @@ function ProjectList({ memories, activeProject, isFocused }) {
746
808
  "%"
747
809
  ] })
748
810
  ] }, row.project ?? "_all");
749
- })
811
+ }),
812
+ truncated && /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
813
+ " \u2026 +",
814
+ hidden,
815
+ " more"
816
+ ] })
750
817
  ]
751
818
  }
752
819
  );
@@ -837,7 +904,7 @@ import { Box as Box8, Text as Text8, useInput as useInput2 } from "ink";
837
904
  import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
838
905
  var BINDINGS = [
839
906
  ["j / k / \u2191\u2193", "Navigate list"],
840
- ["Enter", "Select memory"],
907
+ ["Enter", "Expand memory (full content + scroll)"],
841
908
  ["/", "Search (live filter)"],
842
909
  ["Esc", "Clear search"],
843
910
  ["1-5", "Filter by type (0 = all)"],
@@ -975,11 +1042,91 @@ function PurgeConfirm({ project, memoryCount, onConfirm, onCancel }) {
975
1042
  ] });
976
1043
  }
977
1044
 
978
- // src/commands/memory/dashboard/app.tsx
1045
+ // src/commands/memory/dashboard/components/expand-memory.tsx
1046
+ import { useState as useState3, useEffect as useEffect3 } from "react";
1047
+ import { Box as Box12, Text as Text12, useInput as useInput6 } from "ink";
979
1048
  import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
1049
+ function ExpandMemory({ memory, relations, onClose }) {
1050
+ const { columns, rows } = useTerminalSize();
1051
+ const [scroll, setScroll] = useState3(0);
1052
+ const contentWidth = Math.max(20, columns - 6);
1053
+ const chromeLines = 7 + (relations.length > 0 ? relations.length + 2 : 0);
1054
+ const viewportLines = Math.max(5, rows - chromeLines);
1055
+ const wrappedLines = wrapContent(memory.content, contentWidth);
1056
+ const totalLines = wrappedLines.length;
1057
+ const maxScroll = Math.max(0, totalLines - viewportLines);
1058
+ useEffect3(() => {
1059
+ setScroll(0);
1060
+ }, [memory.id]);
1061
+ useInput6((input, key) => {
1062
+ if (key.escape || input === "q") {
1063
+ onClose();
1064
+ return;
1065
+ }
1066
+ if (input === "j" || key.downArrow) setScroll((s) => Math.min(maxScroll, s + 1));
1067
+ if (input === "k" || key.upArrow) setScroll((s) => Math.max(0, s - 1));
1068
+ if (key.pageDown || input === " ") setScroll((s) => Math.min(maxScroll, s + viewportLines));
1069
+ if (key.pageUp) setScroll((s) => Math.max(0, s - viewportLines));
1070
+ if (input === "g") setScroll(0);
1071
+ if (input === "G") setScroll(maxScroll);
1072
+ });
1073
+ const typeColor = TYPE_COLORS[memory.type] ?? "white";
1074
+ const visible = wrappedLines.slice(scroll, scroll + viewportLines);
1075
+ const scrollInfo = totalLines > viewportLines ? ` [${scroll + 1}-${Math.min(totalLines, scroll + viewportLines)}/${totalLines}]` : ` [${totalLines} lines]`;
1076
+ const divider = "\u2500".repeat(Math.min(contentWidth, 80));
1077
+ return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "double", borderColor: "blue", paddingX: 1, children: [
1078
+ /* @__PURE__ */ jsxs12(Text12, { bold: true, children: [
1079
+ /* @__PURE__ */ jsxs12(Text12, { color: typeColor, children: [
1080
+ "[",
1081
+ memory.type,
1082
+ "]"
1083
+ ] }),
1084
+ " ",
1085
+ memory.title ?? "(untitled)"
1086
+ ] }),
1087
+ /* @__PURE__ */ jsxs12(Text12, { dimColor: true, children: [
1088
+ "id: ",
1089
+ memory.id.slice(0, 8),
1090
+ " | project: ",
1091
+ memory.project ?? "(none)",
1092
+ " | imp: ",
1093
+ memory.importance.toFixed(2),
1094
+ " | updated: ",
1095
+ formatRelativeTime(memory.updatedAt)
1096
+ ] }),
1097
+ /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: divider }),
1098
+ visible.map((line, i) => /* @__PURE__ */ jsx12(Text12, { children: line === "" ? " " : line }, `line-${scroll + i}`)),
1099
+ Array.from({ length: Math.max(0, viewportLines - visible.length) }).map((_, i) => /* @__PURE__ */ jsx12(Text12, { children: " " }, `pad-${i}`)),
1100
+ /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: divider }),
1101
+ relations.length > 0 && /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", children: [
1102
+ /* @__PURE__ */ jsx12(Text12, { bold: true, children: "Relations" }),
1103
+ relations.map((r, i) => {
1104
+ const relColor = RELATION_COLORS[r.relationType] ?? "white";
1105
+ const direction = r.sourceId === memory.id ? "\u2192" : "\u2190";
1106
+ const otherId = r.sourceId === memory.id ? r.targetId : r.sourceId;
1107
+ return /* @__PURE__ */ jsxs12(Text12, { children: [
1108
+ " ",
1109
+ direction,
1110
+ " ",
1111
+ /* @__PURE__ */ jsx12(Text12, { color: relColor, children: r.relationType }),
1112
+ " ",
1113
+ otherId
1114
+ ] }, i);
1115
+ })
1116
+ ] }),
1117
+ /* @__PURE__ */ jsxs12(Text12, { dimColor: true, children: [
1118
+ totalLines > viewportLines ? "j/k scroll \xB7 space/PgDn page \xB7 g/G top/bottom \xB7 " : "",
1119
+ "q/Esc close",
1120
+ scrollInfo
1121
+ ] })
1122
+ ] });
1123
+ }
1124
+
1125
+ // src/commands/memory/dashboard/app.tsx
1126
+ import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
980
1127
  function App({ dataSource }) {
981
1128
  const { exit } = useApp();
982
- const { rows, layout } = useTerminalSize();
1129
+ const { columns, rows, layout } = useTerminalSize();
983
1130
  const state = useDashboardState(dataSource);
984
1131
  useKeybindings({
985
1132
  navigateUp: state.navigateUp,
@@ -996,16 +1143,28 @@ function App({ dataSource }) {
996
1143
  purgeProject: state.promptPurge,
997
1144
  openProjectPicker: () => state.setShowProjectPicker((v) => !v),
998
1145
  showHelp: () => state.setShowHelp((v) => !v),
1146
+ expandMemory: state.expandMemory,
999
1147
  quit: exit
1000
1148
  }, {
1001
1149
  searchActive: state.searchActive,
1002
- pickerOpen: state.showProjectPicker
1150
+ pickerOpen: state.showProjectPicker,
1151
+ expandOpen: state.showExpand
1003
1152
  });
1004
1153
  if (state.showHelp) {
1005
- return /* @__PURE__ */ jsx12(HelpOverlay, { onClose: () => state.setShowHelp(false) });
1154
+ return /* @__PURE__ */ jsx13(HelpOverlay, { onClose: () => state.setShowHelp(false) });
1155
+ }
1156
+ if (state.showExpand && state.selectedMemory) {
1157
+ return /* @__PURE__ */ jsx13(
1158
+ ExpandMemory,
1159
+ {
1160
+ memory: state.selectedMemory,
1161
+ relations: state.relations,
1162
+ onClose: state.closeExpand
1163
+ }
1164
+ );
1006
1165
  }
1007
1166
  if (state.showProjectPicker) {
1008
- return /* @__PURE__ */ jsx12(
1167
+ return /* @__PURE__ */ jsx13(
1009
1168
  ProjectPicker,
1010
1169
  {
1011
1170
  projects: [...state.projects],
@@ -1019,7 +1178,7 @@ function App({ dataSource }) {
1019
1178
  );
1020
1179
  }
1021
1180
  if (state.showDeleteConfirm && state.selectedMemory) {
1022
- return /* @__PURE__ */ jsx12(
1181
+ return /* @__PURE__ */ jsx13(
1023
1182
  DeleteConfirm,
1024
1183
  {
1025
1184
  memory: state.selectedMemory,
@@ -1029,7 +1188,7 @@ function App({ dataSource }) {
1029
1188
  );
1030
1189
  }
1031
1190
  if (state.showPurgeConfirm && state.currentProject) {
1032
- return /* @__PURE__ */ jsx12(
1191
+ return /* @__PURE__ */ jsx13(
1033
1192
  PurgeConfirm,
1034
1193
  {
1035
1194
  project: state.currentProject,
@@ -1039,11 +1198,17 @@ function App({ dataSource }) {
1039
1198
  }
1040
1199
  );
1041
1200
  }
1042
- const contentHeight = Math.max(4, rows - 6);
1201
+ const contentHeight = Math.max(4, rows - 6 - (state.searchActive ? 1 : 0));
1043
1202
  const isNarrow = layout === "narrow";
1044
- return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", children: [
1045
- /* @__PURE__ */ jsx12(KeybindingBar, {}),
1046
- /* @__PURE__ */ jsx12(
1203
+ const listWidth = Math.floor(columns * 0.6);
1204
+ const rightWidth = columns - listWidth;
1205
+ const projectsCount = new Set(state.filteredMemories.map((m) => m.project ?? "(none)")).size + 1;
1206
+ const projectListHeight = isNarrow ? 0 : Math.min(Math.max(4, Math.floor(contentHeight / 3)), projectsCount + 3, 12);
1207
+ const listHeight = isNarrow ? Math.max(6, Math.floor(contentHeight * 0.6)) : contentHeight;
1208
+ const detailHeight = isNarrow ? Math.max(6, contentHeight - listHeight) : Math.max(6, contentHeight - projectListHeight);
1209
+ return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", children: [
1210
+ /* @__PURE__ */ jsx13(KeybindingBar, {}),
1211
+ /* @__PURE__ */ jsx13(
1047
1212
  Header,
1048
1213
  {
1049
1214
  project: state.currentProject,
@@ -1054,7 +1219,7 @@ function App({ dataSource }) {
1054
1219
  layout
1055
1220
  }
1056
1221
  ),
1057
- state.searchActive && /* @__PURE__ */ jsx12(
1222
+ state.searchActive && /* @__PURE__ */ jsx13(
1058
1223
  SearchBar,
1059
1224
  {
1060
1225
  query: state.searchQuery,
@@ -1062,41 +1227,44 @@ function App({ dataSource }) {
1062
1227
  onClose: () => state.setSearchQuery(state.searchQuery)
1063
1228
  }
1064
1229
  ),
1065
- /* @__PURE__ */ jsxs12(Box12, { flexDirection: isNarrow ? "column" : "row", children: [
1066
- /* @__PURE__ */ jsx12(Box12, { width: isNarrow ? "100%" : "60%", children: /* @__PURE__ */ jsx12(
1230
+ /* @__PURE__ */ jsxs13(Box13, { flexDirection: isNarrow ? "column" : "row", height: isNarrow ? void 0 : contentHeight, children: [
1231
+ /* @__PURE__ */ jsx13(Box13, { width: isNarrow ? "100%" : "60%", children: /* @__PURE__ */ jsx13(
1067
1232
  MemoryList,
1068
1233
  {
1069
1234
  memories: state.filteredMemories,
1070
1235
  selectedIndex: state.selectedIndex,
1071
1236
  isFocused: state.focusedPane === "list",
1072
- height: contentHeight
1237
+ height: listHeight
1073
1238
  }
1074
1239
  ) }),
1075
- /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", width: isNarrow ? "100%" : "40%", children: [
1076
- !isNarrow && /* @__PURE__ */ jsx12(
1240
+ /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", width: isNarrow ? "100%" : "40%", children: [
1241
+ !isNarrow && /* @__PURE__ */ jsx13(
1077
1242
  ProjectList,
1078
1243
  {
1079
1244
  memories: state.filteredMemories,
1080
1245
  activeProject: state.currentProject,
1081
- isFocused: state.focusedPane === "projects"
1246
+ isFocused: state.focusedPane === "projects",
1247
+ height: projectListHeight
1082
1248
  }
1083
1249
  ),
1084
- /* @__PURE__ */ jsx12(
1250
+ /* @__PURE__ */ jsx13(
1085
1251
  MemoryDetail,
1086
1252
  {
1087
1253
  memory: state.selectedMemory,
1088
1254
  relations: state.relations,
1089
- isFocused: state.focusedPane === "detail"
1255
+ isFocused: state.focusedPane === "detail",
1256
+ height: detailHeight,
1257
+ width: rightWidth
1090
1258
  }
1091
1259
  )
1092
1260
  ] })
1093
1261
  ] }),
1094
- /* @__PURE__ */ jsx12(StatsBar, { stats: state.stats, visible: state.filteredMemories })
1262
+ /* @__PURE__ */ jsx13(StatsBar, { stats: state.stats, visible: state.filteredMemories })
1095
1263
  ] });
1096
1264
  }
1097
1265
 
1098
1266
  // src/commands/memory/dashboard/tui.tsx
1099
- import { jsx as jsx13 } from "react/jsx-runtime";
1267
+ import { jsx as jsx14 } from "react/jsx-runtime";
1100
1268
  async function startTui(options) {
1101
1269
  const config = loadConfig(
1102
1270
  options?.dbPath ? { dataDir: options.dbPath } : void 0
@@ -1115,7 +1283,7 @@ async function startTui(options) {
1115
1283
  );
1116
1284
  let shuttingDown = false;
1117
1285
  const { waitUntilExit, unmount } = render(
1118
- /* @__PURE__ */ jsx13(App, { dataSource })
1286
+ /* @__PURE__ */ jsx14(App, { dataSource })
1119
1287
  );
1120
1288
  function shutdown() {
1121
1289
  if (shuttingDown) return;
@@ -1138,4 +1306,4 @@ async function startTui(options) {
1138
1306
  export {
1139
1307
  startTui
1140
1308
  };
1141
- //# sourceMappingURL=tui-56GQMXXT.js.map
1309
+ //# sourceMappingURL=tui-ELOJ37ZA.js.map