@lzhzzzzwill/cofos 1.2.1 → 1.2.2

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.
Files changed (2) hide show
  1. package/bin/cofos.js +55 -24
  2. 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: true,
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: true,
195
+ mouse: false,
196
196
  border: { type: "line" },
197
197
  label: " cofos ",
198
198
  style: {
@@ -207,6 +207,8 @@ function createTui() {
207
207
 
208
208
  let buffer = "";
209
209
  let onSubmit = () => {};
210
+ let suggestionMatches = [];
211
+ let selectedSuggestion = 0;
210
212
 
211
213
  function append(text = "") {
212
214
  const data = String(text).replace(/\x1b\[[0-9;]*[A-Za-z]/g, "");
@@ -226,31 +228,48 @@ function createTui() {
226
228
  }
227
229
 
228
230
  function hideSuggestions() {
231
+ suggestionMatches = [];
232
+ selectedSuggestion = 0;
229
233
  if (!suggestions.hidden) {
230
234
  suggestions.hide();
231
235
  screen.render();
232
236
  }
233
237
  }
234
238
 
235
- function updateSuggestions() {
236
- const value = input.getValue() || "";
237
- if (!value.startsWith("/")) {
239
+ function renderSuggestions() {
240
+ if (!suggestionMatches.length) {
238
241
  hideSuggestions();
239
242
  return;
240
243
  }
241
- const matches = slashMatches(value);
242
- if (!matches.length) {
244
+ selectedSuggestion = Math.max(0, Math.min(selectedSuggestion, suggestionMatches.length - 1));
245
+ suggestions.setContent(suggestionMatches.map(({ cmd, desc }, i) => {
246
+ const marker = i === selectedSuggestion ? "{black-fg}{yellow-bg}›" : " ";
247
+ const close = i === selectedSuggestion ? "{/yellow-bg}{/black-fg}" : "";
248
+ return `${marker} {cyan-fg}${cmd}{/cyan-fg} ${desc}${close}`;
249
+ }).join("\n"));
250
+ suggestions.height = Math.min(8, suggestionMatches.length + 2);
251
+ suggestions.show();
252
+ screen.render();
253
+ }
254
+
255
+ function updateSuggestions() {
256
+ const value = input.getValue() || "";
257
+ if (!value.startsWith("/")) {
243
258
  hideSuggestions();
244
259
  return;
245
260
  }
246
- suggestions.setContent(matches.map(({ cmd, desc }) => `{cyan-fg}${cmd}{/cyan-fg} ${desc}`).join("\n"));
247
- suggestions.height = Math.min(8, matches.length + 2);
248
- suggestions.show();
249
- screen.render();
261
+ suggestionMatches = slashMatches(value);
262
+ selectedSuggestion = 0;
263
+ renderSuggestions();
264
+ }
265
+
266
+ function selectedCommand() {
267
+ return suggestionMatches[selectedSuggestion]?.cmd || "";
250
268
  }
251
269
 
252
270
  function submitInput() {
253
- const value = input.getValue();
271
+ let value = input.getValue();
272
+ if (!suggestions.hidden && selectedCommand()) value = selectedCommand();
254
273
  hideSuggestions();
255
274
  input.clearValue();
256
275
  input.focus();
@@ -260,21 +279,32 @@ function createTui() {
260
279
 
261
280
  input.key(["enter"], submitInput);
262
281
 
263
- input.on("keypress", () => setTimeout(updateSuggestions, 0));
282
+ input.on("keypress", (_ch, key = {}) => {
283
+ if (["up", "down", "tab", "enter", "escape"].includes(key.name)) return;
284
+ setTimeout(updateSuggestions, 0);
285
+ });
264
286
 
265
287
  screen.key(["tab"], () => {
266
288
  const value = input.getValue() || "";
267
289
  if (!value.startsWith("/")) return;
268
- const matches = slashMatches(value);
269
- if (!matches.length) return;
270
- if (matches.length === 1) {
271
- input.setValue(matches[0].cmd);
272
- hideSuggestions();
273
- input.focus();
274
- screen.render();
275
- return;
276
- }
277
- updateSuggestions();
290
+ if (!suggestionMatches.length) suggestionMatches = slashMatches(value);
291
+ if (!suggestionMatches.length) return;
292
+ input.setValue(selectedCommand());
293
+ hideSuggestions();
294
+ input.focus();
295
+ screen.render();
296
+ });
297
+
298
+ screen.key(["up"], () => {
299
+ if (suggestions.hidden || !suggestionMatches.length) return;
300
+ selectedSuggestion = (selectedSuggestion - 1 + suggestionMatches.length) % suggestionMatches.length;
301
+ renderSuggestions();
302
+ });
303
+
304
+ screen.key(["down"], () => {
305
+ if (suggestions.hidden || !suggestionMatches.length) return;
306
+ selectedSuggestion = (selectedSuggestion + 1) % suggestionMatches.length;
307
+ renderSuggestions();
278
308
  });
279
309
 
280
310
  screen.key(["escape"], hideSuggestions);
@@ -449,7 +479,7 @@ function main() {
449
479
  return false;
450
480
  }
451
481
 
452
- ui.print(G + " you " + R + input);
482
+ ui.print(Y + "● You" + R + "\n" + input);
453
483
  responseOpen = false;
454
484
  generating = true;
455
485
  proc.stdin.write(input + "\n");
@@ -487,6 +517,7 @@ function main() {
487
517
  buf = buf.slice(ri + RESPONSE.length);
488
518
  if (buf[0] === "\n") buf = buf.slice(1);
489
519
  responseOpen = true;
520
+ ui.append(GR + "◆ COFOS" + R + "\n");
490
521
  }
491
522
 
492
523
  const di = buf.indexOf(DONE);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lzhzzzzwill/cofos",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "COFOS 9B + RAG chat CLI with optional local PDF ingestion.",
5
5
  "type": "module",
6
6
  "bin": {