@tiens.nguyen/gonext-local-worker 1.0.207 → 1.0.209

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/gonext-repl.mjs +42 -10
  2. package/package.json +1 -1
package/gonext-repl.mjs CHANGED
@@ -159,8 +159,39 @@ if (!workerKey || !apiBase) {
159
159
  // editing didn't work at all (user-reported). Giving readline the prompt makes its
160
160
  // redraw math correct — rl.prompt() resets the cursor state after every burst of our
161
161
  // output — and raw mode means backspace/arrows/↑-history all behave like a normal shell.
162
+ // Single source of truth for the REPL's slash commands — drives Tab-completion, the
163
+ // unknown-command guard, and /help, so they can never drift.
164
+ const COMMANDS = [
165
+ { name: "/model", desc: "switch the coding model for this session" },
166
+ { name: "/revert", usage: "/revert [runId]", desc: "undo the agent's file edits (latest run)" },
167
+ { name: "/reset", aliases: ["/new"], desc: "forget this folder's saved conversation and start fresh" },
168
+ { name: "/help", desc: "list these commands" },
169
+ { name: "/exit", aliases: ["/quit"], desc: "quit" },
170
+ ];
171
+ const COMMAND_NAMES = COMMANDS.flatMap((c) => [c.name, ...(c.aliases ?? [])]);
172
+ // Tab-completion: when the line starts with "/", complete against the command names.
173
+ function slashCompleter(line) {
174
+ if (!line.startsWith("/")) return [[], line];
175
+ const hits = COMMAND_NAMES.filter((n) => n.startsWith(line));
176
+ return [hits.length ? hits : COMMAND_NAMES, line];
177
+ }
178
+ function printCommands() {
179
+ console.log(dim(" commands (type / then Tab to complete):"));
180
+ for (const c of COMMANDS) {
181
+ const label = c.usage ?? c.name;
182
+ const alias = c.aliases?.length ? dim(` (${c.aliases.join(", ")})`) : "";
183
+ console.log(` ${cyan(label)}${alias}${dim(" — " + c.desc)}`);
184
+ }
185
+ console.log("");
186
+ }
187
+
162
188
  const IS_TTY = Boolean(process.stdin.isTTY && process.stdout.isTTY);
163
- const rl = createInterface({ input: process.stdin, output: process.stdout, terminal: IS_TTY });
189
+ const rl = createInterface({
190
+ input: process.stdin,
191
+ output: process.stdout,
192
+ terminal: IS_TTY,
193
+ completer: slashCompleter,
194
+ });
164
195
  const PROMPT = cyan(">> ");
165
196
  rl.setPrompt(PROMPT);
166
197
  // Side effect of terminal:false above: readline no longer intercepts arrow keys for
@@ -916,7 +947,7 @@ async function main() {
916
947
  console.error(red(`gonext: ${err.message}`));
917
948
  process.exit(1);
918
949
  }
919
- console.log(dim("Ask about this repo, or /help. Ctrl-C aborts a running turn.\n"));
950
+ console.log(dim("Ask about this repo. Type / (or /help) to list commands — Tab completes. Ctrl-C aborts a running turn.\n"));
920
951
 
921
952
  const cwd = resolve(process.cwd());
922
953
  const history = await loadSession(cwd);
@@ -979,14 +1010,8 @@ async function main() {
979
1010
  if (lineRaw === null) break; // stdin closed
980
1011
  const line = lineRaw.trim();
981
1012
  if (line === "/exit" || line === "/quit") break;
982
- if (line === "/help") {
983
- console.log(
984
- dim(
985
- " /exit — quit · /model — switch the coding model for this session · " +
986
- "/revert [runId] — undo the agent's file edits (latest run) · " +
987
- "/reset — forget this folder's saved conversation and start fresh"
988
- )
989
- );
1013
+ if (line === "/" || line === "/help") {
1014
+ printCommands();
990
1015
  continue;
991
1016
  }
992
1017
  if (line === "/model") {
@@ -1012,6 +1037,13 @@ async function main() {
1012
1037
  });
1013
1038
  continue;
1014
1039
  }
1040
+ // Any OTHER "/…" is a typo/unknown command — don't send it to the agent as a
1041
+ // question; point the user at /help (all real commands were handled above).
1042
+ if (line.startsWith("/")) {
1043
+ const cmd = line.split(/\s+/)[0];
1044
+ console.log(dim(`unknown command: ${cmd} — type /help (or / then Tab) to list commands\n`));
1045
+ continue;
1046
+ }
1015
1047
  history.push({ role: "user", content: line });
1016
1048
  try {
1017
1049
  const { text: answer, shown, cancelled } = await runAgentTurn(history);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiens.nguyen/gonext-local-worker",
3
- "version": "1.0.207",
3
+ "version": "1.0.209",
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",