@vitorcen/context-resume 1.0.2 → 1.0.3
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/ui/app.js +37 -13
- package/package.json +1 -1
package/dist/ui/app.js
CHANGED
|
@@ -3,6 +3,22 @@ import { useState, useEffect } from 'react';
|
|
|
3
3
|
import { Box, Text, useInput, useApp } from 'ink';
|
|
4
4
|
import SelectInput from 'ink-select-input';
|
|
5
5
|
import { getClaudeSessions, getCodexSessions } from '../adapters/index.js';
|
|
6
|
+
import stringWidth from 'string-width';
|
|
7
|
+
// Truncate by display width (handles CJK characters correctly)
|
|
8
|
+
const truncateByWidth = (str, maxWidth) => {
|
|
9
|
+
if (stringWidth(str) <= maxWidth)
|
|
10
|
+
return str;
|
|
11
|
+
let result = '';
|
|
12
|
+
let width = 0;
|
|
13
|
+
for (const char of str) {
|
|
14
|
+
const charWidth = stringWidth(char);
|
|
15
|
+
if (width + charWidth > maxWidth)
|
|
16
|
+
break;
|
|
17
|
+
result += char;
|
|
18
|
+
width += charWidth;
|
|
19
|
+
}
|
|
20
|
+
return result + '...';
|
|
21
|
+
};
|
|
6
22
|
const App = ({ cwd, limit = 10, onSubmit }) => {
|
|
7
23
|
const [claudeItems, setClaudeItems] = useState([]);
|
|
8
24
|
const [codexItems, setCodexItems] = useState([]);
|
|
@@ -33,16 +49,24 @@ const App = ({ cwd, limit = 10, onSubmit }) => {
|
|
|
33
49
|
]);
|
|
34
50
|
// Sort by timestamp desc
|
|
35
51
|
const sortFn = (a, b) => b.timestamp - a.timestamp;
|
|
36
|
-
const cItems = claudeSessions.sort(sortFn).map(s =>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
52
|
+
const cItems = claudeSessions.sort(sortFn).map(s => {
|
|
53
|
+
const title = s.title.replace(/\n/g, ' ').trim();
|
|
54
|
+
const truncatedTitle = truncateByWidth(title, 45);
|
|
55
|
+
return {
|
|
56
|
+
label: `${truncatedTitle} (${new Date(s.timestamp).toLocaleDateString()})`,
|
|
57
|
+
value: s.id,
|
|
58
|
+
session: s
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
const cxItems = codexSessions.sort(sortFn).map(s => {
|
|
62
|
+
const title = s.title.replace(/\n/g, ' ').trim();
|
|
63
|
+
const truncatedTitle = truncateByWidth(title, 45);
|
|
64
|
+
return {
|
|
65
|
+
label: `${truncatedTitle} (${new Date(s.timestamp).toLocaleDateString()})`,
|
|
66
|
+
value: s.id,
|
|
67
|
+
session: s
|
|
68
|
+
};
|
|
69
|
+
});
|
|
46
70
|
setClaudeItems(cItems);
|
|
47
71
|
setCodexItems(cxItems);
|
|
48
72
|
if (cItems.length > 0)
|
|
@@ -66,12 +90,12 @@ const App = ({ cwd, limit = 10, onSubmit }) => {
|
|
|
66
90
|
const currentItem = activePanel === 'claude' ? activeClaudeItem : activeCodexItem;
|
|
67
91
|
// Filter out empty prompts
|
|
68
92
|
const prompts = (currentItem?.session.userPrompts || []).filter(p => p && p.trim().length > 0);
|
|
69
|
-
// Truncate prompts logic
|
|
93
|
+
// Truncate prompts logic (~60 display width: ~120 ASCII chars or ~60 CJK chars)
|
|
70
94
|
const previewText = prompts.map((p, i) => {
|
|
71
95
|
const clean = p.replace(/\n/g, ' ').trim();
|
|
72
|
-
const truncated = clean
|
|
96
|
+
const truncated = truncateByWidth(clean, 120);
|
|
73
97
|
return `${i + 1}. ${truncated}`;
|
|
74
98
|
}).join('\n');
|
|
75
|
-
return (_jsxs(Box, { flexDirection: "column",
|
|
99
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { borderStyle: "single", flexDirection: "column", paddingX: 1, children: [_jsx(Text, { bold: true, underline: true, children: "Preview (User Prompts)" }), _jsx(Text, { children: previewText || 'Select a session to view prompts' })] }), _jsxs(Box, { flexDirection: "row", minHeight: 20, children: [_jsxs(Box, { width: "50%", borderStyle: activePanel === 'claude' ? 'double' : 'single', flexDirection: "column", borderColor: activePanel === 'claude' ? 'green' : 'white', children: [_jsx(Text, { bold: true, underline: true, color: activePanel === 'claude' ? 'green' : 'white', children: "Claude Sessions" }), claudeItems.length === 0 ? (_jsx(Text, { children: "No sessions found." })) : (_jsx(SelectInput, { items: claudeItems, onSelect: handleSelect, onHighlight: handleHighlightClaude, isFocused: activePanel === 'claude' }))] }), _jsxs(Box, { width: "50%", borderStyle: activePanel === 'codex' ? 'double' : 'single', flexDirection: "column", borderColor: activePanel === 'codex' ? 'green' : 'white', children: [_jsx(Text, { bold: true, underline: true, color: activePanel === 'codex' ? 'green' : 'white', children: "Codex Sessions" }), codexItems.length === 0 ? (_jsx(Text, { children: "No sessions found." })) : (_jsx(SelectInput, { items: codexItems, onSelect: handleSelect, onHighlight: handleHighlightCodex, isFocused: activePanel === 'codex' }))] })] }), _jsx(Box, { marginTop: 0, children: _jsx(Text, { dimColor: true, children: "TAB/Arrows: Switch Panel | ENTER: Select | ESC: Exit" }) })] }));
|
|
76
100
|
};
|
|
77
101
|
export default App;
|
package/package.json
CHANGED