caroushell 0.1.18 → 0.1.20
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/ai-suggester.js +4 -3
- package/dist/app.js +22 -7
- package/dist/history-suggester.js +13 -8
- package/dist/keyboard.js +3 -3
- package/package.json +2 -1
package/dist/ai-suggester.js
CHANGED
|
@@ -171,8 +171,9 @@ class AISuggester {
|
|
|
171
171
|
descriptions.push(desc);
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
|
-
const prompt = `You are a shell assistant. Given a partial shell input,
|
|
175
|
-
useful, concise shell commands that the user might run
|
|
174
|
+
const prompt = `You are a shell assistant. Given a partial shell input, \
|
|
175
|
+
suggest ${maxDisplayed} useful, concise shell commands that the user might run \
|
|
176
|
+
next.
|
|
176
177
|
Return one suggestion per line, no numbering, no extra text.
|
|
177
178
|
Return the whole suggestion, not just what remains to type out.
|
|
178
179
|
|
|
@@ -193,7 +194,7 @@ ${descriptions.join("\n\n")}
|
|
|
193
194
|
.map((s) => s.trim())
|
|
194
195
|
.filter(Boolean)
|
|
195
196
|
.slice(0, maxDisplayed);
|
|
196
|
-
(0, logs_1.logLine)(`AI lines: ${lines
|
|
197
|
+
(0, logs_1.logLine)(`AI lines: ${lines}`);
|
|
197
198
|
return lines;
|
|
198
199
|
}
|
|
199
200
|
}
|
package/dist/app.js
CHANGED
|
@@ -8,14 +8,16 @@ const history_suggester_1 = require("./history-suggester");
|
|
|
8
8
|
const ai_suggester_1 = require("./ai-suggester");
|
|
9
9
|
const file_suggester_1 = require("./file-suggester");
|
|
10
10
|
const spawner_1 = require("./spawner");
|
|
11
|
+
const logs_1 = require("./logs");
|
|
11
12
|
class App {
|
|
12
|
-
constructor() {
|
|
13
|
+
constructor(deps = {}) {
|
|
13
14
|
this.usingFileSuggestions = false;
|
|
14
|
-
this.terminal = new terminal_1.Terminal();
|
|
15
|
-
this.keyboard = new keyboard_1.Keyboard();
|
|
16
|
-
this.history = new history_suggester_1.HistorySuggester();
|
|
17
|
-
this.ai = new ai_suggester_1.AISuggester();
|
|
18
|
-
this.files = new file_suggester_1.FileSuggester();
|
|
15
|
+
this.terminal = deps.terminal ?? new terminal_1.Terminal();
|
|
16
|
+
this.keyboard = deps.keyboard ?? new keyboard_1.Keyboard();
|
|
17
|
+
this.history = deps.topPanel ?? new history_suggester_1.HistorySuggester();
|
|
18
|
+
this.ai = deps.bottomPanel ?? new ai_suggester_1.AISuggester();
|
|
19
|
+
this.files = deps.files ?? new file_suggester_1.FileSuggester();
|
|
20
|
+
this.suggesters = deps.suggesters ?? [this.history, this.ai, this.files];
|
|
19
21
|
this.carousel = new carousel_1.Carousel({
|
|
20
22
|
top: this.history,
|
|
21
23
|
bottom: this.ai,
|
|
@@ -170,7 +172,7 @@ class App {
|
|
|
170
172
|
try {
|
|
171
173
|
const storeInHistory = await (0, spawner_1.runUserCommand)(cmd);
|
|
172
174
|
if (storeInHistory) {
|
|
173
|
-
await this.
|
|
175
|
+
await this.broadcastCommand(cmd);
|
|
174
176
|
}
|
|
175
177
|
}
|
|
176
178
|
finally {
|
|
@@ -242,5 +244,18 @@ class App {
|
|
|
242
244
|
this.usingFileSuggestions = true;
|
|
243
245
|
this.carousel.setTopSuggester(this.files);
|
|
244
246
|
}
|
|
247
|
+
async broadcastCommand(cmd) {
|
|
248
|
+
const listeners = this.suggesters
|
|
249
|
+
.map((suggester) => suggester.onCommandRan?.(cmd))
|
|
250
|
+
.filter(Boolean);
|
|
251
|
+
if (listeners.length === 0)
|
|
252
|
+
return;
|
|
253
|
+
try {
|
|
254
|
+
await Promise.all(listeners);
|
|
255
|
+
}
|
|
256
|
+
catch (err) {
|
|
257
|
+
(0, logs_1.logLine)("suggester onCommandRan error: " + err?.message);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
245
260
|
}
|
|
246
261
|
exports.App = App;
|
|
@@ -10,6 +10,7 @@ const config_1 = require("./config");
|
|
|
10
10
|
class HistorySuggester {
|
|
11
11
|
constructor(filePath) {
|
|
12
12
|
this.prefix = "⌛";
|
|
13
|
+
// `items` is the history as a list of commands, with the most recent at index 0
|
|
13
14
|
this.items = [];
|
|
14
15
|
this.filteredItems = [];
|
|
15
16
|
this.maxItems = 1000;
|
|
@@ -47,6 +48,9 @@ class HistorySuggester {
|
|
|
47
48
|
.catch(() => { });
|
|
48
49
|
await fs_1.promises.appendFile(this.filePath, this.serializeHistoryEntry(command), "utf8");
|
|
49
50
|
}
|
|
51
|
+
async onCommandRan(command) {
|
|
52
|
+
await this.add(command);
|
|
53
|
+
}
|
|
50
54
|
latest() {
|
|
51
55
|
return this.filteredItems;
|
|
52
56
|
}
|
|
@@ -71,18 +75,19 @@ class HistorySuggester {
|
|
|
71
75
|
carousel.render();
|
|
72
76
|
}
|
|
73
77
|
descriptionForAi() {
|
|
78
|
+
// This goes into the prompt
|
|
74
79
|
const lines = [];
|
|
75
80
|
const maxHistoryLines = 20;
|
|
76
|
-
const start =
|
|
77
|
-
const end =
|
|
78
|
-
const
|
|
79
|
-
if (
|
|
80
|
-
lines.push(`The most recent command is: "${
|
|
81
|
+
const start = 0;
|
|
82
|
+
const end = maxHistoryLines;
|
|
83
|
+
const newToOldSlice = this.items.slice(start, end);
|
|
84
|
+
if (newToOldSlice.length > 0) {
|
|
85
|
+
lines.push(`The most recent command is: "${newToOldSlice[0]}"`);
|
|
81
86
|
}
|
|
82
|
-
if (
|
|
87
|
+
if (newToOldSlice.length > 1) {
|
|
83
88
|
lines.push("The most recent commands are (from recent to oldest):");
|
|
84
|
-
for (let i = 0; i <
|
|
85
|
-
lines.push(` ${i + 1}. ${
|
|
89
|
+
for (let i = 0; i < newToOldSlice.length; i++) {
|
|
90
|
+
lines.push(` ${i + 1}. ${newToOldSlice[i]}`);
|
|
86
91
|
}
|
|
87
92
|
}
|
|
88
93
|
return lines.join("\n");
|
package/dist/keyboard.js
CHANGED
|
@@ -48,12 +48,12 @@ for (const seq of Object.keys(KEYMAP)) {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
class Keyboard extends events_1.EventEmitter {
|
|
51
|
-
constructor() {
|
|
52
|
-
super(
|
|
51
|
+
constructor(stdin = process.stdin) {
|
|
52
|
+
super();
|
|
53
53
|
this.capturing = false;
|
|
54
54
|
this.buffer = '';
|
|
55
|
-
this.stdin = process.stdin;
|
|
56
55
|
this.onData = (data) => this.handleData(data);
|
|
56
|
+
this.stdin = stdin;
|
|
57
57
|
}
|
|
58
58
|
enableCapture() {
|
|
59
59
|
if (this.capturing)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "caroushell",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.20",
|
|
4
4
|
"description": "Terminal carousel that suggests commands from history, config, and AI.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"build": "tsc -p tsconfig.release.json",
|
|
18
18
|
"prepare": "npm run build",
|
|
19
19
|
"start": "node dist/main.js",
|
|
20
|
+
"test": "node --import tsx --test tests/*.ts",
|
|
20
21
|
"test:generate": "tsx src/test-generate.ts",
|
|
21
22
|
"lint": "eslint . --ext .ts",
|
|
22
23
|
"release": "tsx scripts/release.ts"
|