claude-launchpad 1.14.0 → 1.16.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/dist/{chunk-D6RAMWH6.js → chunk-7KB5YGQZ.js} +2 -2
- package/dist/{chunk-UN43OVRW.js → chunk-DLDVXHI3.js} +2 -2
- package/dist/{chunk-M6GVFN67.js → chunk-IPGNXDJF.js} +2 -2
- package/dist/{chunk-VF7U63AI.js → chunk-LCKV24Q3.js} +3 -3
- package/dist/{chunk-OPORVSAF.js → chunk-MX3T2VEX.js} +3 -3
- package/dist/{chunk-QEPE3WVF.js → chunk-U2TFIUGE.js} +57 -5
- package/dist/chunk-U2TFIUGE.js.map +1 -0
- package/dist/cli.js +136 -62
- package/dist/cli.js.map +1 -1
- package/dist/commands/memory/server.js +4 -4
- package/dist/{context-YIPO4LBS.js → context-3GHG7KW6.js} +6 -6
- package/dist/{doctor-DCHFJ3XV.js → doctor-EKGJ2YAO.js} +4 -4
- package/dist/{install-D32PV7SF.js → install-543ZKMXX.js} +6 -6
- package/dist/{pull-YUQTDRUP.js → pull-ULSZEVCR.js} +8 -8
- package/dist/{push-U4IVTFOU.js → push-JXCWX4NY.js} +8 -8
- package/dist/{require-deps-WDMHDGBN.js → require-deps-AEDO5YRM.js} +3 -3
- package/dist/{stats-77BYLKYP.js → stats-63L7C24W.js} +7 -7
- package/dist/{sync-DTCWK2CY.js → sync-QTJ6BXQ4.js} +5 -5
- package/dist/{sync-clean-ACZCB3NZ.js → sync-clean-OJEK4XH4.js} +3 -3
- package/dist/{sync-status-2V2RCYZO.js → sync-status-EAX527SC.js} +8 -8
- package/dist/{tui-HVJNLRY2.js → tui-BS4XXLOC.js} +92 -45
- package/dist/tui-BS4XXLOC.js.map +1 -0
- package/package.json +2 -1
- package/dist/chunk-QEPE3WVF.js.map +0 -1
- package/dist/tui-HVJNLRY2.js.map +0 -1
- /package/dist/{chunk-D6RAMWH6.js.map → chunk-7KB5YGQZ.js.map} +0 -0
- /package/dist/{chunk-UN43OVRW.js.map → chunk-DLDVXHI3.js.map} +0 -0
- /package/dist/{chunk-M6GVFN67.js.map → chunk-IPGNXDJF.js.map} +0 -0
- /package/dist/{chunk-VF7U63AI.js.map → chunk-LCKV24Q3.js.map} +0 -0
- /package/dist/{chunk-OPORVSAF.js.map → chunk-MX3T2VEX.js.map} +0 -0
- /package/dist/{context-YIPO4LBS.js.map → context-3GHG7KW6.js.map} +0 -0
- /package/dist/{doctor-DCHFJ3XV.js.map → doctor-EKGJ2YAO.js.map} +0 -0
- /package/dist/{install-D32PV7SF.js.map → install-543ZKMXX.js.map} +0 -0
- /package/dist/{pull-YUQTDRUP.js.map → pull-ULSZEVCR.js.map} +0 -0
- /package/dist/{push-U4IVTFOU.js.map → push-JXCWX4NY.js.map} +0 -0
- /package/dist/{require-deps-WDMHDGBN.js.map → require-deps-AEDO5YRM.js.map} +0 -0
- /package/dist/{stats-77BYLKYP.js.map → stats-63L7C24W.js.map} +0 -0
- /package/dist/{sync-DTCWK2CY.js.map → sync-QTJ6BXQ4.js.map} +0 -0
- /package/dist/{sync-clean-ACZCB3NZ.js.map → sync-clean-OJEK4XH4.js.map} +0 -0
- /package/dist/{sync-status-2V2RCYZO.js.map → sync-status-EAX527SC.js.map} +0 -0
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "./chunk-HSGSTSVN.js";
|
|
6
6
|
import {
|
|
7
7
|
migrate
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-MX3T2VEX.js";
|
|
9
9
|
import {
|
|
10
10
|
MemoryRepo
|
|
11
11
|
} from "./chunk-IDH3M4EI.js";
|
|
@@ -15,9 +15,9 @@ import {
|
|
|
15
15
|
createDatabase,
|
|
16
16
|
loadConfig,
|
|
17
17
|
resolveDataDir
|
|
18
|
-
} from "./chunk-
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-
|
|
18
|
+
} from "./chunk-DLDVXHI3.js";
|
|
19
|
+
import "./chunk-7KB5YGQZ.js";
|
|
20
|
+
import "./chunk-U2TFIUGE.js";
|
|
21
21
|
|
|
22
22
|
// src/commands/memory/dashboard/tui.tsx
|
|
23
23
|
import { render } from "ink";
|
|
@@ -63,7 +63,11 @@ var DashboardDataSource = class {
|
|
|
63
63
|
}
|
|
64
64
|
return results;
|
|
65
65
|
}
|
|
66
|
-
/**
|
|
66
|
+
/** Resolve a memory id to its title for relation display (cache-only, no I/O). */
|
|
67
|
+
getMemoryTitle(id) {
|
|
68
|
+
const m = this.#cachedMemories.find((mem) => mem.id === id);
|
|
69
|
+
return m?.title ?? void 0;
|
|
70
|
+
}
|
|
67
71
|
getRelationsForMemory(id) {
|
|
68
72
|
return this.#relationRepo.getByMemory(id);
|
|
69
73
|
}
|
|
@@ -230,7 +234,6 @@ function useDashboardState(dataSource) {
|
|
|
230
234
|
const [currentProject, setCurrentProject] = useState();
|
|
231
235
|
const [sortMode, setSortMode] = useState("importance");
|
|
232
236
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
233
|
-
const [focusedPane, setFocusedPane] = useState("list");
|
|
234
237
|
const [showHelp, setShowHelp] = useState(false);
|
|
235
238
|
const [showProjectPicker, setShowProjectPicker] = useState(false);
|
|
236
239
|
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
|
|
@@ -258,7 +261,8 @@ function useDashboardState(dataSource) {
|
|
|
258
261
|
) : withLife;
|
|
259
262
|
return sortMemories(withSearch, sortMode);
|
|
260
263
|
}, [dataSource, revision, typeFilter, lifespanFilter, searchQuery, currentProject, sortMode]);
|
|
261
|
-
const
|
|
264
|
+
const clampedIndex = Math.max(0, Math.min(selectedIndex, Math.max(0, filteredMemories.length - 1)));
|
|
265
|
+
const selectedMemory = filteredMemories[clampedIndex];
|
|
262
266
|
const relations = useMemo(
|
|
263
267
|
() => selectedMemory ? dataSource.getRelationsForMemory(selectedMemory.id) : [],
|
|
264
268
|
[dataSource, selectedMemory, revision]
|
|
@@ -268,10 +272,12 @@ function useDashboardState(dataSource) {
|
|
|
268
272
|
return dataSource.getStats();
|
|
269
273
|
}, [dataSource, revision]);
|
|
270
274
|
const navigateUp = useCallback(() => {
|
|
271
|
-
|
|
272
|
-
|
|
275
|
+
const last = filteredMemories.length - 1;
|
|
276
|
+
setSelectedIndex((i) => Math.max(0, Math.min(i, last) - 1));
|
|
277
|
+
}, [filteredMemories.length]);
|
|
273
278
|
const navigateDown = useCallback(() => {
|
|
274
|
-
|
|
279
|
+
const last = filteredMemories.length - 1;
|
|
280
|
+
setSelectedIndex((i) => Math.max(0, Math.min(last, Math.min(i, last) + 1)));
|
|
275
281
|
}, [filteredMemories.length]);
|
|
276
282
|
const cycleSort = useCallback(() => {
|
|
277
283
|
setSortMode((m) => SORT_MODES[(SORT_MODES.indexOf(m) + 1) % SORT_MODES.length]);
|
|
@@ -296,14 +302,15 @@ function useDashboardState(dataSource) {
|
|
|
296
302
|
});
|
|
297
303
|
setSelectedIndex(0);
|
|
298
304
|
}, [projects]);
|
|
299
|
-
const focusNext = useCallback(() => {
|
|
300
|
-
setFocusedPane((p) => p === "list" ? "projects" : p === "projects" ? "detail" : "list");
|
|
301
|
-
}, []);
|
|
302
305
|
const filterByType = useCallback((type) => {
|
|
303
306
|
setTypeFilter(type);
|
|
304
307
|
setSelectedIndex(0);
|
|
305
308
|
}, []);
|
|
306
309
|
const openSearch = useCallback(() => setSearchActive(true), []);
|
|
310
|
+
const submitSearch = useCallback(() => {
|
|
311
|
+
setSearchActive(false);
|
|
312
|
+
setSelectedIndex(0);
|
|
313
|
+
}, []);
|
|
307
314
|
const closeSearch = useCallback(() => {
|
|
308
315
|
setSearchActive(false);
|
|
309
316
|
setSearchQuery("");
|
|
@@ -345,8 +352,6 @@ function useDashboardState(dataSource) {
|
|
|
345
352
|
searchActive,
|
|
346
353
|
currentProject,
|
|
347
354
|
sortMode,
|
|
348
|
-
selectedIndex,
|
|
349
|
-
focusedPane,
|
|
350
355
|
showHelp,
|
|
351
356
|
showProjectPicker,
|
|
352
357
|
showDeleteConfirm,
|
|
@@ -357,6 +362,7 @@ function useDashboardState(dataSource) {
|
|
|
357
362
|
relations,
|
|
358
363
|
projects,
|
|
359
364
|
stats,
|
|
365
|
+
selectedIndex: clampedIndex,
|
|
360
366
|
setSearchQuery,
|
|
361
367
|
setCurrentProject,
|
|
362
368
|
setSelectedIndex,
|
|
@@ -368,9 +374,9 @@ function useDashboardState(dataSource) {
|
|
|
368
374
|
cycleLifespan,
|
|
369
375
|
cycleProjectNext,
|
|
370
376
|
cycleProjectPrev,
|
|
371
|
-
focusNext,
|
|
372
377
|
filterByType,
|
|
373
378
|
openSearch,
|
|
379
|
+
submitSearch,
|
|
374
380
|
closeSearch,
|
|
375
381
|
promptDelete,
|
|
376
382
|
confirmDelete,
|
|
@@ -405,6 +411,7 @@ var TYPE_KEYS = {
|
|
|
405
411
|
};
|
|
406
412
|
function useKeybindings(actions, opts) {
|
|
407
413
|
useInput((input, key) => {
|
|
414
|
+
if (opts.modalOpen) return;
|
|
408
415
|
if (opts.expandOpen) return;
|
|
409
416
|
if (opts.searchActive) {
|
|
410
417
|
if (key.escape) actions.closeSearch();
|
|
@@ -425,9 +432,8 @@ function useKeybindings(actions, opts) {
|
|
|
425
432
|
if (input === "p") actions.openProjectPicker();
|
|
426
433
|
if (input === "]" || key.rightArrow) actions.cycleProjectNext();
|
|
427
434
|
if (input === "[" || key.leftArrow) actions.cycleProjectPrev();
|
|
428
|
-
if (
|
|
429
|
-
if (input === "
|
|
430
|
-
if (input === "d") actions.purgeProject();
|
|
435
|
+
if (input === "r" || input === "d") actions.removeMemory();
|
|
436
|
+
if (input === "X") actions.purgeProject();
|
|
431
437
|
if (input === "?") actions.showHelp();
|
|
432
438
|
if (key.return) actions.expandMemory();
|
|
433
439
|
if (input === "q") actions.quit();
|
|
@@ -466,9 +472,8 @@ var HINTS = [
|
|
|
466
472
|
["1-5", "type"],
|
|
467
473
|
["l", "life"],
|
|
468
474
|
["s", "sort"],
|
|
469
|
-
["
|
|
470
|
-
["
|
|
471
|
-
["Tab", "focus"],
|
|
475
|
+
["d", "delete"],
|
|
476
|
+
["X", "purge project"],
|
|
472
477
|
["?", "help"],
|
|
473
478
|
["q", "quit"]
|
|
474
479
|
];
|
|
@@ -519,11 +524,11 @@ function Header({ project, typeFilter, lifespanFilter, sortMode, searchQuery, la
|
|
|
519
524
|
import { Box as Box3, Text as Text3 } from "ink";
|
|
520
525
|
import TextInput from "ink-text-input";
|
|
521
526
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
522
|
-
function SearchBar({ query, onChange,
|
|
527
|
+
function SearchBar({ query, onChange, onSubmit }) {
|
|
523
528
|
return /* @__PURE__ */ jsxs3(Box3, { children: [
|
|
524
529
|
/* @__PURE__ */ jsx3(Text3, { color: "yellow", children: "Search: " }),
|
|
525
|
-
/* @__PURE__ */ jsx3(TextInput, { value: query, onChange, onSubmit
|
|
526
|
-
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: " (
|
|
530
|
+
/* @__PURE__ */ jsx3(TextInput, { value: query, onChange, onSubmit }),
|
|
531
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: " (Enter apply \xB7 Esc cancel)" })
|
|
527
532
|
] });
|
|
528
533
|
}
|
|
529
534
|
|
|
@@ -646,7 +651,7 @@ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
|
646
651
|
var METADATA_ROWS = 18;
|
|
647
652
|
var BORDER_ROWS = 2;
|
|
648
653
|
var MIN_CONTENT_ROWS = 2;
|
|
649
|
-
function MemoryDetail({ memory, relations, isFocused, height, width }) {
|
|
654
|
+
function MemoryDetail({ memory, relations, isFocused, height, width, resolveTitle }) {
|
|
650
655
|
return /* @__PURE__ */ jsxs5(
|
|
651
656
|
Box5,
|
|
652
657
|
{
|
|
@@ -657,12 +662,12 @@ function MemoryDetail({ memory, relations, isFocused, height, width }) {
|
|
|
657
662
|
height,
|
|
658
663
|
children: [
|
|
659
664
|
/* @__PURE__ */ jsx5(Text5, { bold: true, color: isFocused ? "blue" : "gray", children: " Detail " }),
|
|
660
|
-
!memory ? /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "Select a memory to view details" }) : /* @__PURE__ */ jsx5(DetailContent, { memory, relations, height, width })
|
|
665
|
+
!memory ? /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "Select a memory to view details" }) : /* @__PURE__ */ jsx5(DetailContent, { resolveTitle, memory, relations, height, width })
|
|
661
666
|
]
|
|
662
667
|
}
|
|
663
668
|
);
|
|
664
669
|
}
|
|
665
|
-
function DetailContent({ memory, relations, height, width }) {
|
|
670
|
+
function DetailContent({ memory, relations, height, width, resolveTitle }) {
|
|
666
671
|
const life = computeLifespan(memory);
|
|
667
672
|
const typeColor = TYPE_COLORS[memory.type] ?? "white";
|
|
668
673
|
const relationRows = relations.length > 0 ? relations.length + 2 : 0;
|
|
@@ -741,7 +746,7 @@ function DetailContent({ memory, relations, height, width }) {
|
|
|
741
746
|
preview.remainingLines === 1 ? "" : "s",
|
|
742
747
|
" \xB7 press Enter to view full"
|
|
743
748
|
] }),
|
|
744
|
-
relations.length > 0 && /* @__PURE__ */ jsx5(RelationsList, { relations, memoryId: memory.id })
|
|
749
|
+
relations.length > 0 && /* @__PURE__ */ jsx5(RelationsList, { resolveTitle, relations, memoryId: memory.id })
|
|
745
750
|
] });
|
|
746
751
|
}
|
|
747
752
|
function truncateContent(content, maxRows, wrapWidth) {
|
|
@@ -756,7 +761,7 @@ function truncateContent(content, maxRows, wrapWidth) {
|
|
|
756
761
|
remainingLines: allLines.length - visible
|
|
757
762
|
};
|
|
758
763
|
}
|
|
759
|
-
function RelationsList({ relations, memoryId }) {
|
|
764
|
+
function RelationsList({ relations, memoryId, resolveTitle }) {
|
|
760
765
|
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginTop: 1, children: [
|
|
761
766
|
/* @__PURE__ */ jsx5(Text5, { bold: true, children: "Relations" }),
|
|
762
767
|
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "\u2500".repeat(40) }),
|
|
@@ -764,13 +769,14 @@ function RelationsList({ relations, memoryId }) {
|
|
|
764
769
|
const relColor = RELATION_COLORS[r.relationType] ?? "white";
|
|
765
770
|
const direction = r.sourceId === memoryId ? "\u2192" : "\u2190";
|
|
766
771
|
const otherId = r.sourceId === memoryId ? r.targetId : r.sourceId;
|
|
772
|
+
const label = resolveTitle?.(otherId) ?? otherId.slice(0, 8);
|
|
767
773
|
return /* @__PURE__ */ jsxs5(Text5, { children: [
|
|
768
774
|
" ",
|
|
769
775
|
direction,
|
|
770
776
|
" ",
|
|
771
777
|
/* @__PURE__ */ jsx5(Text5, { color: relColor, children: r.relationType }),
|
|
772
778
|
" ",
|
|
773
|
-
|
|
779
|
+
label
|
|
774
780
|
] }, i);
|
|
775
781
|
})
|
|
776
782
|
] });
|
|
@@ -916,9 +922,8 @@ var BINDINGS = [
|
|
|
916
922
|
["s", "Cycle sort mode"],
|
|
917
923
|
["p", "Open project picker"],
|
|
918
924
|
["[ / ]", "Previous / next project"],
|
|
919
|
-
["r", "
|
|
920
|
-
["
|
|
921
|
-
["Tab", "Focus next pane"],
|
|
925
|
+
["d / r", "Delete selected memory"],
|
|
926
|
+
["X", "Purge all memories for current project"],
|
|
922
927
|
["?", "Show this help"],
|
|
923
928
|
["q", "Quit"]
|
|
924
929
|
];
|
|
@@ -1050,7 +1055,7 @@ function PurgeConfirm({ project, memoryCount, onConfirm, onCancel }) {
|
|
|
1050
1055
|
import { useState as useState3, useEffect as useEffect3 } from "react";
|
|
1051
1056
|
import { Box as Box12, Text as Text12, useInput as useInput6 } from "ink";
|
|
1052
1057
|
import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1053
|
-
function ExpandMemory({ memory, relations, onClose }) {
|
|
1058
|
+
function ExpandMemory({ memory, relations, onClose, resolveTitle }) {
|
|
1054
1059
|
const { columns, rows } = useTerminalSize();
|
|
1055
1060
|
const [scroll, setScroll] = useState3(0);
|
|
1056
1061
|
const contentWidth = Math.max(20, columns - 6);
|
|
@@ -1108,13 +1113,14 @@ function ExpandMemory({ memory, relations, onClose }) {
|
|
|
1108
1113
|
const relColor = RELATION_COLORS[r.relationType] ?? "white";
|
|
1109
1114
|
const direction = r.sourceId === memory.id ? "\u2192" : "\u2190";
|
|
1110
1115
|
const otherId = r.sourceId === memory.id ? r.targetId : r.sourceId;
|
|
1116
|
+
const label = resolveTitle?.(otherId) ?? otherId.slice(0, 8);
|
|
1111
1117
|
return /* @__PURE__ */ jsxs12(Text12, { children: [
|
|
1112
1118
|
" ",
|
|
1113
1119
|
direction,
|
|
1114
1120
|
" ",
|
|
1115
1121
|
/* @__PURE__ */ jsx12(Text12, { color: relColor, children: r.relationType }),
|
|
1116
1122
|
" ",
|
|
1117
|
-
|
|
1123
|
+
label
|
|
1118
1124
|
] }, i);
|
|
1119
1125
|
})
|
|
1120
1126
|
] }),
|
|
@@ -1142,7 +1148,6 @@ function App({ dataSource }) {
|
|
|
1142
1148
|
cycleProjectNext: state.cycleProjectNext,
|
|
1143
1149
|
cycleProjectPrev: state.cycleProjectPrev,
|
|
1144
1150
|
cycleSort: state.cycleSort,
|
|
1145
|
-
focusNext: state.focusNext,
|
|
1146
1151
|
removeMemory: state.promptDelete,
|
|
1147
1152
|
purgeProject: state.promptPurge,
|
|
1148
1153
|
openProjectPicker: () => state.setShowProjectPicker((v) => !v),
|
|
@@ -1152,7 +1157,8 @@ function App({ dataSource }) {
|
|
|
1152
1157
|
}, {
|
|
1153
1158
|
searchActive: state.searchActive,
|
|
1154
1159
|
pickerOpen: state.showProjectPicker,
|
|
1155
|
-
expandOpen: state.showExpand
|
|
1160
|
+
expandOpen: state.showExpand,
|
|
1161
|
+
modalOpen: state.showDeleteConfirm || state.showPurgeConfirm || state.showHelp
|
|
1156
1162
|
});
|
|
1157
1163
|
if (state.showHelp) {
|
|
1158
1164
|
return /* @__PURE__ */ jsx13(HelpOverlay, { onClose: () => state.setShowHelp(false) });
|
|
@@ -1163,6 +1169,7 @@ function App({ dataSource }) {
|
|
|
1163
1169
|
{
|
|
1164
1170
|
memory: state.selectedMemory,
|
|
1165
1171
|
relations: state.relations,
|
|
1172
|
+
resolveTitle: (id) => dataSource.getMemoryTitle(id),
|
|
1166
1173
|
onClose: state.closeExpand
|
|
1167
1174
|
}
|
|
1168
1175
|
);
|
|
@@ -1228,7 +1235,7 @@ function App({ dataSource }) {
|
|
|
1228
1235
|
{
|
|
1229
1236
|
query: state.searchQuery,
|
|
1230
1237
|
onChange: state.setSearchQuery,
|
|
1231
|
-
|
|
1238
|
+
onSubmit: state.submitSearch
|
|
1232
1239
|
}
|
|
1233
1240
|
),
|
|
1234
1241
|
/* @__PURE__ */ jsxs13(Box13, { flexDirection: isNarrow ? "column" : "row", height: isNarrow ? void 0 : contentHeight, children: [
|
|
@@ -1237,7 +1244,7 @@ function App({ dataSource }) {
|
|
|
1237
1244
|
{
|
|
1238
1245
|
memories: state.filteredMemories,
|
|
1239
1246
|
selectedIndex: state.selectedIndex,
|
|
1240
|
-
isFocused:
|
|
1247
|
+
isFocused: true,
|
|
1241
1248
|
height: listHeight
|
|
1242
1249
|
}
|
|
1243
1250
|
) }),
|
|
@@ -1247,7 +1254,7 @@ function App({ dataSource }) {
|
|
|
1247
1254
|
{
|
|
1248
1255
|
memories: state.filteredMemories,
|
|
1249
1256
|
activeProject: state.currentProject,
|
|
1250
|
-
isFocused:
|
|
1257
|
+
isFocused: false,
|
|
1251
1258
|
height: projectListHeight
|
|
1252
1259
|
}
|
|
1253
1260
|
),
|
|
@@ -1256,7 +1263,8 @@ function App({ dataSource }) {
|
|
|
1256
1263
|
{
|
|
1257
1264
|
memory: state.selectedMemory,
|
|
1258
1265
|
relations: state.relations,
|
|
1259
|
-
|
|
1266
|
+
resolveTitle: (id) => dataSource.getMemoryTitle(id),
|
|
1267
|
+
isFocused: false,
|
|
1260
1268
|
height: detailHeight,
|
|
1261
1269
|
width: rightWidth
|
|
1262
1270
|
}
|
|
@@ -1267,8 +1275,47 @@ function App({ dataSource }) {
|
|
|
1267
1275
|
] });
|
|
1268
1276
|
}
|
|
1269
1277
|
|
|
1278
|
+
// src/commands/memory/dashboard/components/error-boundary.tsx
|
|
1279
|
+
import React6 from "react";
|
|
1280
|
+
import { Box as Box14, Text as Text13, useApp as useApp2, useInput as useInput7 } from "ink";
|
|
1281
|
+
import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1282
|
+
function CrashScreen({
|
|
1283
|
+
message
|
|
1284
|
+
}) {
|
|
1285
|
+
const { exit } = useApp2();
|
|
1286
|
+
useInput7((input) => {
|
|
1287
|
+
if (input === "q") exit();
|
|
1288
|
+
});
|
|
1289
|
+
return /* @__PURE__ */ jsxs14(
|
|
1290
|
+
Box14,
|
|
1291
|
+
{
|
|
1292
|
+
flexDirection: "column",
|
|
1293
|
+
borderStyle: "round",
|
|
1294
|
+
borderColor: "red",
|
|
1295
|
+
padding: 1,
|
|
1296
|
+
children: [
|
|
1297
|
+
/* @__PURE__ */ jsx14(Text13, { bold: true, color: "red", children: "Dashboard crashed" }),
|
|
1298
|
+
/* @__PURE__ */ jsx14(Text13, { children: message }),
|
|
1299
|
+
/* @__PURE__ */ jsx14(Text13, { dimColor: true, children: "Your data is untouched. Press q to quit." })
|
|
1300
|
+
]
|
|
1301
|
+
}
|
|
1302
|
+
);
|
|
1303
|
+
}
|
|
1304
|
+
var DashboardErrorBoundary = class extends React6.Component {
|
|
1305
|
+
state = { error: null };
|
|
1306
|
+
static getDerivedStateFromError(error) {
|
|
1307
|
+
return { error };
|
|
1308
|
+
}
|
|
1309
|
+
render() {
|
|
1310
|
+
if (this.state.error) {
|
|
1311
|
+
return /* @__PURE__ */ jsx14(CrashScreen, { message: this.state.error.message });
|
|
1312
|
+
}
|
|
1313
|
+
return this.props.children;
|
|
1314
|
+
}
|
|
1315
|
+
};
|
|
1316
|
+
|
|
1270
1317
|
// src/commands/memory/dashboard/tui.tsx
|
|
1271
|
-
import { jsx as
|
|
1318
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1272
1319
|
async function startTui(options) {
|
|
1273
1320
|
const config = loadConfig(
|
|
1274
1321
|
options?.dbPath ? { dataDir: options.dbPath } : void 0
|
|
@@ -1287,7 +1334,7 @@ async function startTui(options) {
|
|
|
1287
1334
|
);
|
|
1288
1335
|
let shuttingDown = false;
|
|
1289
1336
|
const { waitUntilExit, unmount } = render(
|
|
1290
|
-
/* @__PURE__ */
|
|
1337
|
+
/* @__PURE__ */ jsx15(DashboardErrorBoundary, { children: /* @__PURE__ */ jsx15(App, { dataSource }) })
|
|
1291
1338
|
);
|
|
1292
1339
|
function shutdown() {
|
|
1293
1340
|
if (shuttingDown) return;
|
|
@@ -1310,4 +1357,4 @@ async function startTui(options) {
|
|
|
1310
1357
|
export {
|
|
1311
1358
|
startTui
|
|
1312
1359
|
};
|
|
1313
|
-
//# sourceMappingURL=tui-
|
|
1360
|
+
//# sourceMappingURL=tui-BS4XXLOC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/memory/dashboard/tui.tsx","../src/commands/memory/dashboard/data/data-source.ts","../src/commands/memory/dashboard/app.tsx","../src/commands/memory/dashboard/hooks/use-dashboard-state.ts","../src/commands/memory/dashboard/data/formatters.ts","../src/commands/memory/dashboard/hooks/use-keybindings.ts","../src/commands/memory/dashboard/hooks/use-terminal-size.ts","../src/commands/memory/dashboard/components/keybinding-bar.tsx","../src/commands/memory/dashboard/components/header.tsx","../src/commands/memory/dashboard/components/search-bar.tsx","../src/commands/memory/dashboard/components/memory-list.tsx","../src/commands/memory/dashboard/colors.ts","../src/commands/memory/dashboard/components/memory-detail.tsx","../src/commands/memory/dashboard/data/wrap.ts","../src/commands/memory/dashboard/components/project-list.tsx","../src/commands/memory/dashboard/components/stats-bar.tsx","../src/commands/memory/dashboard/components/help-overlay.tsx","../src/commands/memory/dashboard/components/project-picker.tsx","../src/commands/memory/dashboard/components/delete-confirm.tsx","../src/commands/memory/dashboard/components/purge-confirm.tsx","../src/commands/memory/dashboard/components/expand-memory.tsx","../src/commands/memory/dashboard/components/error-boundary.tsx"],"sourcesContent":["import React from 'react';\nimport { render } from 'ink';\nimport { createDatabase, closeDatabase } from '../storage/database.js';\nimport { migrate } from '../storage/migrator.js';\nimport { MemoryRepo } from '../storage/memory-repo.js';\nimport { RelationRepo } from '../storage/relation-repo.js';\nimport { SearchRepo } from '../storage/search-repo.js';\nimport { loadConfig, resolveDataDir } from '../config.js';\nimport { DashboardDataSource } from './data/data-source.js';\nimport { App } from './app.js';\nimport { DashboardErrorBoundary } from './components/error-boundary.js';\n\nexport interface TuiOptions {\n readonly dbPath?: string;\n}\n\nexport async function startTui(options?: TuiOptions): Promise<void> {\n const config = loadConfig(\n options?.dbPath ? { dataDir: options.dbPath } : undefined,\n );\n const dataDir = resolveDataDir(config.dataDir);\n const db = createDatabase({ dataDir });\n migrate(db);\n\n const memoryRepo = new MemoryRepo(db);\n const relationRepo = new RelationRepo(db);\n const searchRepo = new SearchRepo(db);\n\n const dataSource = new DashboardDataSource(\n memoryRepo, relationRepo, searchRepo, dataDir,\n );\n\n let shuttingDown = false;\n\n const { waitUntilExit, unmount } = render(\n <DashboardErrorBoundary>\n <App dataSource={dataSource} />\n </DashboardErrorBoundary>,\n );\n\n function shutdown(): void {\n if (shuttingDown) return;\n shuttingDown = true;\n dataSource.stopWatching();\n unmount();\n closeDatabase(db);\n }\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n try {\n await waitUntilExit();\n } finally {\n if (!shuttingDown) {\n dataSource.stopWatching();\n closeDatabase(db);\n }\n }\n}\n","import { statSync, watchFile, unwatchFile } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { MemoryRepo } from \"../../storage/memory-repo.js\";\nimport type { RelationRepo } from \"../../storage/relation-repo.js\";\nimport type { SearchRepo } from \"../../storage/search-repo.js\";\nimport type { Memory, Relation } from \"../../types.js\";\n\n// -- Types --------------------------------------------------------------------\n\nexport interface MemoryFilter {\n readonly type?: string;\n readonly project?: string;\n readonly query?: string;\n}\n\nexport interface DashboardStats {\n readonly total: number;\n readonly byType: Record<string, number>;\n readonly byProject: Record<string, number>;\n readonly relations: number;\n readonly dbSizeBytes: number;\n readonly oldest: string | null;\n readonly newest: string | null;\n}\n\n// -- Data Source --------------------------------------------------------------\n\nexport class DashboardDataSource {\n readonly #memoryRepo: MemoryRepo;\n readonly #relationRepo: RelationRepo;\n readonly #searchRepo: SearchRepo;\n readonly #dbPath: string;\n\n #cachedMemories: readonly Memory[] = [];\n\n constructor(\n memoryRepo: MemoryRepo,\n relationRepo: RelationRepo,\n searchRepo: SearchRepo,\n dataDir: string,\n ) {\n this.#memoryRepo = memoryRepo;\n this.#relationRepo = relationRepo;\n this.#searchRepo = searchRepo;\n this.#dbPath = join(dataDir, \"memory.db\");\n }\n\n /** Re-query all memories from DB and cache them. Excludes soft-deleted (importance=0). */\n refresh(): void {\n this.#cachedMemories = this.#memoryRepo\n .getAll()\n .filter((m) => m.importance > 0);\n }\n\n /** Return cached memories, optionally filtered by type, project, or FTS query. */\n getMemories(filter?: MemoryFilter): readonly Memory[] {\n if (!filter) return this.#cachedMemories;\n\n let results: readonly Memory[] = this.#cachedMemories;\n\n if (filter.type) {\n const t = filter.type;\n results = results.filter((m) => m.type === t);\n }\n\n if (filter.project) {\n const p = filter.project;\n results = results.filter((m) => m.project === p);\n }\n\n if (filter.query) {\n const matches = this.#searchRepo.searchFts({\n query: filter.query,\n limit: 100,\n });\n const matchedIds = new Set(matches.map((m) => m.memoryId));\n results = results.filter((m) => matchedIds.has(m.id));\n }\n\n return results;\n }\n\n /** Resolve a memory id to its title for relation display (cache-only, no I/O). */\n getMemoryTitle(id: string): string | undefined {\n const m = this.#cachedMemories.find((mem) => mem.id === id);\n return m?.title ?? undefined;\n }\n\n getRelationsForMemory(id: string): readonly Relation[] {\n return this.#relationRepo.getByMemory(id);\n }\n\n /** Compute aggregate stats from cached data + DB queries. */\n getStats(): DashboardStats {\n const total = this.#memoryRepo.count();\n const byType = this.#memoryRepo.countByType();\n const relations = this.#relationRepo.count();\n const { oldest, newest } = this.#memoryRepo.dateRange();\n const dbSizeBytes = this.#getDbSize();\n const byProject = this.#computeByProject();\n\n return { total, byType, byProject, relations, dbSizeBytes, oldest, newest };\n }\n\n /** Derive unique project names from cached memories. */\n getProjects(): readonly string[] {\n const projects = new Set<string>();\n for (const m of this.#cachedMemories) {\n if (m.project) {\n projects.add(m.project);\n }\n }\n return [...projects].sort();\n }\n\n /** Watch the DB file for changes (2s polling interval). Only fires on mtime change. */\n startWatching(onChange: () => void): void {\n let lastMtime = 0;\n watchFile(this.#dbPath, { interval: 2000 }, (curr) => {\n const mtime = curr.mtimeMs;\n if (mtime === lastMtime) return;\n lastMtime = mtime;\n this.refresh();\n onChange();\n });\n }\n\n /** Hard-delete a memory by ID. Returns true if deleted. */\n deleteMemory(id: string): boolean {\n return this.#memoryRepo.hardDelete(id);\n }\n\n /** Count memories for a project (unfiltered). */\n countByProject(project: string): number {\n return this.#cachedMemories.filter((m) => m.project === project).length;\n }\n\n /** Delete all memories for a project. Returns number of deleted memories. */\n purgeProject(project: string): number {\n return this.#memoryRepo.deleteByProject(project);\n }\n\n /** Stop watching the DB file. */\n stopWatching(): void {\n unwatchFile(this.#dbPath);\n }\n\n // -- Private helpers --------------------------------------------------------\n\n #getDbSize(): number {\n try {\n return statSync(this.#dbPath).size;\n } catch {\n return 0;\n }\n }\n\n #computeByProject(): Record<string, number> {\n const counts: Record<string, number> = {};\n for (const m of this.#cachedMemories) {\n const key = m.project ?? \"(none)\";\n counts[key] = (counts[key] ?? 0) + 1;\n }\n return counts;\n }\n}\n","import React from 'react';\nimport { Box, useApp } from 'ink';\nimport type { DashboardDataSource } from './data/data-source.js';\nimport { useDashboardState } from './hooks/use-dashboard-state.js';\nimport { useKeybindings } from './hooks/use-keybindings.js';\nimport { useTerminalSize } from './hooks/use-terminal-size.js';\nimport { KeybindingBar } from './components/keybinding-bar.js';\nimport { Header } from './components/header.js';\nimport { SearchBar } from './components/search-bar.js';\nimport { MemoryList } from './components/memory-list.js';\nimport { MemoryDetail } from './components/memory-detail.js';\nimport { ProjectList } from './components/project-list.js';\nimport { StatsBar } from './components/stats-bar.js';\nimport { HelpOverlay } from './components/help-overlay.js';\nimport { ProjectPicker } from './components/project-picker.js';\nimport { DeleteConfirm } from './components/delete-confirm.js';\nimport { PurgeConfirm } from './components/purge-confirm.js';\nimport { ExpandMemory } from './components/expand-memory.js';\n\ninterface AppProps {\n readonly dataSource: DashboardDataSource;\n}\n\nexport function App({ dataSource }: AppProps): React.ReactNode {\n const { exit } = useApp();\n const { columns, rows, layout } = useTerminalSize();\n const state = useDashboardState(dataSource);\n\n useKeybindings({\n navigateUp: state.navigateUp,\n navigateDown: state.navigateDown,\n openSearch: state.openSearch,\n closeSearch: state.closeSearch,\n filterByType: state.filterByType,\n cycleLifespan: state.cycleLifespan,\n cycleProjectNext: state.cycleProjectNext,\n cycleProjectPrev: state.cycleProjectPrev,\n cycleSort: state.cycleSort,\n removeMemory: state.promptDelete,\n purgeProject: state.promptPurge,\n openProjectPicker: () => state.setShowProjectPicker((v) => !v),\n showHelp: () => state.setShowHelp((v) => !v),\n expandMemory: state.expandMemory,\n quit: exit,\n }, {\n searchActive: state.searchActive,\n pickerOpen: state.showProjectPicker,\n expandOpen: state.showExpand,\n modalOpen: state.showDeleteConfirm || state.showPurgeConfirm || state.showHelp,\n });\n\n if (state.showHelp) {\n return <HelpOverlay onClose={() => state.setShowHelp(false)} />;\n }\n\n if (state.showExpand && state.selectedMemory) {\n return (\n <ExpandMemory\n memory={state.selectedMemory}\n relations={state.relations}\n resolveTitle={(id) => dataSource.getMemoryTitle(id)}\n onClose={state.closeExpand}\n />\n );\n }\n\n if (state.showProjectPicker) {\n return (\n <ProjectPicker\n projects={[...state.projects]}\n activeProject={state.currentProject}\n onSelect={(p) => { state.setCurrentProject(p); state.setSelectedIndex(0); }}\n onClose={() => state.setShowProjectPicker(false)}\n />\n );\n }\n\n if (state.showDeleteConfirm && state.selectedMemory) {\n return (\n <DeleteConfirm\n memory={state.selectedMemory}\n onConfirm={state.confirmDelete}\n onCancel={state.cancelDelete}\n />\n );\n }\n\n if (state.showPurgeConfirm && state.currentProject) {\n return (\n <PurgeConfirm\n project={state.currentProject}\n memoryCount={dataSource.countByProject(state.currentProject)}\n onConfirm={state.confirmPurge}\n onCancel={state.cancelPurge}\n />\n );\n }\n\n const contentHeight = Math.max(4, rows - 6 - (state.searchActive ? 1 : 0));\n const isNarrow = layout === 'narrow';\n const listWidth = Math.floor(columns * 0.6);\n const rightWidth = columns - listWidth;\n // Target split: projects ≤ 1/3 of right column (capped at 12), detail takes the rest\n const projectsCount = new Set(state.filteredMemories.map((m) => m.project ?? '(none)')).size + 1;\n const projectListHeight = isNarrow\n ? 0\n : Math.min(Math.max(4, Math.floor(contentHeight / 3)), projectsCount + 3, 12);\n // Narrow layout stacks list + detail vertically — split contentHeight between them\n const listHeight = isNarrow ? Math.max(6, Math.floor(contentHeight * 0.6)) : contentHeight;\n const detailHeight = isNarrow\n ? Math.max(6, contentHeight - listHeight)\n : Math.max(6, contentHeight - projectListHeight);\n\n return (\n <Box flexDirection=\"column\">\n <KeybindingBar />\n <Header\n project={state.currentProject}\n typeFilter={state.typeFilter}\n lifespanFilter={state.lifespanFilter}\n sortMode={state.sortMode}\n searchQuery={state.searchQuery}\n layout={layout}\n />\n {state.searchActive && (\n <SearchBar\n query={state.searchQuery}\n onChange={state.setSearchQuery}\n onSubmit={state.submitSearch}\n />\n )}\n <Box flexDirection={isNarrow ? 'column' : 'row'} height={isNarrow ? undefined : contentHeight}>\n <Box width={isNarrow ? '100%' : '60%'}>\n <MemoryList\n memories={state.filteredMemories}\n selectedIndex={state.selectedIndex}\n isFocused={true}\n height={listHeight}\n />\n </Box>\n <Box flexDirection=\"column\" width={isNarrow ? '100%' : '40%'}>\n {!isNarrow && (\n <ProjectList\n memories={state.filteredMemories}\n activeProject={state.currentProject}\n isFocused={false}\n height={projectListHeight}\n />\n )}\n <MemoryDetail\n memory={state.selectedMemory}\n relations={state.relations}\n resolveTitle={(id) => dataSource.getMemoryTitle(id)}\n isFocused={false}\n height={detailHeight}\n width={rightWidth}\n />\n </Box>\n </Box>\n <StatsBar stats={state.stats} visible={state.filteredMemories} />\n </Box>\n );\n}\n","import { useState, useMemo, useEffect, useCallback } from 'react';\nimport type { DashboardDataSource } from '../data/data-source.js';\nimport type { Memory, MemoryType, Relation } from '../../types.js';\nimport type { DashboardStats } from '../data/data-source.js';\nimport { computeLifespan, type LifespanStatus } from '../data/formatters.js';\n\nexport type SortMode = 'importance' | 'age' | 'access' | 'lifespan';\n\nconst SORT_MODES: readonly SortMode[] = ['importance', 'age', 'access', 'lifespan'];\nconst LIFESPAN_FILTERS: readonly (LifespanStatus | undefined)[] = [\n undefined, 'healthy', 'fading', 'stale', 'session',\n];\n\nexport function useDashboardState(dataSource: DashboardDataSource) {\n const [revision, setRevision] = useState(0);\n const [typeFilter, setTypeFilter] = useState<MemoryType | undefined>();\n const [lifespanFilter, setLifespanFilter] = useState<LifespanStatus | undefined>();\n const [searchQuery, setSearchQuery] = useState('');\n const [searchActive, setSearchActive] = useState(false);\n const [currentProject, setCurrentProject] = useState<string | undefined>();\n const [sortMode, setSortMode] = useState<SortMode>('importance');\n const [selectedIndex, setSelectedIndex] = useState(0);\n const [showHelp, setShowHelp] = useState(false);\n const [showProjectPicker, setShowProjectPicker] = useState(false);\n const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);\n const [showPurgeConfirm, setShowPurgeConfirm] = useState(false);\n const [showExpand, setShowExpand] = useState(false);\n\n useEffect(() => {\n dataSource.refresh();\n setRevision((r) => r + 1);\n dataSource.startWatching(() => {\n dataSource.refresh();\n setRevision((r) => r + 1);\n });\n return () => dataSource.stopWatching();\n }, [dataSource]);\n\n const projects = useMemo(() => {\n void revision;\n return dataSource.getProjects();\n }, [dataSource, revision]);\n\n const filteredMemories = useMemo(() => {\n void revision;\n const raw = dataSource.getMemories({ type: typeFilter, project: currentProject });\n const withLife = lifespanFilter\n ? raw.filter((m) => computeLifespan(m).status === lifespanFilter)\n : raw;\n const withSearch = searchQuery\n ? withLife.filter((m) =>\n (m.title?.toLowerCase().includes(searchQuery.toLowerCase()) ?? false) ||\n m.content.toLowerCase().includes(searchQuery.toLowerCase()) ||\n m.tags.some((t) => t.toLowerCase().includes(searchQuery.toLowerCase()))\n )\n : withLife;\n return sortMemories(withSearch, sortMode);\n }, [dataSource, revision, typeFilter, lifespanFilter, searchQuery, currentProject, sortMode]);\n\n // Clamp: narrowing filters/search must never strand the selection past the\n // end of the list (blank detail pane until a nav key was pressed).\n const clampedIndex = Math.max(0, Math.min(selectedIndex, Math.max(0, filteredMemories.length - 1)));\n const selectedMemory = filteredMemories[clampedIndex];\n const relations = useMemo(\n () => selectedMemory ? dataSource.getRelationsForMemory(selectedMemory.id) : [],\n [dataSource, selectedMemory, revision],\n );\n const stats = useMemo(() => { void revision; return dataSource.getStats(); }, [dataSource, revision]);\n\n // Reconcile the raw index against the CURRENT list before stepping —\n // otherwise k burns presses walking a stale out-of-range index down, and\n // j on an empty list drives it negative.\n const navigateUp = useCallback(() => {\n const last = filteredMemories.length - 1;\n setSelectedIndex((i) => Math.max(0, Math.min(i, last) - 1));\n }, [filteredMemories.length]);\n const navigateDown = useCallback(() => {\n const last = filteredMemories.length - 1;\n setSelectedIndex((i) => Math.max(0, Math.min(last, Math.min(i, last) + 1)));\n }, [filteredMemories.length]);\n\n const cycleSort = useCallback(() => {\n setSortMode((m) => SORT_MODES[(SORT_MODES.indexOf(m) + 1) % SORT_MODES.length]!);\n }, []);\n const cycleLifespan = useCallback(() => {\n setLifespanFilter((f) => {\n const idx = LIFESPAN_FILTERS.findIndex((x) => x === f);\n return LIFESPAN_FILTERS[(idx + 1) % LIFESPAN_FILTERS.length];\n });\n }, []);\n const cycleProjectNext = useCallback(() => {\n setCurrentProject((curr) => {\n const idx = curr ? projects.indexOf(curr) : -1;\n return idx >= projects.length - 1 ? undefined : projects[idx + 1];\n });\n setSelectedIndex(0);\n }, [projects]);\n const cycleProjectPrev = useCallback(() => {\n setCurrentProject((curr) => {\n const idx = curr ? projects.indexOf(curr) : -1;\n return idx <= 0 ? (idx === 0 ? undefined : projects[projects.length - 1]) : projects[idx - 1];\n });\n setSelectedIndex(0);\n }, [projects]);\n const filterByType = useCallback((type: MemoryType | undefined) => {\n setTypeFilter(type);\n setSelectedIndex(0);\n }, []);\n const openSearch = useCallback(() => setSearchActive(true), []);\n // Enter: keep the filter, hand the keyboard back to the list (find-then-act).\n const submitSearch = useCallback(() => {\n setSearchActive(false);\n setSelectedIndex(0);\n }, []);\n // Esc: cancel — drop the filter entirely.\n const closeSearch = useCallback(() => {\n setSearchActive(false);\n setSearchQuery('');\n setSelectedIndex(0);\n }, []);\n const promptDelete = useCallback(() => {\n if (selectedMemory) setShowDeleteConfirm(true);\n }, [selectedMemory]);\n const confirmDelete = useCallback(() => {\n if (!selectedMemory) return;\n dataSource.deleteMemory(selectedMemory.id);\n setShowDeleteConfirm(false);\n setSelectedIndex((i) => Math.max(0, i - 1));\n dataSource.refresh();\n setRevision((r) => r + 1);\n }, [dataSource, selectedMemory]);\n const cancelDelete = useCallback(() => setShowDeleteConfirm(false), []);\n const promptPurge = useCallback(() => {\n if (currentProject) setShowPurgeConfirm(true);\n }, [currentProject]);\n const confirmPurge = useCallback(() => {\n if (!currentProject) return;\n dataSource.purgeProject(currentProject);\n setShowPurgeConfirm(false);\n setCurrentProject(undefined);\n setSelectedIndex(0);\n dataSource.refresh();\n setRevision((r) => r + 1);\n }, [dataSource, currentProject]);\n const cancelPurge = useCallback(() => setShowPurgeConfirm(false), []);\n const expandMemory = useCallback(() => {\n if (selectedMemory) setShowExpand(true);\n }, [selectedMemory]);\n const closeExpand = useCallback(() => setShowExpand(false), []);\n\n return {\n typeFilter, lifespanFilter, searchQuery, searchActive, currentProject,\n sortMode, showHelp, showProjectPicker, showDeleteConfirm, showPurgeConfirm, showExpand,\n filteredMemories, selectedMemory, relations, projects, stats,\n selectedIndex: clampedIndex,\n setSearchQuery, setCurrentProject, setSelectedIndex, setShowHelp, setShowProjectPicker,\n navigateUp, navigateDown, cycleSort, cycleLifespan,\n cycleProjectNext, cycleProjectPrev, filterByType,\n openSearch, submitSearch, closeSearch, promptDelete, confirmDelete, cancelDelete,\n promptPurge, confirmPurge, cancelPurge, expandMemory, closeExpand,\n };\n}\n\nfunction sortMemories(memories: readonly Memory[], mode: SortMode): readonly Memory[] {\n const sorted = [...memories];\n const sorters: Record<SortMode, (a: Memory, b: Memory) => number> = {\n importance: (a, b) => b.importance - a.importance,\n age: (a, b) => b.createdAt.localeCompare(a.createdAt),\n access: (a, b) => b.accessCount - a.accessCount,\n lifespan: (a, b) => computeLifespan(a).remaining - computeLifespan(b).remaining,\n };\n sorted.sort(sorters[mode]);\n return sorted;\n}\n","import type { Memory, MemoryType } from \"../../types.js\";\nimport { DEFAULT_DECAY_PARAMS } from \"../../config.js\";\n\n// -- Relative Time ------------------------------------------------------------\n\nconst MINUTE = 60_000;\nconst HOUR = 3_600_000;\nconst DAY = 86_400_000;\nconst MONTH = 30 * DAY;\nconst YEAR = 365 * DAY;\n\nexport function formatRelativeTime(isoString: string): string {\n const diff = Date.now() - new Date(isoString).getTime();\n\n if (diff < 0) return \"just now\";\n if (diff < MINUTE) return \"just now\";\n if (diff < HOUR) return `${Math.floor(diff / MINUTE)}m ago`;\n if (diff < DAY) return `${Math.floor(diff / HOUR)}h ago`;\n if (diff < MONTH) return `${Math.floor(diff / DAY)}d ago`;\n if (diff < YEAR) return `${Math.floor(diff / MONTH)}mo ago`;\n return `${Math.floor(diff / YEAR)}y ago`;\n}\n\n// -- Importance Bar -----------------------------------------------------------\n\nconst FILLED = \"\\u2588\"; // full block\nconst EMPTY = \"\\u2591\"; // light shade\n\nexport function formatImportanceBar(\n value: number,\n width: number = 8,\n): string {\n const clamped = Math.max(0, Math.min(1, value));\n const filled = Math.round(clamped * width);\n return FILLED.repeat(filled) + EMPTY.repeat(width - filled);\n}\n\n// -- Truncation ---------------------------------------------------------------\n\nexport function truncate(text: string, maxLen: number): string {\n if (text.length <= maxLen) return text;\n if (maxLen <= 1) return \"\\u2026\";\n return text.slice(0, maxLen - 1) + \"\\u2026\";\n}\n\n// -- Byte Formatting ----------------------------------------------------------\n\nconst UNITS = [\"B\", \"KB\", \"MB\", \"GB\"] as const;\n\nexport function formatBytes(bytes: number): string {\n if (bytes < 0) return \"0B\";\n let value = bytes;\n let unitIndex = 0;\n while (value >= 1024 && unitIndex < UNITS.length - 1) {\n value /= 1024;\n unitIndex++;\n }\n if (unitIndex === 0) return `${value}B`;\n return `${value.toFixed(1)}${UNITS[unitIndex]}`;\n}\n\n// -- Lifespan Helpers ---------------------------------------------------------\n\nexport type LifespanStatus = \"healthy\" | \"fading\" | \"stale\" | \"session\";\n\nexport interface LifespanInfo {\n readonly status: LifespanStatus;\n readonly tauDays: number;\n readonly ageDays: number;\n readonly remaining: number;\n}\n\nexport function tauDaysForType(type: MemoryType): number {\n return DEFAULT_DECAY_PARAMS.tauByType[type];\n}\n\nexport function computeLifespan(memory: Memory): LifespanInfo {\n const tauDays = tauDaysForType(memory.type);\n if (tauDays === 0) {\n return {\n status: \"session\",\n tauDays,\n ageDays: 0,\n remaining: 0,\n };\n }\n\n const ageDays = Math.max(\n 0,\n (Date.now() - new Date(memory.createdAt).getTime()) / DAY,\n );\n const remaining = Math.max(0, Math.min(1, 1 - ageDays / (tauDays * 2)));\n const status: LifespanStatus =\n remaining > 0.62 ? \"healthy\" : remaining > 0.32 ? \"fading\" : \"stale\";\n return { status, tauDays, ageDays, remaining };\n}\n\nexport function formatLifespanLabel(status: LifespanStatus): string {\n switch (status) {\n case \"healthy\":\n return \"HEALTHY\";\n case \"fading\":\n return \"FADING \";\n case \"stale\":\n return \"STALE \";\n case \"session\":\n return \"SESSION\";\n }\n}\n","import { useInput } from 'ink';\nimport type { MemoryType } from '../../types.js';\n\nconst TYPE_KEYS: Record<string, MemoryType> = {\n '1': 'working',\n '2': 'episodic',\n '3': 'semantic',\n '4': 'procedural',\n '5': 'pattern',\n};\n\nexport interface KeybindingActions {\n readonly navigateUp: () => void;\n readonly navigateDown: () => void;\n readonly openSearch: () => void;\n readonly closeSearch: () => void;\n readonly filterByType: (type: MemoryType | undefined) => void;\n readonly cycleLifespan: () => void;\n readonly cycleProjectNext: () => void;\n readonly cycleProjectPrev: () => void;\n readonly cycleSort: () => void;\n readonly openProjectPicker: () => void;\n readonly showHelp: () => void;\n readonly removeMemory: () => void;\n readonly purgeProject: () => void;\n readonly expandMemory: () => void;\n readonly quit: () => void;\n}\n\nexport function useKeybindings(\n actions: KeybindingActions,\n opts: { searchActive: boolean; pickerOpen: boolean; expandOpen: boolean; modalOpen: boolean },\n): void {\n useInput((input, key) => {\n // Confirm dialogs and help own the keyboard exclusively — global keys must\n // not retarget a live delete, stack confirms, or quit mid-dialog.\n if (opts.modalOpen) return;\n if (opts.expandOpen) return;\n if (opts.searchActive) {\n if (key.escape) actions.closeSearch();\n return;\n }\n if (opts.pickerOpen) {\n if (key.escape) actions.openProjectPicker(); // toggle off\n return;\n }\n\n if (input === 'j' || key.downArrow) actions.navigateDown();\n if (input === 'k' || key.upArrow) actions.navigateUp();\n if (input === '/') actions.openSearch();\n if (key.escape) actions.closeSearch();\n if (input === '0') actions.filterByType(undefined);\n if (input in TYPE_KEYS) actions.filterByType(TYPE_KEYS[input]!);\n if (input === 'l') actions.cycleLifespan();\n if (input === 's') actions.cycleSort();\n if (input === 'p') actions.openProjectPicker();\n if (input === ']' || key.rightArrow) actions.cycleProjectNext();\n if (input === '[' || key.leftArrow) actions.cycleProjectPrev();\n // d = delete the selected memory (TUI convention); X = purge the whole\n // project. The old mapping put project-nuking one key from item-delete.\n if (input === 'r' || input === 'd') actions.removeMemory();\n if (input === 'X') actions.purgeProject();\n if (input === '?') actions.showHelp();\n if (key.return) actions.expandMemory();\n if (input === 'q') actions.quit();\n });\n}\n","import { useStdout } from 'ink';\nimport { useState, useEffect } from 'react';\n\nexport interface TerminalSize {\n readonly columns: number;\n readonly rows: number;\n}\n\nexport type LayoutMode = 'wide' | 'medium' | 'narrow';\n\nexport function useTerminalSize(): TerminalSize & { layout: LayoutMode } {\n const { stdout } = useStdout();\n const [size, setSize] = useState<TerminalSize>({\n columns: stdout.columns ?? 80,\n rows: stdout.rows ?? 24,\n });\n\n useEffect(() => {\n const handler = () => setSize({ columns: stdout.columns, rows: stdout.rows });\n stdout.on('resize', handler);\n return () => { stdout.off('resize', handler); };\n }, [stdout]);\n\n const layout: LayoutMode =\n size.columns >= 120 ? 'wide' :\n size.columns >= 80 ? 'medium' : 'narrow';\n\n return { ...size, layout };\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\n\nconst HINTS = [\n ['j/k', 'navigate'],\n ['Enter', 'expand'],\n ['/', 'search'],\n ['p', 'projects'],\n ['1-5', 'type'],\n ['l', 'life'],\n ['s', 'sort'],\n ['d', 'delete'],\n ['X', 'purge project'],\n ['?', 'help'],\n ['q', 'quit'],\n] as const;\n\nexport function KeybindingBar(): React.ReactNode {\n return (\n <Box>\n {HINTS.map(([key, label], i) => (\n <React.Fragment key={key}>\n {i > 0 && <Text dimColor> </Text>}\n <Text color=\"cyan\">{key}</Text>\n <Text dimColor> {label}</Text>\n </React.Fragment>\n ))}\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport type { MemoryType } from '../../types.js';\nimport type { LifespanStatus } from '../data/formatters.js';\nimport type { SortMode } from '../hooks/use-dashboard-state.js';\nimport type { LayoutMode } from '../hooks/use-terminal-size.js';\n\ninterface HeaderProps {\n readonly project?: string;\n readonly typeFilter?: MemoryType;\n readonly lifespanFilter?: LifespanStatus;\n readonly sortMode: SortMode;\n readonly searchQuery: string;\n readonly layout: LayoutMode;\n}\n\nexport function Header({ project, typeFilter, lifespanFilter, sortMode, searchQuery, layout }: HeaderProps): React.ReactNode {\n const sep = <Text dimColor> | </Text>;\n\n return (\n <Box overflow=\"hidden\">\n <Text bold color=\"green\"> agentic-memory </Text>\n {sep}\n <Text color=\"white\">{project ?? 'all projects'}</Text>\n {layout !== 'narrow' && (\n <>\n {sep}\n <Text dimColor>{typeFilter ?? 'all types'}</Text>\n {sep}\n <Text dimColor>{lifespanFilter ?? 'all life'}</Text>\n </>\n )}\n {layout === 'wide' && (\n <>\n {sep}\n <Text dimColor>sort:{sortMode}</Text>\n </>\n )}\n {searchQuery && (\n <>\n {sep}\n <Text color=\"yellow\">/{searchQuery}</Text>\n </>\n )}\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport TextInput from 'ink-text-input';\n\ninterface SearchBarProps {\n readonly query: string;\n readonly onChange: (value: string) => void;\n readonly onSubmit: () => void;\n}\n\nexport function SearchBar({ query, onChange, onSubmit }: SearchBarProps): React.ReactNode {\n return (\n <Box>\n <Text color=\"yellow\">Search: </Text>\n <TextInput value={query} onChange={onChange} onSubmit={onSubmit} />\n <Text dimColor> (Enter apply · Esc cancel)</Text>\n </Box>\n );\n}\n","import React, { useMemo } from 'react';\nimport { Box, Text } from 'ink';\nimport type { Memory } from '../../types.js';\nimport { truncate, formatRelativeTime, computeLifespan, formatLifespanLabel } from '../data/formatters.js';\nimport { TYPE_ABBREV } from '../colors.js';\n\ninterface MemoryListProps {\n readonly memories: readonly Memory[];\n readonly selectedIndex: number;\n readonly isFocused: boolean;\n readonly height: number;\n}\n\ntype LifeColor = 'green' | 'yellow' | 'red' | 'magenta';\n\nconst LIFE_COLORS: Record<string, LifeColor> = {\n healthy: 'green',\n fading: 'yellow',\n stale: 'red',\n session: 'magenta',\n};\n\nexport function MemoryList({ memories, selectedIndex, isFocused, height }: MemoryListProps): React.ReactNode {\n // Reserve 2 rows for top+bottom borders and 1 for the title — visible rows are what's left.\n const viewportHeight = Math.max(1, height - 3);\n\n const scrollOffset = useMemo(() => {\n if (selectedIndex < 0) return 0;\n if (memories.length <= viewportHeight) return 0;\n const half = Math.floor(viewportHeight / 2);\n const offset = Math.max(0, selectedIndex - half);\n return Math.min(offset, memories.length - viewportHeight);\n }, [selectedIndex, memories.length, viewportHeight]);\n\n const visible = memories.slice(scrollOffset, scrollOffset + viewportHeight);\n const label = ` Memories [${memories.length}] `;\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={isFocused ? 'cyan' : 'gray'}\n height={height}\n >\n <Text bold color={isFocused ? 'cyan' : 'gray'}>{label}</Text>\n {visible.length === 0 && <Text dimColor> No memories found</Text>}\n {visible.map((m, i) => {\n const isSelected = scrollOffset + i === selectedIndex;\n return <MemoryRow key={m.id} memory={m} isSelected={isSelected} />;\n })}\n </Box>\n );\n}\n\nfunction MemoryRow({ memory, isSelected }: { memory: Memory; isSelected: boolean }): React.ReactNode {\n const life = computeLifespan(memory);\n const title = truncate(memory.title ?? memory.content.replace(/\\n/g, ' '), 36);\n const project = truncate(memory.project ?? '', 14);\n const type = TYPE_ABBREV[memory.type] ?? memory.type;\n const lifeColor = LIFE_COLORS[life.status] ?? 'white';\n const lifeLabel = formatLifespanLabel(life.status).trim();\n const imp = `${Math.round(memory.importance * 100)}%`;\n const updated = formatRelativeTime(memory.updatedAt);\n\n return (\n <Box>\n <Text inverse={isSelected}>\n <Text bold>{isSelected ? '▸ ' : ' '}</Text>\n <Text bold>{title.padEnd(38)}</Text>\n <Text dimColor>{project.padEnd(16)}</Text>\n <Text color=\"cyan\">{type} </Text>\n <Text color={lifeColor}>{lifeLabel.padEnd(8)}</Text>\n <Text>{imp.padStart(4)} </Text>\n <Text dimColor>{updated.padEnd(8)}</Text>\n <Text color=\"blue\">acc:{memory.accessCount}</Text>\n </Text>\n </Box>\n );\n}\n","import type { MemoryType, RelationType } from \"../types.js\";\n\n// -- Type Colors (blessed-compatible color names) -----------------------------\n\nexport const TYPE_COLORS: Record<MemoryType, string> = {\n working: \"red\",\n episodic: \"yellow\",\n semantic: \"cyan\",\n procedural: \"green\",\n pattern: \"magenta\",\n};\n\n// -- Type Abbreviations (4-char max) ------------------------------------------\n\nexport const TYPE_ABBREV: Record<MemoryType, string> = {\n working: \"WORK\",\n episodic: \"EPIS\",\n semantic: \"SEMA\",\n procedural: \"PROC\",\n pattern: \"PTRN\",\n};\n\n// -- Relation Colors ----------------------------------------------------------\n\nexport const RELATION_COLORS: Record<RelationType, string> = {\n relates_to: \"white\",\n depends_on: \"blue\",\n contradicts: \"red\",\n extends: \"green\",\n implements: \"cyan\",\n derived_from: \"yellow\",\n};\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport type { Memory, Relation } from '../../types.js';\nimport {\n formatImportanceBar,\n formatRelativeTime,\n computeLifespan,\n formatLifespanLabel,\n} from '../data/formatters.js';\nimport { TYPE_COLORS, RELATION_COLORS } from '../colors.js';\nimport { wrapContent } from '../data/wrap.js';\n\nconst METADATA_ROWS = 18;\nconst BORDER_ROWS = 2;\nconst MIN_CONTENT_ROWS = 2;\n\ninterface MemoryDetailProps {\n readonly memory?: Memory;\n readonly relations: readonly Relation[];\n readonly isFocused: boolean;\n readonly height: number;\n readonly width: number;\n readonly resolveTitle?: (id: string) => string | undefined;\n}\n\nexport function MemoryDetail({ memory, relations, isFocused, height, width, resolveTitle }: MemoryDetailProps): React.ReactNode {\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={isFocused ? 'blue' : 'gray'}\n paddingX={1}\n height={height}\n >\n <Text bold color={isFocused ? 'blue' : 'gray'}> Detail </Text>\n {!memory ? (\n <Text dimColor>Select a memory to view details</Text>\n ) : (\n <DetailContent resolveTitle={resolveTitle} memory={memory} relations={relations} height={height} width={width} />\n )}\n </Box>\n );\n}\n\ninterface DetailContentProps {\n readonly memory: Memory;\n readonly relations: readonly Relation[];\n readonly height: number;\n readonly width: number;\n readonly resolveTitle?: (id: string) => string | undefined;\n}\n\nfunction DetailContent({ memory, relations, height, width, resolveTitle }: DetailContentProps): React.ReactNode {\n const life = computeLifespan(memory);\n const typeColor = TYPE_COLORS[memory.type] ?? 'white';\n const relationRows = relations.length > 0 ? relations.length + 2 : 0;\n const contentRows = Math.max(MIN_CONTENT_ROWS, height - METADATA_ROWS - BORDER_ROWS - relationRows);\n const contentWidth = Math.max(10, width - 4);\n const preview = truncateContent(memory.content, contentRows, contentWidth);\n\n return (\n <Box flexDirection=\"column\">\n <Text bold>{memory.title ?? '(untitled)'}</Text>\n <Text> </Text>\n <Text>Type: <Text color={typeColor}>{memory.type}</Text></Text>\n <Text>Lifespan: {formatLifespanLabel(life.status)} | age {Math.round(life.ageDays)}d | tau {life.tauDays}d</Text>\n <Text>Health: {formatImportanceBar(life.remaining)} {(life.remaining * 100).toFixed(0)}%</Text>\n <Text>Importance: {formatImportanceBar(memory.importance)} {memory.importance.toFixed(2)}</Text>\n <Text>Project: {memory.project ?? '(none)'}</Text>\n <Text>Tags: {memory.tags.length > 0 ? memory.tags.map((t) => `[${t}]`).join(' ') : '(none)'}</Text>\n <Text>Source: {memory.source ?? 'unknown'}</Text>\n <Text> </Text>\n <Text>Created: {formatRelativeTime(memory.createdAt)}</Text>\n <Text>Updated: {formatRelativeTime(memory.updatedAt)}</Text>\n <Text>Accessed: {memory.accessCount}x{memory.lastAccessed ? ` (last: ${formatRelativeTime(memory.lastAccessed)})` : ''}</Text>\n <Text>Injected: {memory.injectionCount}x</Text>\n <Text> </Text>\n <Text bold>Content</Text>\n <Text dimColor>{'─'.repeat(Math.min(contentWidth, 40))}</Text>\n {preview.lines.map((line, i) => (\n <Text key={`line-${i}`}>{line === '' ? ' ' : line}</Text>\n ))}\n {preview.truncated && (\n <Text dimColor>… +{preview.remainingLines} line{preview.remainingLines === 1 ? '' : 's'} · press Enter to view full</Text>\n )}\n {relations.length > 0 && <RelationsList resolveTitle={resolveTitle} relations={relations} memoryId={memory.id} />}\n </Box>\n );\n}\n\ninterface ContentPreview {\n readonly lines: readonly string[];\n readonly truncated: boolean;\n readonly remainingLines: number;\n}\n\nfunction truncateContent(content: string, maxRows: number, wrapWidth: number): ContentPreview {\n const allLines = wrapContent(content, wrapWidth);\n if (allLines.length <= maxRows) {\n return { lines: allLines, truncated: false, remainingLines: 0 };\n }\n // Reserve one row for the \"... press Enter\" hint\n const visible = Math.max(1, maxRows - 1);\n return {\n lines: allLines.slice(0, visible),\n truncated: true,\n remainingLines: allLines.length - visible,\n };\n}\n\nfunction RelationsList({ relations, memoryId, resolveTitle }: { relations: readonly Relation[]; memoryId: string; resolveTitle?: (id: string) => string | undefined }): React.ReactNode {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text bold>Relations</Text>\n <Text dimColor>{'─'.repeat(40)}</Text>\n {relations.map((r, i) => {\n const relColor = RELATION_COLORS[r.relationType] ?? 'white';\n const direction = r.sourceId === memoryId ? '→' : '←';\n const otherId = r.sourceId === memoryId ? r.targetId : r.sourceId;\n const label = resolveTitle?.(otherId) ?? otherId.slice(0, 8);\n return (\n <Text key={i}> {direction} <Text color={relColor}>{r.relationType}</Text> {label}</Text>\n );\n })}\n </Box>\n );\n}\n","/**\n * Split content into display lines, wrapping long lines at the given width.\n * Preserves empty lines.\n */\nexport function wrapContent(content: string, width: number): readonly string[] {\n if (width <= 0) return content.split('\\n');\n const out: string[] = [];\n for (const rawLine of content.split('\\n')) {\n if (rawLine.length === 0) {\n out.push('');\n continue;\n }\n for (let i = 0; i < rawLine.length; i += width) {\n out.push(rawLine.slice(i, i + width));\n }\n }\n return out;\n}\n","import React, { useMemo } from 'react';\nimport { Box, Text } from 'ink';\nimport type { Memory } from '../../types.js';\nimport { computeLifespan } from '../data/formatters.js';\n\ninterface ProjectListProps {\n readonly memories: readonly Memory[];\n readonly activeProject?: string;\n readonly isFocused: boolean;\n readonly height: number;\n}\n\ninterface ProjectRow {\n readonly project: string | undefined;\n readonly total: number;\n readonly healthPct: number;\n}\n\nexport function ProjectList({ memories, activeProject, isFocused, height }: ProjectListProps): React.ReactNode {\n const rows = useMemo(() => buildProjectRows(memories), [memories]);\n // Reserve rows for title + borders; leave one for \"+N more\" if truncated\n const visibleRows = Math.max(1, height - 3);\n const truncated = rows.length > visibleRows;\n const displayed = truncated ? rows.slice(0, visibleRows - 1) : rows;\n const hidden = rows.length - displayed.length;\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={isFocused ? 'magenta' : 'gray'}\n height={height}\n >\n <Text bold color={isFocused ? 'magenta' : 'gray'}> Projects </Text>\n {displayed.map((row) => {\n const isActive = row.project === activeProject || (row.project === undefined && !activeProject);\n const name = (row.project ?? 'All projects').padEnd(20).slice(0, 20);\n const healthColor = row.healthPct > 62 ? 'green' : row.healthPct > 32 ? 'yellow' : 'red';\n return (\n <Box key={row.project ?? '_all'}>\n <Text bold={isActive}>{isActive ? '> ' : ' '}</Text>\n <Text bold={isActive}>{name}</Text>\n <Text color=\"cyan\">{String(row.total).padStart(4)} mem</Text>\n <Text> </Text>\n <Text color={healthColor}>{String(row.healthPct).padStart(3)}%</Text>\n </Box>\n );\n })}\n {truncated && <Text dimColor> … +{hidden} more</Text>}\n </Box>\n );\n}\n\nfunction buildProjectRows(memories: readonly Memory[]): readonly ProjectRow[] {\n const byProject = new Map<string, Memory[]>();\n for (const m of memories) {\n const key = m.project ?? '(none)';\n const list = byProject.get(key) ?? [];\n list.push(m);\n byProject.set(key, list);\n }\n\n const rows: ProjectRow[] = [];\n for (const [project, mems] of byProject) {\n const avg = mems.reduce((s, m) => s + computeLifespan(m).remaining, 0) / mems.length;\n rows.push({ project, total: mems.length, healthPct: Math.round(avg * 100) });\n }\n rows.sort((a, b) => b.total - a.total);\n\n const allHealth = memories.length > 0\n ? Math.round((memories.reduce((s, m) => s + computeLifespan(m).remaining, 0) / memories.length) * 100)\n : 0;\n return [{ project: undefined, total: memories.length, healthPct: allHealth }, ...rows];\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport type { DashboardStats } from '../data/data-source.js';\nimport type { Memory } from '../../types.js';\nimport { formatBytes, computeLifespan } from '../data/formatters.js';\nimport { TYPE_COLORS } from '../colors.js';\n\ninterface StatsBarProps {\n readonly stats: DashboardStats;\n readonly visible: readonly Memory[];\n}\n\nexport function StatsBar({ stats, visible }: StatsBarProps): React.ReactNode {\n const lifeCounts = { healthy: 0, fading: 0, stale: 0, session: 0 };\n for (const m of visible) {\n lifeCounts[computeLifespan(m).status]++;\n }\n\n const typeEntries = Object.entries(stats.byType).filter(([, c]) => c > 0);\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"single\" borderColor=\"gray\" paddingX={1}>\n <Box gap={2}>\n <Text><Text bold>Total:</Text> {stats.total}</Text>\n <Text><Text bold>Relations:</Text> {stats.relations}</Text>\n <Text><Text bold>Visible:</Text> {visible.length}</Text>\n <Text><Text bold>DB:</Text> {formatBytes(stats.dbSizeBytes)}</Text>\n </Box>\n <Box gap={2}>\n <Text>\n <Text color=\"green\">H:{lifeCounts.healthy}</Text>\n {' '}<Text color=\"yellow\">F:{lifeCounts.fading}</Text>\n {' '}<Text color=\"red\">S:{lifeCounts.stale}</Text>\n {' '}<Text color=\"magenta\">Sess:{lifeCounts.session}</Text>\n </Text>\n {typeEntries.map(([type, count]) => (\n <Text key={type} color={TYPE_COLORS[type as keyof typeof TYPE_COLORS] ?? 'white'}>\n {type}:{count}\n </Text>\n ))}\n </Box>\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text, useInput } from 'ink';\n\ninterface HelpOverlayProps {\n readonly onClose: () => void;\n}\n\nconst BINDINGS = [\n ['j / k / ↑↓', 'Navigate list'],\n ['Enter', 'Expand memory (full content + scroll)'],\n ['/', 'Search (live filter)'],\n ['Esc', 'Clear search'],\n ['1-5', 'Filter by type (0 = all)'],\n ['l', 'Cycle lifespan filter'],\n ['s', 'Cycle sort mode'],\n ['p', 'Open project picker'],\n ['[ / ]', 'Previous / next project'],\n ['d / r', 'Delete selected memory'],\n ['X', 'Purge all memories for current project'],\n ['?', 'Show this help'],\n ['q', 'Quit'],\n] as const;\n\nexport function HelpOverlay({ onClose }: HelpOverlayProps): React.ReactNode {\n useInput(() => onClose());\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"double\"\n borderColor=\"yellow\"\n paddingX={2}\n paddingY={1}\n >\n <Text bold color=\"yellow\">Keybindings</Text>\n <Text> </Text>\n {BINDINGS.map(([key, desc]) => (\n <Box key={key} gap={1}>\n <Text color=\"cyan\">{key.padEnd(14)}</Text>\n <Text>{desc}</Text>\n </Box>\n ))}\n <Text> </Text>\n <Text dimColor>Press any key to close</Text>\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text, useInput } from 'ink';\n\ninterface ProjectPickerProps {\n readonly projects: readonly string[];\n readonly activeProject?: string;\n readonly onSelect: (project: string | undefined) => void;\n readonly onClose: () => void;\n}\n\nexport function ProjectPicker({ projects, activeProject, onSelect, onClose }: ProjectPickerProps): React.ReactNode {\n const [selectedIdx, setSelectedIdx] = React.useState(() => {\n if (!activeProject) return 0;\n const idx = projects.indexOf(activeProject);\n return idx >= 0 ? idx + 1 : 0;\n });\n\n const options = [\n { label: 'All projects', project: undefined as string | undefined },\n ...projects.map((p) => ({ label: p, project: p as string | undefined })),\n ];\n\n useInput((input, key) => {\n if (key.escape) { onClose(); return; }\n if (input === 'j' || key.downArrow) setSelectedIdx((i) => Math.min(options.length - 1, i + 1));\n if (input === 'k' || key.upArrow) setSelectedIdx((i) => Math.max(0, i - 1));\n if (key.return) {\n onSelect(options[selectedIdx]?.project);\n onClose();\n }\n });\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"double\" borderColor=\"yellow\" paddingX={2} paddingY={1}>\n <Text bold color=\"yellow\">Project Picker</Text>\n <Text dimColor>Enter=select Esc=close</Text>\n <Text> </Text>\n {options.map((opt, i) => {\n const isSelected = i === selectedIdx;\n const isActive = opt.project === activeProject || (opt.project === undefined && !activeProject);\n return (\n <Text key={opt.label} inverse={isSelected}>\n {isActive ? '> ' : ' '}{opt.label}\n </Text>\n );\n })}\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport type { Memory } from '../../types.js';\n\ninterface DeleteConfirmProps {\n readonly memory: Memory;\n readonly onConfirm: () => void;\n readonly onCancel: () => void;\n}\n\nexport function DeleteConfirm({ memory, onConfirm, onCancel }: DeleteConfirmProps): React.ReactNode {\n useInput((input, key) => {\n if (input === 'y' || input === 'Y') onConfirm();\n if (input === 'n' || input === 'N' || key.escape) onCancel();\n });\n\n const title = memory.title ?? memory.content.slice(0, 40);\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"double\" borderColor=\"red\" paddingX={2} paddingY={1}>\n <Text bold color=\"red\">Delete memory?</Text>\n <Text> </Text>\n <Text bold>{title}</Text>\n <Text dimColor>[{memory.type}] {memory.project ?? '(no project)'}</Text>\n <Text> </Text>\n <Text>This is a permanent hard delete. The memory cannot be recovered.</Text>\n <Text> </Text>\n <Text><Text color=\"green\" bold>y</Text> confirm <Text color=\"red\" bold>n/Esc</Text> cancel</Text>\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text, useInput } from 'ink';\n\ninterface PurgeConfirmProps {\n readonly project: string;\n readonly memoryCount: number;\n readonly onConfirm: () => void;\n readonly onCancel: () => void;\n}\n\nexport function PurgeConfirm({ project, memoryCount, onConfirm, onCancel }: PurgeConfirmProps): React.ReactNode {\n useInput((input, key) => {\n if (input === 'y' || input === 'Y') onConfirm();\n if (input === 'n' || input === 'N' || key.escape) onCancel();\n });\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"double\" borderColor=\"red\" paddingX={2} paddingY={1}>\n <Text bold color=\"red\">Delete all memories for project?</Text>\n <Text> </Text>\n <Text bold>{project}</Text>\n <Text dimColor>{memoryCount} memories will be permanently deleted.</Text>\n <Text> </Text>\n <Text>This cannot be undone.</Text>\n <Text> </Text>\n <Text><Text color=\"green\" bold>y</Text> confirm <Text color=\"red\" bold>n/Esc</Text> cancel</Text>\n </Box>\n );\n}\n","import React, { useState, useEffect } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport type { Memory, Relation } from '../../types.js';\nimport { useTerminalSize } from '../hooks/use-terminal-size.js';\nimport { TYPE_COLORS, RELATION_COLORS } from '../colors.js';\nimport { formatRelativeTime } from '../data/formatters.js';\nimport { wrapContent } from '../data/wrap.js';\n\ninterface ExpandMemoryProps {\n readonly memory: Memory;\n readonly relations: readonly Relation[];\n readonly onClose: () => void;\n readonly resolveTitle?: (id: string) => string | undefined;\n}\n\nexport function ExpandMemory({ memory, relations, onClose, resolveTitle }: ExpandMemoryProps): React.ReactNode {\n const { columns, rows } = useTerminalSize();\n const [scroll, setScroll] = useState(0);\n\n const contentWidth = Math.max(20, columns - 6);\n const chromeLines = 7 + (relations.length > 0 ? relations.length + 2 : 0);\n const viewportLines = Math.max(5, rows - chromeLines);\n\n const wrappedLines = wrapContent(memory.content, contentWidth);\n const totalLines = wrappedLines.length;\n const maxScroll = Math.max(0, totalLines - viewportLines);\n\n useEffect(() => { setScroll(0); }, [memory.id]);\n\n useInput((input, key) => {\n if (key.escape || input === 'q') { onClose(); return; }\n if (input === 'j' || key.downArrow) setScroll((s) => Math.min(maxScroll, s + 1));\n if (input === 'k' || key.upArrow) setScroll((s) => Math.max(0, s - 1));\n if (key.pageDown || input === ' ') setScroll((s) => Math.min(maxScroll, s + viewportLines));\n if (key.pageUp) setScroll((s) => Math.max(0, s - viewportLines));\n if (input === 'g') setScroll(0);\n if (input === 'G') setScroll(maxScroll);\n });\n\n const typeColor = TYPE_COLORS[memory.type] ?? 'white';\n const visible = wrappedLines.slice(scroll, scroll + viewportLines);\n const scrollInfo = totalLines > viewportLines\n ? ` [${scroll + 1}-${Math.min(totalLines, scroll + viewportLines)}/${totalLines}]`\n : ` [${totalLines} lines]`;\n const divider = '─'.repeat(Math.min(contentWidth, 80));\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"double\" borderColor=\"blue\" paddingX={1}>\n <Text bold>\n <Text color={typeColor}>[{memory.type}]</Text>{' '}\n {memory.title ?? '(untitled)'}\n </Text>\n <Text dimColor>\n id: {memory.id.slice(0, 8)} | project: {memory.project ?? '(none)'} | imp: {memory.importance.toFixed(2)} | updated: {formatRelativeTime(memory.updatedAt)}\n </Text>\n <Text dimColor>{divider}</Text>\n {visible.map((line, i) => (\n <Text key={`line-${scroll + i}`}>{line === '' ? ' ' : line}</Text>\n ))}\n {Array.from({ length: Math.max(0, viewportLines - visible.length) }).map((_, i) => (\n <Text key={`pad-${i}`}> </Text>\n ))}\n <Text dimColor>{divider}</Text>\n {relations.length > 0 && (\n <Box flexDirection=\"column\">\n <Text bold>Relations</Text>\n {relations.map((r, i) => {\n const relColor = RELATION_COLORS[r.relationType] ?? 'white';\n const direction = r.sourceId === memory.id ? '→' : '←';\n const otherId = r.sourceId === memory.id ? r.targetId : r.sourceId;\n const label = resolveTitle?.(otherId) ?? otherId.slice(0, 8);\n return <Text key={i}> {direction} <Text color={relColor}>{r.relationType}</Text> {label}</Text>;\n })}\n </Box>\n )}\n <Text dimColor>\n {totalLines > viewportLines ? 'j/k scroll · space/PgDn page · g/G top/bottom · ' : ''}q/Esc close{scrollInfo}\n </Text>\n </Box>\n );\n}\n\n","import React from \"react\";\nimport { Box, Text, useApp, useInput } from \"ink\";\n\nfunction CrashScreen({\n message,\n}: {\n readonly message: string;\n}): React.ReactNode {\n const { exit } = useApp();\n useInput((input) => {\n if (input === \"q\") exit();\n });\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor=\"red\"\n padding={1}\n >\n <Text bold color=\"red\">\n Dashboard crashed\n </Text>\n <Text>{message}</Text>\n <Text dimColor>Your data is untouched. Press q to quit.</Text>\n </Box>\n );\n}\n\ninterface Props {\n readonly children: React.ReactNode;\n}\ninterface State {\n readonly error: Error | null;\n}\n\n/**\n * One bad render must not unmount Ink mid-raw-mode and strand the terminal.\n * Ink restores the terminal on clean exit; this keeps the exit clean.\n */\nexport class DashboardErrorBoundary extends React.Component<Props, State> {\n override state: State = { error: null };\n\n static getDerivedStateFromError(error: Error): State {\n return { error };\n }\n\n override render(): React.ReactNode {\n if (this.state.error) {\n return <CrashScreen message={this.state.error.message} />;\n }\n return this.props.children;\n }\n}\n"],"mappings":"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","names":["Box","useState","useEffect","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","useMemo","Box","Text","jsx","jsxs","useMemo","Box","Text","Box","Text","jsx","jsxs","Box","Text","useMemo","Box","Text","jsx","jsxs","useMemo","Box","Text","Box","Text","jsx","jsxs","Box","Text","Box","Text","useInput","jsx","jsxs","React","Box","Text","useInput","jsx","jsxs","Box","Text","useInput","jsx","jsxs","Box","Text","useInput","jsx","jsxs","useState","useEffect","Box","Text","useInput","jsx","jsxs","useState","useEffect","useInput","Box","Text","jsx","jsxs","Box","React","Box","Text","useApp","useInput","jsx","jsxs","jsx"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-launchpad",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"description": "Score your Claude Code config, fix the gaps with hooks and permissions, prove Claude follows your rules with eval. Includes persistent memory for Claude Code with free cross-machine sync (GitHub Gist), ranked context injection, and benchmarks that measure whether memory actually helps.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
"@types/react": "^19.2.14",
|
|
94
94
|
"@types/shell-quote": "^1.7.5",
|
|
95
95
|
"better-sqlite3": "^11.10.0",
|
|
96
|
+
"ink-testing-library": "^4.0.0",
|
|
96
97
|
"sqlite-vec": "0.1.9",
|
|
97
98
|
"tsup": "^8.5.1",
|
|
98
99
|
"tsx": "^4.21.0",
|