openpaean 0.2.0 → 0.3.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/agent/chat.ink.d.ts +5 -0
- package/dist/agent/chat.ink.d.ts.map +1 -1
- package/dist/agent/chat.ink.js +9 -0
- package/dist/agent/chat.ink.js.map +1 -1
- package/dist/cli.js +3 -3
- package/dist/cli.js.map +1 -1
- package/dist/commands/agent.d.ts.map +1 -1
- package/dist/commands/agent.js +6 -5
- package/dist/commands/agent.js.map +1 -1
- package/dist/ui/terminal/ErrorDisplay.d.ts +63 -0
- package/dist/ui/terminal/ErrorDisplay.d.ts.map +1 -0
- package/dist/ui/terminal/ErrorDisplay.js +113 -0
- package/dist/ui/terminal/ErrorDisplay.js.map +1 -0
- package/dist/ui/terminal/HelpDisplay.d.ts +21 -0
- package/dist/ui/terminal/HelpDisplay.d.ts.map +1 -0
- package/dist/ui/terminal/HelpDisplay.js +89 -0
- package/dist/ui/terminal/HelpDisplay.js.map +1 -0
- package/dist/ui/terminal/Spinner.d.ts +65 -0
- package/dist/ui/terminal/Spinner.d.ts.map +1 -0
- package/dist/ui/terminal/Spinner.js +130 -0
- package/dist/ui/terminal/Spinner.js.map +1 -0
- package/dist/ui/terminal/StatusBar.d.ts +27 -0
- package/dist/ui/terminal/StatusBar.d.ts.map +1 -0
- package/dist/ui/terminal/StatusBar.js +79 -0
- package/dist/ui/terminal/StatusBar.js.map +1 -0
- package/dist/ui/terminal/TerminalApp.d.ts +137 -0
- package/dist/ui/terminal/TerminalApp.d.ts.map +1 -0
- package/dist/ui/terminal/TerminalApp.js +450 -0
- package/dist/ui/terminal/TerminalApp.js.map +1 -0
- package/dist/ui/terminal/output.d.ts +91 -0
- package/dist/ui/terminal/output.d.ts.map +1 -0
- package/dist/ui/terminal/output.js +138 -0
- package/dist/ui/terminal/output.js.map +1 -0
- package/dist/ui/theme/index.d.ts +157 -0
- package/dist/ui/theme/index.d.ts.map +1 -0
- package/dist/ui/theme/index.js +236 -0
- package/dist/ui/theme/index.js.map +1 -0
- package/dist/utils/inputHistory.d.ts +88 -0
- package/dist/utils/inputHistory.d.ts.map +1 -0
- package/dist/utils/inputHistory.js +206 -0
- package/dist/utils/inputHistory.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input History Management
|
|
3
|
+
* Persistent command history with search capabilities
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
import { homedir } from 'os';
|
|
8
|
+
/**
|
|
9
|
+
* Default history options
|
|
10
|
+
*/
|
|
11
|
+
const DEFAULT_OPTIONS = {
|
|
12
|
+
maxSize: 1000,
|
|
13
|
+
historyPath: join(homedir(), '.openpaean', 'history'),
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Input History class
|
|
17
|
+
*/
|
|
18
|
+
export class InputHistory {
|
|
19
|
+
history = [];
|
|
20
|
+
index = -1;
|
|
21
|
+
tempInput = '';
|
|
22
|
+
options;
|
|
23
|
+
constructor(options = {}) {
|
|
24
|
+
this.options = { ...DEFAULT_OPTIONS, ...options };
|
|
25
|
+
this.load();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Load history from file
|
|
29
|
+
*/
|
|
30
|
+
load() {
|
|
31
|
+
if (existsSync(this.options.historyPath)) {
|
|
32
|
+
try {
|
|
33
|
+
const content = readFileSync(this.options.historyPath, 'utf-8');
|
|
34
|
+
const lines = content.trim().split('\n');
|
|
35
|
+
this.history = lines
|
|
36
|
+
.map(line => {
|
|
37
|
+
try {
|
|
38
|
+
return JSON.parse(line);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Fallback: treat line as plain command
|
|
42
|
+
return { command: line, timestamp: Date.now() };
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
.filter(entry => entry.command.trim().length > 0);
|
|
46
|
+
// Limit size
|
|
47
|
+
if (this.history.length > this.options.maxSize) {
|
|
48
|
+
this.history = this.history.slice(-this.options.maxSize);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
this.history = [];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
this.index = this.history.length;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Save history to file
|
|
59
|
+
*/
|
|
60
|
+
save() {
|
|
61
|
+
try {
|
|
62
|
+
const dir = join(this.options.historyPath, '..');
|
|
63
|
+
if (!existsSync(dir)) {
|
|
64
|
+
mkdirSync(dir, { recursive: true });
|
|
65
|
+
}
|
|
66
|
+
const content = this.history
|
|
67
|
+
.map(entry => JSON.stringify(entry))
|
|
68
|
+
.join('\n');
|
|
69
|
+
writeFileSync(this.options.historyPath, content, 'utf-8');
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
// Silently fail on save errors
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Add a command to history
|
|
77
|
+
*/
|
|
78
|
+
add(command) {
|
|
79
|
+
const trimmed = command.trim();
|
|
80
|
+
if (trimmed.length === 0)
|
|
81
|
+
return;
|
|
82
|
+
// Skip duplicates of the most recent entry
|
|
83
|
+
if (this.history.length > 0 && this.history[this.history.length - 1].command === trimmed) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
this.history.push({
|
|
87
|
+
command: trimmed,
|
|
88
|
+
timestamp: Date.now(),
|
|
89
|
+
});
|
|
90
|
+
// Trim if over max size
|
|
91
|
+
if (this.history.length > this.options.maxSize) {
|
|
92
|
+
this.history.shift();
|
|
93
|
+
}
|
|
94
|
+
this.save();
|
|
95
|
+
this.index = this.history.length;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get previous command (up arrow)
|
|
99
|
+
*/
|
|
100
|
+
getPrevious(currentInput) {
|
|
101
|
+
if (this.history.length === 0)
|
|
102
|
+
return null;
|
|
103
|
+
// Save current input on first navigation
|
|
104
|
+
if (this.index === this.history.length) {
|
|
105
|
+
this.tempInput = currentInput;
|
|
106
|
+
}
|
|
107
|
+
if (this.index > 0) {
|
|
108
|
+
this.index--;
|
|
109
|
+
return this.history[this.index].command;
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get next command (down arrow)
|
|
115
|
+
*/
|
|
116
|
+
getNext() {
|
|
117
|
+
if (this.index < this.history.length - 1) {
|
|
118
|
+
this.index++;
|
|
119
|
+
return this.history[this.index].command;
|
|
120
|
+
}
|
|
121
|
+
// Return to current input
|
|
122
|
+
if (this.index === this.history.length - 1) {
|
|
123
|
+
this.index = this.history.length;
|
|
124
|
+
return this.tempInput;
|
|
125
|
+
}
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Search backwards for matching command
|
|
130
|
+
*/
|
|
131
|
+
search(prefix, startIndex) {
|
|
132
|
+
const start = startIndex ?? this.history.length;
|
|
133
|
+
for (let i = start - 1; i >= 0; i--) {
|
|
134
|
+
if (this.history[i].command.toLowerCase().startsWith(prefix.toLowerCase())) {
|
|
135
|
+
return { command: this.history[i].command, index: i };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Fuzzy search in history
|
|
142
|
+
*/
|
|
143
|
+
fuzzySearch(query, limit = 10) {
|
|
144
|
+
const lowerQuery = query.toLowerCase();
|
|
145
|
+
return this.history
|
|
146
|
+
.filter(entry => entry.command.toLowerCase().includes(lowerQuery))
|
|
147
|
+
.sort((a, b) => b.timestamp - a.timestamp)
|
|
148
|
+
.slice(0, limit);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Get all history entries
|
|
152
|
+
*/
|
|
153
|
+
getAll() {
|
|
154
|
+
return [...this.history];
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Get history entry at index
|
|
158
|
+
*/
|
|
159
|
+
getAt(index) {
|
|
160
|
+
if (index >= 0 && index < this.history.length) {
|
|
161
|
+
return this.history[index].command;
|
|
162
|
+
}
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Clear history
|
|
167
|
+
*/
|
|
168
|
+
clear() {
|
|
169
|
+
this.history = [];
|
|
170
|
+
this.index = 0;
|
|
171
|
+
this.save();
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Reset navigation index
|
|
175
|
+
*/
|
|
176
|
+
resetIndex() {
|
|
177
|
+
this.index = this.history.length;
|
|
178
|
+
this.tempInput = '';
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Get size
|
|
182
|
+
*/
|
|
183
|
+
get size() {
|
|
184
|
+
return this.history.length;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Singleton instance
|
|
189
|
+
*/
|
|
190
|
+
let historyInstance = null;
|
|
191
|
+
/**
|
|
192
|
+
* Get the history singleton
|
|
193
|
+
*/
|
|
194
|
+
export function getHistory() {
|
|
195
|
+
if (!historyInstance) {
|
|
196
|
+
historyInstance = new InputHistory();
|
|
197
|
+
}
|
|
198
|
+
return historyInstance;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Reset the history singleton (for testing)
|
|
202
|
+
*/
|
|
203
|
+
export function resetHistory() {
|
|
204
|
+
historyInstance = null;
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=inputHistory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inputHistory.js","sourceRoot":"","sources":["../../src/utils/inputHistory.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openpaean",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Open source AI agent CLI with
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Open source AI agent CLI with scrolling TUI (Claude Code style) and local MCP integration",
|
|
5
5
|
"author": "Paean AI <dev@paean.ai>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|