@tiens.nguyen/gonext-local-worker 1.0.210 → 1.0.211
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/gonext-repl.mjs +41 -18
- package/package.json +1 -1
package/gonext-repl.mjs
CHANGED
|
@@ -175,7 +175,7 @@ function slashCompleter(line) {
|
|
|
175
175
|
const hits = COMMAND_NAMES.filter((n) => n.startsWith(line));
|
|
176
176
|
return [hits.length ? hits : COMMAND_NAMES, line];
|
|
177
177
|
}
|
|
178
|
-
function
|
|
178
|
+
function commandRows(prefix = "") {
|
|
179
179
|
const p = (prefix ?? "").trim();
|
|
180
180
|
const show = COMMANDS.filter(
|
|
181
181
|
(c) =>
|
|
@@ -183,12 +183,18 @@ function printCommands(prefix = "") {
|
|
|
183
183
|
p === "/" ||
|
|
184
184
|
[c.name, ...(c.aliases ?? [])].some((n) => n.startsWith(p))
|
|
185
185
|
);
|
|
186
|
-
|
|
187
|
-
|
|
186
|
+
const list = show.length ? show : COMMANDS;
|
|
187
|
+
const rows = [dim(" commands (Tab completes):")];
|
|
188
|
+
for (const c of list) {
|
|
188
189
|
const label = c.usage ?? c.name;
|
|
189
190
|
const alias = c.aliases?.length ? dim(` (${c.aliases.join(", ")})`) : "";
|
|
190
|
-
|
|
191
|
+
rows.push(` ${cyan(label)}${alias}${dim(" — " + c.desc)}`);
|
|
191
192
|
}
|
|
193
|
+
return rows;
|
|
194
|
+
}
|
|
195
|
+
// Permanent print (used by /help and a lone-"/" submit — scrolls with history).
|
|
196
|
+
function printCommands(prefix = "") {
|
|
197
|
+
for (const r of commandRows(prefix)) console.log(r);
|
|
192
198
|
console.log("");
|
|
193
199
|
}
|
|
194
200
|
|
|
@@ -221,6 +227,7 @@ const isNetworkError = (e) =>
|
|
|
221
227
|
const _lineQueue = [];
|
|
222
228
|
let _lineWaiter = null;
|
|
223
229
|
let _stdinClosed = false;
|
|
230
|
+
let slashHintRows = 0; // live slash-command hint rows drawn below the prompt (0 = none)
|
|
224
231
|
rl.on("line", (l) => {
|
|
225
232
|
// While a turn is running, IGNORE typed input entirely — no type-ahead, no queued
|
|
226
233
|
// next question. Only Ctrl+C (handled via SIGINT) does anything mid-turn. Clear the
|
|
@@ -230,6 +237,12 @@ rl.on("line", (l) => {
|
|
|
230
237
|
rl.cursor = 0;
|
|
231
238
|
return;
|
|
232
239
|
}
|
|
240
|
+
// Enter left the cursor on the row where the live slash-hint started — erase it so the
|
|
241
|
+
// command's own output doesn't print over/under a stale hint block.
|
|
242
|
+
if (slashHintRows > 0) {
|
|
243
|
+
process.stdout.write("\x1b[J");
|
|
244
|
+
slashHintRows = 0;
|
|
245
|
+
}
|
|
233
246
|
const clean = stripAnsiEscapes(l);
|
|
234
247
|
if (_lineWaiter) {
|
|
235
248
|
const w = _lineWaiter;
|
|
@@ -243,7 +256,28 @@ rl.on("line", (l) => {
|
|
|
243
256
|
// turn: echo is already muted, but readline still recalls history into the invisible
|
|
244
257
|
// buffer on ↑/↓ — reset the line state after every keypress so nothing accumulates or
|
|
245
258
|
// moves. Ctrl+C is unaffected (readline emits its SIGINT before this handler runs).
|
|
246
|
-
|
|
259
|
+
// Live command hint = an EPHEMERAL overlay drawn BELOW the prompt while the line starts
|
|
260
|
+
// with "/", so it redraws as you type (narrowing) and DISAPPEARS when you clear the slash
|
|
261
|
+
// (instead of stacking permanent copies in scrollback). Rendered with relative cursor
|
|
262
|
+
// moves (down to draw, back up to the input line) so it survives terminal scrolling.
|
|
263
|
+
const inputCol = () => 4 + rl.cursor; // ">> " is 3 cols; content starts at col 4 (1-based)
|
|
264
|
+
function clearSlashHint() {
|
|
265
|
+
if (slashHintRows === 0) return;
|
|
266
|
+
// Cursor is on the input line. Drop into the hint region, erase to end of screen, return.
|
|
267
|
+
process.stdout.write("\n\x1b[J" + `\x1b[1A\x1b[${inputCol()}G`);
|
|
268
|
+
slashHintRows = 0;
|
|
269
|
+
}
|
|
270
|
+
function drawSlashHint(line) {
|
|
271
|
+
const rows = commandRows(line);
|
|
272
|
+
// Repaint in place: erase the old block, draw the new one, move the cursor back up.
|
|
273
|
+
const body = rows.map((r) => "\x1b[K" + r).join("\n");
|
|
274
|
+
let out = "";
|
|
275
|
+
if (slashHintRows > 0) out += "\n\x1b[J\x1b[1A"; // wipe previous block, back to input row
|
|
276
|
+
out += "\n" + body; // draw below the input line
|
|
277
|
+
out += `\x1b[${rows.length}A\x1b[${inputCol()}G`; // back up to the input line + column
|
|
278
|
+
process.stdout.write(out);
|
|
279
|
+
slashHintRows = rows.length;
|
|
280
|
+
}
|
|
247
281
|
if (process.stdin.isTTY) {
|
|
248
282
|
process.stdin.on("keypress", () => {
|
|
249
283
|
if (following) {
|
|
@@ -252,19 +286,8 @@ if (process.stdin.isTTY) {
|
|
|
252
286
|
rl.historyIndex = -1;
|
|
253
287
|
return;
|
|
254
288
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
// pressing Tab. Shown once per "/…" run; cleared/reset when the line stops being a
|
|
258
|
-
// slash command (so a fresh "/" shows it again).
|
|
259
|
-
const l = rl.line;
|
|
260
|
-
if (l.startsWith("/") && !slashHintShown) {
|
|
261
|
-
slashHintShown = true;
|
|
262
|
-
process.stdout.write("\r\x1b[K"); // wipe the ">> /" input row
|
|
263
|
-
printCommands(l); // list where the prompt was + below
|
|
264
|
-
rl._refreshLine(); // redraw ">> /" (with cursor) beneath the list
|
|
265
|
-
} else if (!l.startsWith("/")) {
|
|
266
|
-
slashHintShown = false;
|
|
267
|
-
}
|
|
289
|
+
if (rl.line.startsWith("/")) drawSlashHint(rl.line);
|
|
290
|
+
else clearSlashHint();
|
|
268
291
|
});
|
|
269
292
|
}
|
|
270
293
|
rl.on("close", () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiens.nguyen/gonext-local-worker",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.211",
|
|
4
4
|
"description": "Polls GoNext cloud API for async local LLM jobs and runs them against Ollama/OpenAI-compatible servers on this Mac",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|