Add tab-completion and persistent history to ac-cli shell

Use picocli-shell-jline3 to generate a completer from the command
tree, and explicitly save JLine history on exit so it persists
across sessions in ~/.agenticcode_history.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ingo Schnabel
2026-06-14 08:42:35 +02:00
parent 138569faff
commit 5ea36f7c4a
3 changed files with 40 additions and 22 deletions

View File

@@ -33,6 +33,10 @@
<groupId>org.jline</groupId>
<artifactId>jline</artifactId>
</dependency>
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli-shell-jline3</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>

View File

@@ -1,6 +1,7 @@
package com.agenticcode.cli;
import org.jline.reader.EndOfFileException;
import org.jline.reader.History;
import org.jline.reader.LineReader;
import org.jline.reader.LineReaderBuilder;
import org.jline.reader.ParsedLine;
@@ -10,6 +11,7 @@ import org.jline.reader.impl.history.DefaultHistory;
import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder;
import picocli.CommandLine;
import picocli.shell.jline3.PicocliCommands;
import java.io.IOException;
import java.nio.file.Path;
@@ -29,39 +31,45 @@ final class InteractiveShell {
int run() throws IOException {
try (Terminal terminal = TerminalBuilder.builder().build()) {
PicocliCommands picocliCommands = new PicocliCommands(commandLine);
LineReader reader = LineReaderBuilder.builder()
.terminal(terminal)
.parser(new DefaultParser())
.completer(picocliCommands.compileCompleters())
.appName("agenticcode")
.variable(LineReader.HISTORY_FILE, HISTORY_FILE)
.build();
new DefaultHistory(reader);
History history = new DefaultHistory(reader);
terminal.writer().println("AgenticCode interactive shell. Type 'help' for commands, 'exit' to quit.");
while (true) {
String line;
try {
line = reader.readLine("agenticcode> ").trim();
} catch (UserInterruptException e) {
continue;
} catch (EndOfFileException e) {
break;
}
try {
while (true) {
String line;
try {
line = reader.readLine("agenticcode> ").trim();
} catch (UserInterruptException e) {
continue;
} catch (EndOfFileException e) {
break;
}
if (line.isEmpty()) {
continue;
}
if (line.equals("exit") || line.equals("quit")) {
break;
}
if (line.equals("help") || line.equals("?")) {
commandLine.usage(terminal.writer());
continue;
}
if (line.isEmpty()) {
continue;
}
if (line.equals("exit") || line.equals("quit")) {
break;
}
if (line.equals("help") || line.equals("?")) {
commandLine.usage(terminal.writer());
continue;
}
ParsedLine parsed = reader.getParser().parse(line, line.length());
commandLine.execute(parsed.words().toArray(new String[0]));
ParsedLine parsed = reader.getParser().parse(line, line.length());
commandLine.execute(parsed.words().toArray(new String[0]));
}
} finally {
history.save();
}
}
return 0;

View File

@@ -111,6 +111,12 @@
<version>${picocli.version}</version>
</dependency>
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli-shell-jline3</artifactId>
<version>${picocli.version}</version>
</dependency>
<dependency>
<groupId>org.jline</groupId>
<artifactId>jline</artifactId>