@colbymchenry/cmem 0.2.23 → 0.2.29
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.
Potentially problematic release.
This version of @colbymchenry/cmem might be problematic. Click here for more details.
- package/dist/cli.js +530 -70
- package/dist/cli.js.map +1 -1
- package/package.json +12 -5
package/dist/cli.js
CHANGED
|
@@ -202,7 +202,7 @@ import { spawn as spawn2 } from "child_process";
|
|
|
202
202
|
|
|
203
203
|
// src/ui/App.tsx
|
|
204
204
|
import { useState as useState2, useEffect as useEffect2, useCallback as useCallback2 } from "react";
|
|
205
|
-
import { Box as
|
|
205
|
+
import { Box as Box6, Text as Text6, useInput, useApp } from "ink";
|
|
206
206
|
import TextInput2 from "ink-text-input";
|
|
207
207
|
import Spinner from "ink-spinner";
|
|
208
208
|
import { basename as basename4, dirname as dirname2 } from "path";
|
|
@@ -361,21 +361,23 @@ var SessionList = ({
|
|
|
361
361
|
};
|
|
362
362
|
var SessionItem = ({ session, isSelected }) => {
|
|
363
363
|
const hasCustomTitle = !!session.customTitle;
|
|
364
|
-
const displayTitle = truncate(session.customTitle || session.title,
|
|
365
|
-
const folderName = session.projectPath ? truncate(basename2(session.projectPath),
|
|
364
|
+
const displayTitle = truncate(session.customTitle || session.title, 38);
|
|
365
|
+
const folderName = session.projectPath ? truncate(basename2(session.projectPath), 38) : "";
|
|
366
366
|
const msgs = String(session.messageCount).padStart(3);
|
|
367
367
|
const updated = formatTimeAgo(session.updatedAt);
|
|
368
368
|
const getTitleColor = () => {
|
|
369
369
|
if (isSelected) return "cyan";
|
|
370
|
+
if (session.isFavorite) return "yellow";
|
|
370
371
|
if (hasCustomTitle) return "magenta";
|
|
371
372
|
return void 0;
|
|
372
373
|
};
|
|
373
374
|
return /* @__PURE__ */ jsxs3(Box3, { children: [
|
|
374
375
|
/* @__PURE__ */ jsx3(Text3, { color: isSelected ? "cyan" : void 0, children: isSelected ? "\u25B8 " : " " }),
|
|
375
|
-
/* @__PURE__ */ jsx3(Text3, {
|
|
376
|
+
/* @__PURE__ */ jsx3(Text3, { color: "yellow", children: session.isFavorite ? "\u2B50" : " " }),
|
|
377
|
+
/* @__PURE__ */ jsx3(Text3, { bold: isSelected, color: getTitleColor(), wrap: "truncate", children: displayTitle.padEnd(38) }),
|
|
376
378
|
/* @__PURE__ */ jsxs3(Text3, { color: "blue", children: [
|
|
377
379
|
" ",
|
|
378
|
-
folderName.padEnd(
|
|
380
|
+
folderName.padEnd(38)
|
|
379
381
|
] }),
|
|
380
382
|
/* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
381
383
|
" ",
|
|
@@ -386,16 +388,108 @@ var SessionItem = ({ session, isSelected }) => {
|
|
|
386
388
|
] });
|
|
387
389
|
};
|
|
388
390
|
|
|
389
|
-
// src/ui/components/
|
|
391
|
+
// src/ui/components/ProjectList.tsx
|
|
390
392
|
import { Box as Box4, Text as Text4 } from "ink";
|
|
391
393
|
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
394
|
+
var ProjectList = ({
|
|
395
|
+
projects,
|
|
396
|
+
selectedIndex
|
|
397
|
+
}) => {
|
|
398
|
+
if (projects.length === 0) {
|
|
399
|
+
return /* @__PURE__ */ jsxs4(
|
|
400
|
+
Box4,
|
|
401
|
+
{
|
|
402
|
+
flexDirection: "column",
|
|
403
|
+
borderStyle: "round",
|
|
404
|
+
borderColor: "gray",
|
|
405
|
+
paddingX: 1,
|
|
406
|
+
paddingY: 0,
|
|
407
|
+
children: [
|
|
408
|
+
/* @__PURE__ */ jsx4(Text4, { bold: true, children: "Projects" }),
|
|
409
|
+
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "No projects found" }),
|
|
410
|
+
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "Start using Claude Code in a project directory" })
|
|
411
|
+
]
|
|
412
|
+
}
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
const visibleCount = 8;
|
|
416
|
+
let startIndex = Math.max(0, selectedIndex - Math.floor(visibleCount / 2));
|
|
417
|
+
const endIndex = Math.min(projects.length, startIndex + visibleCount);
|
|
418
|
+
if (endIndex - startIndex < visibleCount) {
|
|
419
|
+
startIndex = Math.max(0, endIndex - visibleCount);
|
|
420
|
+
}
|
|
421
|
+
const visibleProjects = projects.slice(startIndex, endIndex);
|
|
422
|
+
return /* @__PURE__ */ jsxs4(
|
|
423
|
+
Box4,
|
|
424
|
+
{
|
|
425
|
+
flexDirection: "column",
|
|
426
|
+
borderStyle: "round",
|
|
427
|
+
borderColor: "gray",
|
|
428
|
+
paddingX: 1,
|
|
429
|
+
paddingY: 0,
|
|
430
|
+
children: [
|
|
431
|
+
/* @__PURE__ */ jsxs4(Text4, { bold: true, children: [
|
|
432
|
+
"Projects (",
|
|
433
|
+
projects.length,
|
|
434
|
+
")"
|
|
435
|
+
] }),
|
|
436
|
+
visibleProjects.map((project, i) => {
|
|
437
|
+
const actualIndex = startIndex + i;
|
|
438
|
+
const isSelected = actualIndex === selectedIndex;
|
|
439
|
+
return /* @__PURE__ */ jsx4(
|
|
440
|
+
ProjectItem,
|
|
441
|
+
{
|
|
442
|
+
project,
|
|
443
|
+
isSelected
|
|
444
|
+
},
|
|
445
|
+
project.path
|
|
446
|
+
);
|
|
447
|
+
}),
|
|
448
|
+
projects.length > visibleCount && /* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
|
|
449
|
+
startIndex > 0 ? "\u2191 more above" : "",
|
|
450
|
+
startIndex > 0 && endIndex < projects.length ? " | " : "",
|
|
451
|
+
endIndex < projects.length ? "\u2193 more below" : ""
|
|
452
|
+
] })
|
|
453
|
+
]
|
|
454
|
+
}
|
|
455
|
+
);
|
|
456
|
+
};
|
|
457
|
+
var ProjectItem = ({ project, isSelected }) => {
|
|
458
|
+
const displayName = truncate(project.name, 40);
|
|
459
|
+
const sessions = `${project.sessionCount} session${project.sessionCount !== 1 ? "s" : ""}`;
|
|
460
|
+
const messages = `${project.totalMessages} msgs`;
|
|
461
|
+
const updated = formatTimeAgo(project.lastUpdated);
|
|
462
|
+
const orderBadge = project.sortOrder !== null ? `${project.sortOrder + 1}.` : " ";
|
|
463
|
+
return /* @__PURE__ */ jsxs4(Box4, { children: [
|
|
464
|
+
/* @__PURE__ */ jsx4(Text4, { color: isSelected ? "cyan" : void 0, children: isSelected ? "\u25B8 " : " " }),
|
|
465
|
+
/* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
|
|
466
|
+
orderBadge.padStart(3),
|
|
467
|
+
" "
|
|
468
|
+
] }),
|
|
469
|
+
/* @__PURE__ */ jsx4(Text4, { color: "blue", children: "\u{1F4C1} " }),
|
|
470
|
+
/* @__PURE__ */ jsx4(Text4, { bold: isSelected, color: isSelected ? "cyan" : void 0, wrap: "truncate", children: displayName.padEnd(35) }),
|
|
471
|
+
/* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
|
|
472
|
+
" ",
|
|
473
|
+
sessions.padEnd(12)
|
|
474
|
+
] }),
|
|
475
|
+
/* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
|
|
476
|
+
" ",
|
|
477
|
+
messages.padEnd(10)
|
|
478
|
+
] }),
|
|
479
|
+
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: updated.padStart(10) })
|
|
480
|
+
] });
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
// src/ui/components/Preview.tsx
|
|
484
|
+
import { Box as Box5, Text as Text5 } from "ink";
|
|
485
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
392
486
|
var Preview = ({ session }) => {
|
|
393
487
|
if (!session) {
|
|
394
488
|
return null;
|
|
395
489
|
}
|
|
396
490
|
const summary = session.summary ? truncate(session.summary, 200) : "No summary available";
|
|
397
|
-
return /* @__PURE__ */
|
|
398
|
-
|
|
491
|
+
return /* @__PURE__ */ jsxs5(
|
|
492
|
+
Box5,
|
|
399
493
|
{
|
|
400
494
|
flexDirection: "column",
|
|
401
495
|
borderStyle: "round",
|
|
@@ -404,15 +498,16 @@ var Preview = ({ session }) => {
|
|
|
404
498
|
paddingY: 0,
|
|
405
499
|
marginTop: 1,
|
|
406
500
|
children: [
|
|
407
|
-
/* @__PURE__ */
|
|
408
|
-
/* @__PURE__ */
|
|
409
|
-
session.
|
|
501
|
+
/* @__PURE__ */ jsxs5(Box5, { children: [
|
|
502
|
+
/* @__PURE__ */ jsx5(Text5, { bold: true, children: "Preview" }),
|
|
503
|
+
session.isFavorite && /* @__PURE__ */ jsx5(Text5, { color: "yellow", children: " \u2B50" }),
|
|
504
|
+
session.projectPath && /* @__PURE__ */ jsxs5(Text5, { bold: true, color: "blue", children: [
|
|
410
505
|
" \u{1F4C1} ",
|
|
411
506
|
session.projectPath
|
|
412
507
|
] })
|
|
413
508
|
] }),
|
|
414
|
-
/* @__PURE__ */
|
|
415
|
-
/* @__PURE__ */
|
|
509
|
+
/* @__PURE__ */ jsx5(Text5, { wrap: "wrap", children: summary }),
|
|
510
|
+
/* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
|
|
416
511
|
"Messages: ",
|
|
417
512
|
session.messageCount
|
|
418
513
|
] })
|
|
@@ -720,6 +815,22 @@ function initSchema(database) {
|
|
|
720
815
|
embedding FLOAT[${EMBEDDING_DIMENSIONS}]
|
|
721
816
|
);
|
|
722
817
|
`);
|
|
818
|
+
database.exec(`
|
|
819
|
+
CREATE TABLE IF NOT EXISTS favorites (
|
|
820
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
821
|
+
type TEXT NOT NULL CHECK (type IN ('session', 'folder')),
|
|
822
|
+
value TEXT NOT NULL,
|
|
823
|
+
created_at TEXT NOT NULL,
|
|
824
|
+
UNIQUE(type, value)
|
|
825
|
+
);
|
|
826
|
+
`);
|
|
827
|
+
database.exec(`
|
|
828
|
+
CREATE TABLE IF NOT EXISTS project_order (
|
|
829
|
+
path TEXT PRIMARY KEY,
|
|
830
|
+
sort_order INTEGER NOT NULL,
|
|
831
|
+
updated_at TEXT NOT NULL
|
|
832
|
+
);
|
|
833
|
+
`);
|
|
723
834
|
database.exec(`
|
|
724
835
|
CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id);
|
|
725
836
|
`);
|
|
@@ -729,6 +840,9 @@ function initSchema(database) {
|
|
|
729
840
|
database.exec(`
|
|
730
841
|
CREATE INDEX IF NOT EXISTS idx_sessions_source ON sessions(source_file);
|
|
731
842
|
`);
|
|
843
|
+
database.exec(`
|
|
844
|
+
CREATE INDEX IF NOT EXISTS idx_favorites_type ON favorites(type);
|
|
845
|
+
`);
|
|
732
846
|
runMigrations(database);
|
|
733
847
|
}
|
|
734
848
|
function runMigrations(database) {
|
|
@@ -1001,6 +1115,96 @@ function needsReembedding(sessionId, currentContentLength, threshold = 500) {
|
|
|
1001
1115
|
if (!state) return true;
|
|
1002
1116
|
return currentContentLength - state.contentLength >= threshold;
|
|
1003
1117
|
}
|
|
1118
|
+
function addFavorite(type, value) {
|
|
1119
|
+
const db2 = getDatabase();
|
|
1120
|
+
try {
|
|
1121
|
+
db2.prepare(`
|
|
1122
|
+
INSERT OR IGNORE INTO favorites (type, value, created_at)
|
|
1123
|
+
VALUES (?, ?, ?)
|
|
1124
|
+
`).run(type, value, (/* @__PURE__ */ new Date()).toISOString());
|
|
1125
|
+
return true;
|
|
1126
|
+
} catch {
|
|
1127
|
+
return false;
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
function removeFavorite(type, value) {
|
|
1131
|
+
const db2 = getDatabase();
|
|
1132
|
+
const result = db2.prepare(`
|
|
1133
|
+
DELETE FROM favorites WHERE type = ? AND value = ?
|
|
1134
|
+
`).run(type, value);
|
|
1135
|
+
return result.changes > 0;
|
|
1136
|
+
}
|
|
1137
|
+
function toggleFavorite(type, value) {
|
|
1138
|
+
if (isFavorite(type, value)) {
|
|
1139
|
+
removeFavorite(type, value);
|
|
1140
|
+
return false;
|
|
1141
|
+
} else {
|
|
1142
|
+
addFavorite(type, value);
|
|
1143
|
+
return true;
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
function isFavorite(type, value) {
|
|
1147
|
+
const db2 = getDatabase();
|
|
1148
|
+
const row = db2.prepare(`
|
|
1149
|
+
SELECT 1 FROM favorites WHERE type = ? AND value = ?
|
|
1150
|
+
`).get(type, value);
|
|
1151
|
+
return !!row;
|
|
1152
|
+
}
|
|
1153
|
+
function getFavorites(type) {
|
|
1154
|
+
const db2 = getDatabase();
|
|
1155
|
+
const rows = db2.prepare(`
|
|
1156
|
+
SELECT id, type, value, created_at as createdAt
|
|
1157
|
+
FROM favorites
|
|
1158
|
+
WHERE type = ?
|
|
1159
|
+
ORDER BY created_at DESC
|
|
1160
|
+
`).all(type);
|
|
1161
|
+
return rows;
|
|
1162
|
+
}
|
|
1163
|
+
function getFavoriteSessionIds() {
|
|
1164
|
+
const favorites = getFavorites("session");
|
|
1165
|
+
return new Set(favorites.map((f) => f.value));
|
|
1166
|
+
}
|
|
1167
|
+
function hasFavoriteSessions() {
|
|
1168
|
+
const db2 = getDatabase();
|
|
1169
|
+
const row = db2.prepare(`
|
|
1170
|
+
SELECT 1 FROM favorites WHERE type = 'session' LIMIT 1
|
|
1171
|
+
`).get();
|
|
1172
|
+
return !!row;
|
|
1173
|
+
}
|
|
1174
|
+
function getProjectOrders() {
|
|
1175
|
+
const db2 = getDatabase();
|
|
1176
|
+
const rows = db2.prepare(`
|
|
1177
|
+
SELECT path, sort_order as sortOrder
|
|
1178
|
+
FROM project_order
|
|
1179
|
+
ORDER BY sort_order ASC
|
|
1180
|
+
`).all();
|
|
1181
|
+
const map = /* @__PURE__ */ new Map();
|
|
1182
|
+
for (const row of rows) {
|
|
1183
|
+
map.set(row.path, row.sortOrder);
|
|
1184
|
+
}
|
|
1185
|
+
return map;
|
|
1186
|
+
}
|
|
1187
|
+
function updateProjectOrders(orders) {
|
|
1188
|
+
const db2 = getDatabase();
|
|
1189
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1190
|
+
const stmt = db2.prepare(`
|
|
1191
|
+
INSERT OR REPLACE INTO project_order (path, sort_order, updated_at)
|
|
1192
|
+
VALUES (?, ?, ?)
|
|
1193
|
+
`);
|
|
1194
|
+
const transaction = db2.transaction(() => {
|
|
1195
|
+
for (const order of orders) {
|
|
1196
|
+
stmt.run(order.path, order.sortOrder, now);
|
|
1197
|
+
}
|
|
1198
|
+
});
|
|
1199
|
+
transaction();
|
|
1200
|
+
}
|
|
1201
|
+
function hasCustomProjectOrder() {
|
|
1202
|
+
const db2 = getDatabase();
|
|
1203
|
+
const row = db2.prepare(`
|
|
1204
|
+
SELECT 1 FROM project_order LIMIT 1
|
|
1205
|
+
`).get();
|
|
1206
|
+
return !!row;
|
|
1207
|
+
}
|
|
1004
1208
|
|
|
1005
1209
|
// src/db/vectors.ts
|
|
1006
1210
|
function storeEmbedding(sessionId, embedding) {
|
|
@@ -1112,18 +1316,81 @@ function useSessions(options = {}) {
|
|
|
1112
1316
|
const [embeddingsReady, setEmbeddingsReady] = useState(false);
|
|
1113
1317
|
const [isSearching, setIsSearching] = useState(false);
|
|
1114
1318
|
const [projectFilter, setProjectFilter] = useState(options.projectFilter ?? null);
|
|
1319
|
+
const [favoriteSessionIds, setFavoriteSessionIds] = useState(/* @__PURE__ */ new Set());
|
|
1320
|
+
const [hasFavSessions, setHasFavSessions] = useState(false);
|
|
1321
|
+
const [projectOrderMap, setProjectOrderMap] = useState(/* @__PURE__ */ new Map());
|
|
1322
|
+
const [hasCustomOrder, setHasCustomOrder] = useState(false);
|
|
1323
|
+
const smartSort = useCallback((sessionList, favIds) => {
|
|
1324
|
+
const withFavorites = sessionList.map((s) => ({
|
|
1325
|
+
...s,
|
|
1326
|
+
isFavorite: favIds.has(s.id)
|
|
1327
|
+
}));
|
|
1328
|
+
return withFavorites.sort((a, b) => {
|
|
1329
|
+
const aHasCustom = !!a.customTitle;
|
|
1330
|
+
const bHasCustom = !!b.customTitle;
|
|
1331
|
+
const aTier = a.isFavorite ? 0 : aHasCustom ? 1 : 2;
|
|
1332
|
+
const bTier = b.isFavorite ? 0 : bHasCustom ? 1 : 2;
|
|
1333
|
+
if (aTier !== bTier) return aTier - bTier;
|
|
1334
|
+
if (a.messageCount !== b.messageCount) return b.messageCount - a.messageCount;
|
|
1335
|
+
return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();
|
|
1336
|
+
});
|
|
1337
|
+
}, []);
|
|
1338
|
+
const [projects, setProjects] = useState([]);
|
|
1339
|
+
const calculateProjects = useCallback((sessionList, orderMap) => {
|
|
1340
|
+
const projectMap = /* @__PURE__ */ new Map();
|
|
1341
|
+
for (const session of sessionList) {
|
|
1342
|
+
if (!session.projectPath) continue;
|
|
1343
|
+
const existing = projectMap.get(session.projectPath);
|
|
1344
|
+
if (existing) {
|
|
1345
|
+
existing.sessionCount++;
|
|
1346
|
+
existing.totalMessages += session.messageCount;
|
|
1347
|
+
if (new Date(session.updatedAt) > new Date(existing.lastUpdated)) {
|
|
1348
|
+
existing.lastUpdated = session.updatedAt;
|
|
1349
|
+
}
|
|
1350
|
+
} else {
|
|
1351
|
+
const pathParts = session.projectPath.split("/");
|
|
1352
|
+
projectMap.set(session.projectPath, {
|
|
1353
|
+
path: session.projectPath,
|
|
1354
|
+
name: pathParts[pathParts.length - 1] || session.projectPath,
|
|
1355
|
+
sessionCount: 1,
|
|
1356
|
+
totalMessages: session.messageCount,
|
|
1357
|
+
sortOrder: orderMap.get(session.projectPath) ?? null,
|
|
1358
|
+
lastUpdated: session.updatedAt
|
|
1359
|
+
});
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
return Array.from(projectMap.values()).sort((a, b) => {
|
|
1363
|
+
if (a.sortOrder !== null && b.sortOrder !== null) {
|
|
1364
|
+
return a.sortOrder - b.sortOrder;
|
|
1365
|
+
}
|
|
1366
|
+
if (a.sortOrder !== null && b.sortOrder === null) return -1;
|
|
1367
|
+
if (a.sortOrder === null && b.sortOrder !== null) return 1;
|
|
1368
|
+
if (a.totalMessages !== b.totalMessages) return b.totalMessages - a.totalMessages;
|
|
1369
|
+
return new Date(b.lastUpdated).getTime() - new Date(a.lastUpdated).getTime();
|
|
1370
|
+
});
|
|
1371
|
+
}, []);
|
|
1115
1372
|
const loadSessions = useCallback(() => {
|
|
1116
1373
|
try {
|
|
1117
1374
|
const loaded = projectFilter ? listHumanSessionsByProject(projectFilter) : listHumanSessions();
|
|
1118
|
-
|
|
1119
|
-
|
|
1375
|
+
const favIds = getFavoriteSessionIds();
|
|
1376
|
+
const orderMap = getProjectOrders();
|
|
1377
|
+
setFavoriteSessionIds(favIds);
|
|
1378
|
+
setProjectOrderMap(orderMap);
|
|
1379
|
+
setHasFavSessions(hasFavoriteSessions());
|
|
1380
|
+
setHasCustomOrder(hasCustomProjectOrder());
|
|
1381
|
+
const sorted = smartSort(loaded, favIds);
|
|
1382
|
+
setAllSessions(sorted);
|
|
1383
|
+
setSessions(sorted);
|
|
1384
|
+
if (!projectFilter) {
|
|
1385
|
+
setProjects(calculateProjects(sorted, orderMap));
|
|
1386
|
+
}
|
|
1120
1387
|
setError(null);
|
|
1121
1388
|
} catch (err) {
|
|
1122
1389
|
setError(String(err));
|
|
1123
1390
|
} finally {
|
|
1124
1391
|
setLoading(false);
|
|
1125
1392
|
}
|
|
1126
|
-
}, [projectFilter]);
|
|
1393
|
+
}, [projectFilter, smartSort, calculateProjects]);
|
|
1127
1394
|
const initEmbeddings = useCallback(async () => {
|
|
1128
1395
|
if (isReady()) {
|
|
1129
1396
|
setEmbeddingsReady(true);
|
|
@@ -1153,7 +1420,7 @@ function useSessions(options = {}) {
|
|
|
1153
1420
|
const filtered = allSessions.filter(
|
|
1154
1421
|
(s) => s.title.toLowerCase().includes(query.toLowerCase()) || s.summary && s.summary.toLowerCase().includes(query.toLowerCase())
|
|
1155
1422
|
);
|
|
1156
|
-
setSessions(filtered);
|
|
1423
|
+
setSessions(smartSort(filtered, favoriteSessionIds));
|
|
1157
1424
|
setIsSearching(true);
|
|
1158
1425
|
return;
|
|
1159
1426
|
}
|
|
@@ -1161,18 +1428,18 @@ function useSessions(options = {}) {
|
|
|
1161
1428
|
setLoading(true);
|
|
1162
1429
|
const queryEmbedding = await getEmbedding(query);
|
|
1163
1430
|
const results = searchSessions(queryEmbedding, 20);
|
|
1164
|
-
setSessions(results);
|
|
1431
|
+
setSessions(smartSort(results, favoriteSessionIds));
|
|
1165
1432
|
setIsSearching(true);
|
|
1166
1433
|
} catch (err) {
|
|
1167
1434
|
setError(String(err));
|
|
1168
1435
|
const filtered = allSessions.filter(
|
|
1169
1436
|
(s) => s.title.toLowerCase().includes(query.toLowerCase()) || s.summary && s.summary.toLowerCase().includes(query.toLowerCase())
|
|
1170
1437
|
);
|
|
1171
|
-
setSessions(filtered);
|
|
1438
|
+
setSessions(smartSort(filtered, favoriteSessionIds));
|
|
1172
1439
|
} finally {
|
|
1173
1440
|
setLoading(false);
|
|
1174
1441
|
}
|
|
1175
|
-
}, [allSessions, embeddingsReady]);
|
|
1442
|
+
}, [allSessions, embeddingsReady, favoriteSessionIds, smartSort]);
|
|
1176
1443
|
const clearSearch = useCallback(() => {
|
|
1177
1444
|
setSessions(allSessions);
|
|
1178
1445
|
setIsSearching(false);
|
|
@@ -1187,8 +1454,43 @@ function useSessions(options = {}) {
|
|
|
1187
1454
|
const getSessionById = useCallback((id) => {
|
|
1188
1455
|
return getSession(id);
|
|
1189
1456
|
}, []);
|
|
1457
|
+
const toggleFavoriteHandler = useCallback((sessionId) => {
|
|
1458
|
+
const isNowFavorite = toggleFavorite("session", sessionId);
|
|
1459
|
+
const newFavIds = new Set(favoriteSessionIds);
|
|
1460
|
+
if (isNowFavorite) {
|
|
1461
|
+
newFavIds.add(sessionId);
|
|
1462
|
+
} else {
|
|
1463
|
+
newFavIds.delete(sessionId);
|
|
1464
|
+
}
|
|
1465
|
+
setFavoriteSessionIds(newFavIds);
|
|
1466
|
+
setHasFavSessions(newFavIds.size > 0);
|
|
1467
|
+
setAllSessions((prev) => smartSort(prev, newFavIds));
|
|
1468
|
+
setSessions((prev) => smartSort(prev, newFavIds));
|
|
1469
|
+
return isNowFavorite;
|
|
1470
|
+
}, [favoriteSessionIds, smartSort]);
|
|
1471
|
+
const moveProject = useCallback((fromIndex, toIndex) => {
|
|
1472
|
+
if (fromIndex === toIndex) return;
|
|
1473
|
+
if (fromIndex < 0 || toIndex < 0) return;
|
|
1474
|
+
if (fromIndex >= projects.length || toIndex >= projects.length) return;
|
|
1475
|
+
const newProjects = [...projects];
|
|
1476
|
+
const [movedProject] = newProjects.splice(fromIndex, 1);
|
|
1477
|
+
newProjects.splice(toIndex, 0, movedProject);
|
|
1478
|
+
const orders = newProjects.map((project, index) => ({
|
|
1479
|
+
path: project.path,
|
|
1480
|
+
sortOrder: index
|
|
1481
|
+
}));
|
|
1482
|
+
updateProjectOrders(orders);
|
|
1483
|
+
const newOrderMap = /* @__PURE__ */ new Map();
|
|
1484
|
+
for (const order of orders) {
|
|
1485
|
+
newOrderMap.set(order.path, order.sortOrder);
|
|
1486
|
+
}
|
|
1487
|
+
setProjectOrderMap(newOrderMap);
|
|
1488
|
+
setHasCustomOrder(true);
|
|
1489
|
+
setProjects(newProjects.map((p, i) => ({ ...p, sortOrder: i })));
|
|
1490
|
+
}, [projects]);
|
|
1190
1491
|
return {
|
|
1191
1492
|
sessions,
|
|
1493
|
+
projects,
|
|
1192
1494
|
loading,
|
|
1193
1495
|
error,
|
|
1194
1496
|
embeddingsReady,
|
|
@@ -1198,16 +1500,22 @@ function useSessions(options = {}) {
|
|
|
1198
1500
|
search,
|
|
1199
1501
|
clearSearch,
|
|
1200
1502
|
deleteSession: deleteSessionHandler,
|
|
1201
|
-
getSessionById
|
|
1503
|
+
getSessionById,
|
|
1504
|
+
toggleFavorite: toggleFavoriteHandler,
|
|
1505
|
+
favoriteSessionIds,
|
|
1506
|
+
hasFavoriteSessions: hasFavSessions,
|
|
1507
|
+
moveProject,
|
|
1508
|
+
hasCustomProjectOrder: hasCustomOrder
|
|
1202
1509
|
};
|
|
1203
1510
|
}
|
|
1204
1511
|
|
|
1205
1512
|
// src/ui/App.tsx
|
|
1206
|
-
import { jsx as
|
|
1513
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1207
1514
|
var App = ({ onResume, projectFilter: initialProjectFilter }) => {
|
|
1208
1515
|
const { exit } = useApp();
|
|
1209
1516
|
const {
|
|
1210
1517
|
sessions,
|
|
1518
|
+
projects,
|
|
1211
1519
|
loading,
|
|
1212
1520
|
embeddingsReady,
|
|
1213
1521
|
projectFilter,
|
|
@@ -1215,18 +1523,34 @@ var App = ({ onResume, projectFilter: initialProjectFilter }) => {
|
|
|
1215
1523
|
search,
|
|
1216
1524
|
clearSearch,
|
|
1217
1525
|
deleteSession: deleteSession2,
|
|
1218
|
-
refresh
|
|
1526
|
+
refresh,
|
|
1527
|
+
toggleFavorite: toggleFavorite2,
|
|
1528
|
+
moveProject
|
|
1219
1529
|
} = useSessions({ projectFilter: initialProjectFilter });
|
|
1220
1530
|
const [selectedIndex, setSelectedIndex] = useState2(0);
|
|
1221
1531
|
const [searchQuery, setSearchQuery] = useState2("");
|
|
1222
1532
|
const [mode, setMode] = useState2("list");
|
|
1223
1533
|
const [statusMessage, setStatusMessage] = useState2(null);
|
|
1224
1534
|
const [renameValue, setRenameValue] = useState2("");
|
|
1535
|
+
const [currentTab, setCurrentTab] = useState2("global");
|
|
1536
|
+
const [selectedProjectPath, setSelectedProjectPath] = useState2(null);
|
|
1537
|
+
const getCurrentView = useCallback2(() => {
|
|
1538
|
+
if (currentTab === "projects") {
|
|
1539
|
+
return selectedProjectPath ? "project-sessions" : "projects";
|
|
1540
|
+
}
|
|
1541
|
+
return "sessions";
|
|
1542
|
+
}, [currentTab, selectedProjectPath]);
|
|
1543
|
+
const currentView = getCurrentView();
|
|
1544
|
+
const projectSessions = selectedProjectPath ? sessions.filter((s) => s.projectPath === selectedProjectPath) : [];
|
|
1545
|
+
useEffect2(() => {
|
|
1546
|
+
setSelectedIndex(0);
|
|
1547
|
+
}, [currentTab, selectedProjectPath]);
|
|
1225
1548
|
useEffect2(() => {
|
|
1226
|
-
|
|
1227
|
-
|
|
1549
|
+
const maxIndex = currentView === "projects" ? projects.length - 1 : currentView === "project-sessions" ? projectSessions.length - 1 : sessions.length - 1;
|
|
1550
|
+
if (selectedIndex > maxIndex) {
|
|
1551
|
+
setSelectedIndex(Math.max(0, maxIndex));
|
|
1228
1552
|
}
|
|
1229
|
-
}, [sessions, selectedIndex]);
|
|
1553
|
+
}, [currentView, projects.length, projectSessions.length, sessions.length, selectedIndex]);
|
|
1230
1554
|
useEffect2(() => {
|
|
1231
1555
|
if (mode === "search" && searchQuery.length > 2) {
|
|
1232
1556
|
const timer = setTimeout(() => {
|
|
@@ -1243,8 +1567,15 @@ var App = ({ onResume, projectFilter: initialProjectFilter }) => {
|
|
|
1243
1567
|
return () => clearTimeout(timer);
|
|
1244
1568
|
}
|
|
1245
1569
|
}, [statusMessage]);
|
|
1570
|
+
const getCurrentSessions = useCallback2(() => {
|
|
1571
|
+
if (currentView === "project-sessions") {
|
|
1572
|
+
return projectSessions;
|
|
1573
|
+
}
|
|
1574
|
+
return sessions;
|
|
1575
|
+
}, [currentView, projectSessions, sessions]);
|
|
1246
1576
|
const handleRestore = useCallback2(() => {
|
|
1247
|
-
const
|
|
1577
|
+
const currentSessions2 = getCurrentSessions();
|
|
1578
|
+
const session = currentSessions2[selectedIndex];
|
|
1248
1579
|
if (!session) return;
|
|
1249
1580
|
if (session.sourceFile) {
|
|
1250
1581
|
const filename = basename4(session.sourceFile);
|
|
@@ -1283,17 +1614,30 @@ var App = ({ onResume, projectFilter: initialProjectFilter }) => {
|
|
|
1283
1614
|
} else {
|
|
1284
1615
|
setStatusMessage("No source file - cannot resume this session");
|
|
1285
1616
|
}
|
|
1286
|
-
}, [
|
|
1617
|
+
}, [getCurrentSessions, selectedIndex, onResume, exit]);
|
|
1618
|
+
const handleEnterProject = useCallback2(() => {
|
|
1619
|
+
const project = projects[selectedIndex];
|
|
1620
|
+
if (project) {
|
|
1621
|
+
setSelectedProjectPath(project.path);
|
|
1622
|
+
setSelectedIndex(0);
|
|
1623
|
+
}
|
|
1624
|
+
}, [projects, selectedIndex]);
|
|
1625
|
+
const handleBackToProjects = useCallback2(() => {
|
|
1626
|
+
setSelectedProjectPath(null);
|
|
1627
|
+
setSelectedIndex(0);
|
|
1628
|
+
}, []);
|
|
1287
1629
|
const handleDelete = useCallback2(() => {
|
|
1288
|
-
const
|
|
1630
|
+
const currentSessions2 = getCurrentSessions();
|
|
1631
|
+
const session = currentSessions2[selectedIndex];
|
|
1289
1632
|
if (session) {
|
|
1290
1633
|
deleteSession2(session.id);
|
|
1291
1634
|
setStatusMessage(`Deleted: ${session.customTitle || session.title}`);
|
|
1292
1635
|
setMode("list");
|
|
1293
1636
|
}
|
|
1294
|
-
}, [
|
|
1637
|
+
}, [getCurrentSessions, selectedIndex, deleteSession2]);
|
|
1295
1638
|
const handleRename = useCallback2(() => {
|
|
1296
|
-
const
|
|
1639
|
+
const currentSessions2 = getCurrentSessions();
|
|
1640
|
+
const session = currentSessions2[selectedIndex];
|
|
1297
1641
|
if (session && renameValue.trim()) {
|
|
1298
1642
|
renameSession(session.id, renameValue.trim());
|
|
1299
1643
|
setStatusMessage(`Renamed to: ${renameValue.trim()}`);
|
|
@@ -1301,18 +1645,19 @@ var App = ({ onResume, projectFilter: initialProjectFilter }) => {
|
|
|
1301
1645
|
}
|
|
1302
1646
|
setMode("list");
|
|
1303
1647
|
setRenameValue("");
|
|
1304
|
-
}, [
|
|
1648
|
+
}, [getCurrentSessions, selectedIndex, renameValue, refresh]);
|
|
1305
1649
|
const handleClearRename = useCallback2(() => {
|
|
1306
|
-
const
|
|
1650
|
+
const currentSessions2 = getCurrentSessions();
|
|
1651
|
+
const session = currentSessions2[selectedIndex];
|
|
1307
1652
|
if (session && session.customTitle) {
|
|
1308
1653
|
renameSession(session.id, null);
|
|
1309
1654
|
setStatusMessage(`Cleared custom name`);
|
|
1310
1655
|
refresh();
|
|
1311
1656
|
}
|
|
1312
1657
|
setMode("list");
|
|
1313
|
-
}, [
|
|
1658
|
+
}, [getCurrentSessions, selectedIndex, refresh]);
|
|
1314
1659
|
useInput((input, key) => {
|
|
1315
|
-
if (input === "q" && mode !== "search" && mode !== "rename") {
|
|
1660
|
+
if (input === "q" && mode !== "search" && mode !== "rename" && mode !== "sort-project") {
|
|
1316
1661
|
exit();
|
|
1317
1662
|
return;
|
|
1318
1663
|
}
|
|
@@ -1349,54 +1694,99 @@ var App = ({ onResume, projectFilter: initialProjectFilter }) => {
|
|
|
1349
1694
|
}
|
|
1350
1695
|
return;
|
|
1351
1696
|
}
|
|
1697
|
+
if (mode === "sort-project") {
|
|
1698
|
+
if (key.escape || key.return) {
|
|
1699
|
+
setMode("list");
|
|
1700
|
+
return;
|
|
1701
|
+
}
|
|
1702
|
+
if (key.upArrow || input === "k") {
|
|
1703
|
+
if (selectedIndex > 0) {
|
|
1704
|
+
moveProject(selectedIndex, selectedIndex - 1);
|
|
1705
|
+
setSelectedIndex(selectedIndex - 1);
|
|
1706
|
+
}
|
|
1707
|
+
return;
|
|
1708
|
+
}
|
|
1709
|
+
if (key.downArrow || input === "j") {
|
|
1710
|
+
if (selectedIndex < projects.length - 1) {
|
|
1711
|
+
moveProject(selectedIndex, selectedIndex + 1);
|
|
1712
|
+
setSelectedIndex(selectedIndex + 1);
|
|
1713
|
+
}
|
|
1714
|
+
return;
|
|
1715
|
+
}
|
|
1716
|
+
return;
|
|
1717
|
+
}
|
|
1352
1718
|
if (input === "/") {
|
|
1353
1719
|
setMode("search");
|
|
1354
1720
|
return;
|
|
1355
1721
|
}
|
|
1356
|
-
if (
|
|
1357
|
-
|
|
1358
|
-
|
|
1722
|
+
if ((key.escape || key.backspace || key.delete) && currentView === "project-sessions") {
|
|
1723
|
+
handleBackToProjects();
|
|
1724
|
+
return;
|
|
1725
|
+
}
|
|
1726
|
+
if (input === "r" && currentView !== "projects") {
|
|
1727
|
+
const currentSessions2 = getCurrentSessions();
|
|
1728
|
+
if (currentSessions2.length > 0) {
|
|
1729
|
+
const session = currentSessions2[selectedIndex];
|
|
1359
1730
|
setRenameValue(session?.customTitle || "");
|
|
1360
1731
|
setMode("rename");
|
|
1361
1732
|
}
|
|
1362
1733
|
return;
|
|
1363
1734
|
}
|
|
1364
|
-
if (input === "R") {
|
|
1735
|
+
if (input === "R" && currentView !== "projects") {
|
|
1365
1736
|
handleClearRename();
|
|
1366
1737
|
return;
|
|
1367
1738
|
}
|
|
1739
|
+
if (key.leftArrow || input === "h") {
|
|
1740
|
+
if (currentTab === "projects") {
|
|
1741
|
+
setCurrentTab("global");
|
|
1742
|
+
setSelectedProjectPath(null);
|
|
1743
|
+
}
|
|
1744
|
+
return;
|
|
1745
|
+
}
|
|
1746
|
+
if (key.rightArrow || input === "l") {
|
|
1747
|
+
if (currentTab === "global") {
|
|
1748
|
+
setCurrentTab("projects");
|
|
1749
|
+
}
|
|
1750
|
+
return;
|
|
1751
|
+
}
|
|
1368
1752
|
if (key.upArrow || input === "k") {
|
|
1369
1753
|
setSelectedIndex((prev) => Math.max(0, prev - 1));
|
|
1370
1754
|
return;
|
|
1371
1755
|
}
|
|
1372
1756
|
if (key.downArrow || input === "j") {
|
|
1373
|
-
|
|
1757
|
+
const maxIndex = currentView === "projects" ? projects.length - 1 : currentView === "project-sessions" ? projectSessions.length - 1 : sessions.length - 1;
|
|
1758
|
+
setSelectedIndex((prev) => Math.min(maxIndex, prev + 1));
|
|
1374
1759
|
return;
|
|
1375
1760
|
}
|
|
1376
1761
|
if (key.return) {
|
|
1377
|
-
|
|
1762
|
+
if (currentView === "projects") {
|
|
1763
|
+
handleEnterProject();
|
|
1764
|
+
} else {
|
|
1765
|
+
handleRestore();
|
|
1766
|
+
}
|
|
1378
1767
|
return;
|
|
1379
1768
|
}
|
|
1380
|
-
if (input === "d") {
|
|
1381
|
-
|
|
1769
|
+
if (input === "d" && currentView !== "projects") {
|
|
1770
|
+
const currentSessions2 = getCurrentSessions();
|
|
1771
|
+
if (currentSessions2.length > 0) {
|
|
1382
1772
|
setMode("confirm-delete");
|
|
1383
1773
|
}
|
|
1384
1774
|
return;
|
|
1385
1775
|
}
|
|
1386
|
-
if (input === "
|
|
1387
|
-
if (
|
|
1388
|
-
|
|
1389
|
-
|
|
1776
|
+
if (input === "s") {
|
|
1777
|
+
if (currentView === "projects") {
|
|
1778
|
+
if (projects.length > 0) {
|
|
1779
|
+
setMode("sort-project");
|
|
1780
|
+
setStatusMessage("Sort mode: use \u2191\u2193 to move, Enter to confirm");
|
|
1781
|
+
}
|
|
1390
1782
|
} else {
|
|
1391
|
-
const
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
setStatusMessage("No folder for this session");
|
|
1783
|
+
const currentSessions2 = getCurrentSessions();
|
|
1784
|
+
const session = currentSessions2[selectedIndex];
|
|
1785
|
+
if (session) {
|
|
1786
|
+
const isNowFavorite = toggleFavorite2(session.id);
|
|
1787
|
+
setStatusMessage(isNowFavorite ? "\u2B50 Added to favorites" : "Removed from favorites");
|
|
1397
1788
|
}
|
|
1398
1789
|
}
|
|
1399
|
-
setSelectedIndex(0);
|
|
1400
1790
|
return;
|
|
1401
1791
|
}
|
|
1402
1792
|
});
|
|
@@ -1405,15 +1795,21 @@ var App = ({ onResume, projectFilter: initialProjectFilter }) => {
|
|
|
1405
1795
|
setSelectedIndex(0);
|
|
1406
1796
|
}, []);
|
|
1407
1797
|
if (loading && sessions.length === 0) {
|
|
1408
|
-
return /* @__PURE__ */
|
|
1409
|
-
/* @__PURE__ */
|
|
1410
|
-
/* @__PURE__ */
|
|
1798
|
+
return /* @__PURE__ */ jsxs6(Box6, { padding: 1, children: [
|
|
1799
|
+
/* @__PURE__ */ jsx6(Spinner, { type: "dots" }),
|
|
1800
|
+
/* @__PURE__ */ jsx6(Text6, { children: " Loading sessions..." })
|
|
1411
1801
|
] });
|
|
1412
1802
|
}
|
|
1413
|
-
const
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1803
|
+
const currentSessions = getCurrentSessions();
|
|
1804
|
+
const selectedSession = currentView !== "projects" ? currentSessions[selectedIndex] || null : null;
|
|
1805
|
+
const selectedProject = currentView === "projects" ? projects[selectedIndex] || null : null;
|
|
1806
|
+
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", padding: 1, children: [
|
|
1807
|
+
/* @__PURE__ */ jsx6(Header, { embeddingsReady, projectFilter: selectedProjectPath }),
|
|
1808
|
+
currentView === "project-sessions" && selectedProjectPath && /* @__PURE__ */ jsxs6(Box6, { marginBottom: 0, children: [
|
|
1809
|
+
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "Projects \u2192 " }),
|
|
1810
|
+
/* @__PURE__ */ jsx6(Text6, { color: "blue", children: basename4(selectedProjectPath) })
|
|
1811
|
+
] }),
|
|
1812
|
+
currentTab === "global" && /* @__PURE__ */ jsx6(
|
|
1417
1813
|
SearchInput,
|
|
1418
1814
|
{
|
|
1419
1815
|
value: searchQuery,
|
|
@@ -1421,22 +1817,62 @@ var App = ({ onResume, projectFilter: initialProjectFilter }) => {
|
|
|
1421
1817
|
isFocused: mode === "search"
|
|
1422
1818
|
}
|
|
1423
1819
|
),
|
|
1424
|
-
/* @__PURE__ */
|
|
1820
|
+
currentView === "projects" ? /* @__PURE__ */ jsx6(
|
|
1821
|
+
ProjectList,
|
|
1822
|
+
{
|
|
1823
|
+
projects,
|
|
1824
|
+
selectedIndex,
|
|
1825
|
+
onSelect: setSelectedIndex
|
|
1826
|
+
}
|
|
1827
|
+
) : /* @__PURE__ */ jsx6(
|
|
1425
1828
|
SessionList,
|
|
1426
1829
|
{
|
|
1427
|
-
sessions,
|
|
1830
|
+
sessions: currentSessions,
|
|
1428
1831
|
selectedIndex,
|
|
1429
1832
|
onSelect: setSelectedIndex
|
|
1430
1833
|
}
|
|
1431
1834
|
),
|
|
1432
|
-
/* @__PURE__ */
|
|
1433
|
-
|
|
1835
|
+
selectedSession && /* @__PURE__ */ jsx6(Preview, { session: selectedSession }),
|
|
1836
|
+
selectedProject && /* @__PURE__ */ jsxs6(
|
|
1837
|
+
Box6,
|
|
1838
|
+
{
|
|
1839
|
+
flexDirection: "column",
|
|
1840
|
+
borderStyle: "round",
|
|
1841
|
+
borderColor: "gray",
|
|
1842
|
+
paddingX: 1,
|
|
1843
|
+
paddingY: 0,
|
|
1844
|
+
marginTop: 1,
|
|
1845
|
+
children: [
|
|
1846
|
+
/* @__PURE__ */ jsxs6(Box6, { children: [
|
|
1847
|
+
/* @__PURE__ */ jsx6(Text6, { bold: true, children: "Project Preview" }),
|
|
1848
|
+
selectedProject.sortOrder !== null && /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1849
|
+
" (#",
|
|
1850
|
+
selectedProject.sortOrder + 1,
|
|
1851
|
+
")"
|
|
1852
|
+
] })
|
|
1853
|
+
] }),
|
|
1854
|
+
/* @__PURE__ */ jsxs6(Text6, { color: "blue", children: [
|
|
1855
|
+
"\u{1F4C1} ",
|
|
1856
|
+
selectedProject.path
|
|
1857
|
+
] }),
|
|
1858
|
+
/* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1859
|
+
selectedProject.sessionCount,
|
|
1860
|
+
" session",
|
|
1861
|
+
selectedProject.sessionCount !== 1 ? "s" : "",
|
|
1862
|
+
" \u2022 ",
|
|
1863
|
+
selectedProject.totalMessages,
|
|
1864
|
+
" messages"
|
|
1865
|
+
] })
|
|
1866
|
+
]
|
|
1867
|
+
}
|
|
1868
|
+
),
|
|
1869
|
+
/* @__PURE__ */ jsx6(Box6, { marginTop: 1, children: mode === "confirm-delete" ? /* @__PURE__ */ jsxs6(Text6, { color: "yellow", children: [
|
|
1434
1870
|
'Delete "',
|
|
1435
1871
|
selectedSession?.customTitle || selectedSession?.title,
|
|
1436
1872
|
'"? [y/n]'
|
|
1437
|
-
] }) : mode === "rename" ? /* @__PURE__ */
|
|
1438
|
-
/* @__PURE__ */
|
|
1439
|
-
/* @__PURE__ */
|
|
1873
|
+
] }) : mode === "rename" ? /* @__PURE__ */ jsxs6(Box6, { children: [
|
|
1874
|
+
/* @__PURE__ */ jsx6(Text6, { color: "magenta", children: "Rename: " }),
|
|
1875
|
+
/* @__PURE__ */ jsx6(
|
|
1440
1876
|
TextInput2,
|
|
1441
1877
|
{
|
|
1442
1878
|
value: renameValue,
|
|
@@ -1444,8 +1880,32 @@ var App = ({ onResume, projectFilter: initialProjectFilter }) => {
|
|
|
1444
1880
|
placeholder: "Enter new name..."
|
|
1445
1881
|
}
|
|
1446
1882
|
),
|
|
1447
|
-
/* @__PURE__ */
|
|
1448
|
-
] }) : statusMessage ? /* @__PURE__ */
|
|
1883
|
+
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: " [Enter] Save [Esc] Cancel" })
|
|
1884
|
+
] }) : mode === "sort-project" ? /* @__PURE__ */ jsx6(Text6, { color: "cyan", children: "Sort mode: [\u2191\u2193] Move project [Enter/Esc] Done" }) : statusMessage ? /* @__PURE__ */ jsx6(Text6, { color: "green", children: statusMessage }) : currentView === "projects" ? /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "[\u2191\u2193] Navigate [Enter] Open [s] Sort [\u2190\u2192] Switch tabs [q] Quit" }) : currentView === "project-sessions" ? /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "[\u2191\u2193] Navigate [Enter] Resume [s] Star [Esc] Back [r] Rename [d] Delete [q] Quit" }) : /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "[\u2191\u2193] Navigate [Enter] Resume [s] Star [r] Rename [d] Delete [/] Search [q] Quit" }) }),
|
|
1885
|
+
/* @__PURE__ */ jsxs6(Box6, { marginTop: 1, children: [
|
|
1886
|
+
/* @__PURE__ */ jsx6(
|
|
1887
|
+
Text6,
|
|
1888
|
+
{
|
|
1889
|
+
backgroundColor: currentTab === "global" ? "green" : void 0,
|
|
1890
|
+
color: currentTab === "global" ? "white" : void 0,
|
|
1891
|
+
bold: currentTab === "global",
|
|
1892
|
+
dimColor: currentTab !== "global",
|
|
1893
|
+
children: currentTab === "global" ? " Global " : "Global"
|
|
1894
|
+
}
|
|
1895
|
+
),
|
|
1896
|
+
/* @__PURE__ */ jsx6(Text6, { children: " " }),
|
|
1897
|
+
/* @__PURE__ */ jsx6(
|
|
1898
|
+
Text6,
|
|
1899
|
+
{
|
|
1900
|
+
backgroundColor: currentTab === "projects" ? "magenta" : void 0,
|
|
1901
|
+
color: currentTab === "projects" ? "white" : void 0,
|
|
1902
|
+
bold: currentTab === "projects",
|
|
1903
|
+
dimColor: currentTab !== "projects",
|
|
1904
|
+
children: currentTab === "projects" ? " Projects " : "Projects"
|
|
1905
|
+
}
|
|
1906
|
+
),
|
|
1907
|
+
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: " [\u2190\u2192] switch" })
|
|
1908
|
+
] })
|
|
1449
1909
|
] });
|
|
1450
1910
|
};
|
|
1451
1911
|
|