@lzhzzzzwill/cofos 1.2.1 → 1.2.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/bin/cofos.js +89 -26
- package/package.json +1 -1
package/bin/cofos.js
CHANGED
|
@@ -169,7 +169,7 @@ function createTui() {
|
|
|
169
169
|
alwaysScroll: true,
|
|
170
170
|
keys: true,
|
|
171
171
|
vi: true,
|
|
172
|
-
mouse:
|
|
172
|
+
mouse: false,
|
|
173
173
|
tags: false,
|
|
174
174
|
scrollbar: { ch: " ", track: { bg: "black" }, style: { bg: "cyan" } },
|
|
175
175
|
});
|
|
@@ -192,7 +192,7 @@ function createTui() {
|
|
|
192
192
|
height: 3,
|
|
193
193
|
inputOnFocus: true,
|
|
194
194
|
keys: true,
|
|
195
|
-
mouse:
|
|
195
|
+
mouse: false,
|
|
196
196
|
border: { type: "line" },
|
|
197
197
|
label: " cofos ",
|
|
198
198
|
style: {
|
|
@@ -207,6 +207,10 @@ function createTui() {
|
|
|
207
207
|
|
|
208
208
|
let buffer = "";
|
|
209
209
|
let onSubmit = () => {};
|
|
210
|
+
let onExit = () => {};
|
|
211
|
+
let submitting = false;
|
|
212
|
+
let suggestionMatches = [];
|
|
213
|
+
let selectedSuggestion = 0;
|
|
210
214
|
|
|
211
215
|
function append(text = "") {
|
|
212
216
|
const data = String(text).replace(/\x1b\[[0-9;]*[A-Za-z]/g, "");
|
|
@@ -226,59 +230,91 @@ function createTui() {
|
|
|
226
230
|
}
|
|
227
231
|
|
|
228
232
|
function hideSuggestions() {
|
|
233
|
+
suggestionMatches = [];
|
|
234
|
+
selectedSuggestion = 0;
|
|
229
235
|
if (!suggestions.hidden) {
|
|
230
236
|
suggestions.hide();
|
|
231
237
|
screen.render();
|
|
232
238
|
}
|
|
233
239
|
}
|
|
234
240
|
|
|
235
|
-
function
|
|
236
|
-
|
|
237
|
-
if (!value.startsWith("/")) {
|
|
241
|
+
function renderSuggestions() {
|
|
242
|
+
if (!suggestionMatches.length) {
|
|
238
243
|
hideSuggestions();
|
|
239
244
|
return;
|
|
240
245
|
}
|
|
241
|
-
|
|
242
|
-
|
|
246
|
+
selectedSuggestion = Math.max(0, Math.min(selectedSuggestion, suggestionMatches.length - 1));
|
|
247
|
+
suggestions.setContent(suggestionMatches.map(({ cmd, desc }, i) => {
|
|
248
|
+
const marker = i === selectedSuggestion ? "{black-fg}{yellow-bg}›" : " ";
|
|
249
|
+
const close = i === selectedSuggestion ? "{/yellow-bg}{/black-fg}" : "";
|
|
250
|
+
return `${marker} {cyan-fg}${cmd}{/cyan-fg} ${desc}${close}`;
|
|
251
|
+
}).join("\n"));
|
|
252
|
+
suggestions.height = Math.min(8, suggestionMatches.length + 2);
|
|
253
|
+
suggestions.show();
|
|
254
|
+
screen.render();
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function updateSuggestions() {
|
|
258
|
+
const value = input.getValue() || "";
|
|
259
|
+
if (!value.startsWith("/")) {
|
|
243
260
|
hideSuggestions();
|
|
244
261
|
return;
|
|
245
262
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
263
|
+
suggestionMatches = slashMatches(value);
|
|
264
|
+
selectedSuggestion = 0;
|
|
265
|
+
renderSuggestions();
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function selectedCommand() {
|
|
269
|
+
return suggestionMatches[selectedSuggestion]?.cmd || "";
|
|
250
270
|
}
|
|
251
271
|
|
|
252
272
|
function submitInput() {
|
|
253
|
-
|
|
273
|
+
if (submitting) return;
|
|
274
|
+
submitting = true;
|
|
275
|
+
let value = input.getValue();
|
|
276
|
+
if (!suggestions.hidden && selectedCommand()) value = selectedCommand();
|
|
254
277
|
hideSuggestions();
|
|
255
278
|
input.clearValue();
|
|
256
279
|
input.focus();
|
|
257
280
|
screen.render();
|
|
258
281
|
onSubmit(String(value || ""));
|
|
282
|
+
setTimeout(() => { submitting = false; }, 0);
|
|
259
283
|
}
|
|
260
284
|
|
|
261
285
|
input.key(["enter"], submitInput);
|
|
286
|
+
screen.key(["enter"], submitInput);
|
|
262
287
|
|
|
263
|
-
input.on("keypress", () =>
|
|
288
|
+
input.on("keypress", (_ch, key = {}) => {
|
|
289
|
+
if (["up", "down", "tab", "enter", "escape"].includes(key.name)) return;
|
|
290
|
+
setTimeout(updateSuggestions, 0);
|
|
291
|
+
});
|
|
264
292
|
|
|
265
293
|
screen.key(["tab"], () => {
|
|
266
294
|
const value = input.getValue() || "";
|
|
267
295
|
if (!value.startsWith("/")) return;
|
|
268
|
-
|
|
269
|
-
if (!
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
296
|
+
if (!suggestionMatches.length) suggestionMatches = slashMatches(value);
|
|
297
|
+
if (!suggestionMatches.length) return;
|
|
298
|
+
input.setValue(selectedCommand());
|
|
299
|
+
hideSuggestions();
|
|
300
|
+
input.focus();
|
|
301
|
+
screen.render();
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
screen.key(["up"], () => {
|
|
305
|
+
if (suggestions.hidden || !suggestionMatches.length) return;
|
|
306
|
+
selectedSuggestion = (selectedSuggestion - 1 + suggestionMatches.length) % suggestionMatches.length;
|
|
307
|
+
renderSuggestions();
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
screen.key(["down"], () => {
|
|
311
|
+
if (suggestions.hidden || !suggestionMatches.length) return;
|
|
312
|
+
selectedSuggestion = (selectedSuggestion + 1) % suggestionMatches.length;
|
|
313
|
+
renderSuggestions();
|
|
278
314
|
});
|
|
279
315
|
|
|
280
316
|
screen.key(["escape"], hideSuggestions);
|
|
281
|
-
screen.key(["C-c"], () =>
|
|
317
|
+
screen.key(["C-c"], () => onExit());
|
|
282
318
|
|
|
283
319
|
input.focus();
|
|
284
320
|
screen.render();
|
|
@@ -289,6 +325,8 @@ function createTui() {
|
|
|
289
325
|
append,
|
|
290
326
|
print: (text = "") => append(String(text) + "\n"),
|
|
291
327
|
setSubmitHandler: (fn) => { onSubmit = fn; },
|
|
328
|
+
setExitHandler: (fn) => { onExit = fn; },
|
|
329
|
+
focus: () => { input.focus(); screen.render(); },
|
|
292
330
|
setPrompt: (label) => { input.setLabel(` ${label} `); screen.render(); },
|
|
293
331
|
destroy: () => screen.destroy(),
|
|
294
332
|
};
|
|
@@ -393,7 +431,7 @@ function main() {
|
|
|
393
431
|
proc.stdout.setEncoding("utf-8");
|
|
394
432
|
proc.stderr.setEncoding("utf-8");
|
|
395
433
|
|
|
396
|
-
let buf = "", ready = false, generating = false, responseOpen = false, closed = false;
|
|
434
|
+
let buf = "", ready = false, generating = false, responseOpen = false, commandOpen = false, closed = false;
|
|
397
435
|
const inputQ = [];
|
|
398
436
|
let mlBuf = [];
|
|
399
437
|
|
|
@@ -405,6 +443,7 @@ function main() {
|
|
|
405
443
|
ui.destroy();
|
|
406
444
|
}
|
|
407
445
|
|
|
446
|
+
ui.setExitHandler(shutdown);
|
|
408
447
|
process.on("SIGTERM", shutdown);
|
|
409
448
|
process.on("SIGINT", shutdown);
|
|
410
449
|
|
|
@@ -440,6 +479,14 @@ function main() {
|
|
|
440
479
|
if (/^\/(clear)$/.test(input)) {
|
|
441
480
|
mlBuf = [];
|
|
442
481
|
responseOpen = false;
|
|
482
|
+
commandOpen = true;
|
|
483
|
+
proc.stdin.write(input + "\n");
|
|
484
|
+
generating = true;
|
|
485
|
+
return true;
|
|
486
|
+
}
|
|
487
|
+
if (/^\/(topk)(?:\s+\d+)?$/.test(input) || /^\/rag\s+(?:on|off)$/.test(input)) {
|
|
488
|
+
responseOpen = false;
|
|
489
|
+
commandOpen = true;
|
|
443
490
|
proc.stdin.write(input + "\n");
|
|
444
491
|
generating = true;
|
|
445
492
|
return true;
|
|
@@ -449,7 +496,7 @@ function main() {
|
|
|
449
496
|
return false;
|
|
450
497
|
}
|
|
451
498
|
|
|
452
|
-
ui.print(
|
|
499
|
+
ui.print(Y + "● " + R + input);
|
|
453
500
|
responseOpen = false;
|
|
454
501
|
generating = true;
|
|
455
502
|
proc.stdin.write(input + "\n");
|
|
@@ -477,6 +524,20 @@ function main() {
|
|
|
477
524
|
}
|
|
478
525
|
if (!generating) { buf = ""; return; }
|
|
479
526
|
|
|
527
|
+
if (commandOpen) {
|
|
528
|
+
const di = buf.indexOf(DONE);
|
|
529
|
+
if (di === -1) return;
|
|
530
|
+
const pre = buf.slice(0, di).trim();
|
|
531
|
+
if (pre) ui.print(G + "• " + R + pre);
|
|
532
|
+
buf = buf.slice(di + DONE.length);
|
|
533
|
+
if (buf[0] === "\n") buf = buf.slice(1);
|
|
534
|
+
generating = false;
|
|
535
|
+
commandOpen = false;
|
|
536
|
+
ui.focus();
|
|
537
|
+
drain();
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
|
|
480
541
|
if (!responseOpen) {
|
|
481
542
|
const ri = buf.indexOf(RESPONSE);
|
|
482
543
|
if (ri === -1) {
|
|
@@ -487,6 +548,7 @@ function main() {
|
|
|
487
548
|
buf = buf.slice(ri + RESPONSE.length);
|
|
488
549
|
if (buf[0] === "\n") buf = buf.slice(1);
|
|
489
550
|
responseOpen = true;
|
|
551
|
+
ui.append(GR + B + "◆ COFOS " + R);
|
|
490
552
|
}
|
|
491
553
|
|
|
492
554
|
const di = buf.indexOf(DONE);
|
|
@@ -498,6 +560,7 @@ function main() {
|
|
|
498
560
|
generating = false;
|
|
499
561
|
responseOpen = false;
|
|
500
562
|
ui.append("\n");
|
|
563
|
+
ui.focus();
|
|
501
564
|
drain();
|
|
502
565
|
} else {
|
|
503
566
|
const keep = DONE.length - 1;
|