Skip to content

feat: replace JLine with TamboUI for dependency search TUI#2465

Draft
maxandersen wants to merge 4 commits into
jbangdev:mainfrom
maxandersen:aesh-tamboui
Draft

feat: replace JLine with TamboUI for dependency search TUI#2465
maxandersen wants to merge 4 commits into
jbangdev:mainfrom
maxandersen:aesh-tamboui

Conversation

@maxandersen
Copy link
Copy Markdown
Collaborator

Summary

Replace JLine with TamboUI for the jbang deps search interactive TUI.

Draft PR — built on top of #2453 (aesh migration). Should be merged after #2453. Also requires TamboUI 0.4.0-SNAPSHOT with aesh 3.7 alignment (tamboui PR #344).

Changes

Dependencies

  • Remove jline-console-ui, jline-terminal-jni
  • Add tamboui-toolkit:0.4.0-SNAPSHOT, tamboui-aesh-backend:0.4.0-SNAPSHOT
  • Net jar size delta: +33KB

TUI rewrite (ArtifactSearchWidget)

  • Layout: dock() with search input (top), scrollable results list (center), details + help bar (bottom)
  • Async Central search: runs on scheduler thread via runner.schedule(), results marshalled back with runOnRenderThread(), generation counter discards stale results
  • Match highlighting: all result rows show matched characters (green+bold) using SearchFuzzedResult.highlightTarget()
  • Version picker: side pane appears on Enter, Esc goes back
  • Deduplication: results grouped by groupId:artifactId, showing best-scored version
  • Offline support: respects existing --offline / -o flag via Util.isOffline()

Search intent classifier (SearchIntentClassifier)

Classifies user input to route to the best Central query:

Input Intent Central Query
jackson databind KEYWORD jackson databind
ObjectMapper SIMPLE_CLASS c:ObjectMapper
com.fasterxml.jackson.databind.ObjectMapper FQCN fc:com.fasterxml...
import com.fasterxml...ObjectMapper; JAVA_IMPORT fc:com.fasterxml...
error: package org.jsoup does not exist PACKAGE_ERROR org.jsoup
com.fasterxml:jackson-databind:2.20.0 EXACT_GAV pass-through
  • Auto-triggers Central search (400ms debounce) for class/import/error intents
  • 19 unit tests

Key bindings

  • Tab/F5: search Maven Central
  • Enter: select artifact → pick version → done
  • Esc: clear search (or quit if empty)
  • Custom bindings unbind Tab from focus cycling and q/Q from quit

Removed

  • ComboBox.java (JLine widget)
  • All JLine imports and dependencies

Dependencies

stalep and others added 4 commits May 15, 2026 15:52
Migrate jbang's CLI framework from picocli to aesh, leveraging aesh's
compile-time annotation processor to eliminate runtime reflection and
improve startup performance.

Key changes:
- Replace all picocli annotations (@command, @option, @parameters) with
  aesh equivalents (@CommandDefinition, @GroupCommandDefinition, @option,
  @argument, @arguments, @OptionList, @OptionGroup, @mixin)
- Convert Callable<Integer> commands to Command<CommandInvocation> with
  CommandResult return type
- Port custom type converters, parameter consumers, and preprocessors to
  aesh Converter and OptionParser interfaces
- Implement external plugin command discovery in help output
- Add default value provider using aesh's post-parse processing
- Wire mutual exclusion validation via aesh's exclusiveWith
- Restore version checking, dynamic completion, option aliases, negatable
  options, and grouped help sections
- Regenerate native-image configuration for aesh
- Update tests for aesh CLI parsing

Performance (vs picocli, median):
- Native image: 6ms vs 33ms (5.5x faster) for single commands
- JDK 25: 109ms vs 228ms (2.1x faster)
- JDK 11: 149ms vs 269ms (1.8x faster)
Replace the picocli-based genadoc.java (934 lines) with an aesh-based
version (~300 lines) that generates the same asciidoc man page format.
Uses aesh's ProcessedCommand/ProcessedOption API to traverse the
command tree and extract metadata.

Generates 63 pages with proper jbang- prefixed names, hierarchical
nav.adoc, and tagged sections matching the existing format.
- Cache: fix groovyc cache toggle using wrong variable (kotlincs
  instead of groovys) — --groovyc flag was silently broken
- Config: fix typo "removed from in" → "removed from"
- RunMixin: serialize --jfr with = format for StrictOptionParser
- RunMixin: serialize --no-cds when explicitly set to false
- RunMixin: don't serialize javaagent value as "null" for valueless entries
- Alias: use LinkedHashMap in groupingBy to preserve sort order
- Replace JLine (jline-console-ui, jline-terminal-jni) with TamboUI
  (tamboui-toolkit, tamboui-aesh-backend) 0.4.0-SNAPSHOT
- Rewrite ArtifactSearchWidget using TamboUI toolkit DSL
  - dock() layout: search input (top), results (center), details+help (bottom)
  - Async Central search via runner.schedule() + runOnRenderThread()
  - Match highlighting on all result rows using SearchFuzzedResult
  - Version picker as side pane (Enter on artifact)
  - Deduplicate results by groupId:artifactId
- Add SearchIntentClassifier: detects GAV, class name, FQCN, Java import,
  compiler error, keyword — routes to appropriate Central query (c:/fc:/etc)
  - Auto-triggers Central search with 400ms debounce for class/import intents
- Support --offline flag (reuses existing BaseCommand.offline via Util)
- Remove JLine dependencies and ComboBox.java
- Custom key bindings: unbind Tab/focusNext so Tab triggers Central search,
  unbind q/Q from quit to allow typing in search
- Net jar size delta: +33KB
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 16, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1266bf27-24f2-4943-930b-d0ec04d0129a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Comment @coderabbitai help to get the list of available commands and usage tips.

@quintesse
Copy link
Copy Markdown
Contributor

Why is this PR so big and has many changes that seem to have nothing to do with a change to Tamboui?

@maxandersen
Copy link
Copy Markdown
Collaborator Author

@quintesse its dependent on #2453 so it has all those changes too. so looks much bigger than it is.

More correct is just looking at e233cbd (this PR)

For now still just a draft - wanting to see if full build had any challenges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants