Migrate CLI from picocli to aesh with REPL console mode - #166
Draft
stalep wants to merge 9 commits into
Draft
Conversation
stalep
force-pushed
the
aesh
branch
3 times, most recently
from
August 5, 2026 14:44
f32ed5b to
22bf867
Compare
Replace the picocli-based single-command CLI with an aesh interactive
REPL (Read-Eval-Print Loop) shell. Users can now run multiple commands
in a single session with tab completion, history, and folder context.
Entity-centric command structure:
folder — add, list, remove, upload, export, import, structure,
recalculate, purge, values
node — add (jq/js/jsonata/sqlpath/sqlpathall/split/fixedthreshold/
relativedifference/stddev), list, remove, update
view — list, show, create, remove, update (--add/--remove/--reorder)
run — list, show, upload
notification — add, list, remove
legacy — load-tests, load-runs, verify
admin — create-user, create-team, add-member, list-users, list-teams,
create-api-key, list-api-keys, revoke-api-key
cd — set active folder context
upload — top-level shortcut for folder upload
Key features:
- Folder context: 'cd myFolder' sets context, subsequent commands omit --to/--from
- Tab completion for commands, folder names, and node names
- acceptNameWithoutDashes on all options (picocli-compatible syntax)
- @arguments for positional args matching original CLI syntax
- Default limit of 50 on list commands to prevent OOM
- Ctrl-C interrupt support (InterruptedException on all commands)
- generateHelp on all commands (--help shows usage)
- Views: create views, add/remove node columns, show pivoted data
- Runs: list uploads, show raw JSON data, per-node value inspection
- H5mCommandRegistryFactory filters top-level commands for clean tab completion
- Graceful startup recovery on SQLite (handles missing tables)
- Upload command awaits CompletableFuture completion before returning
- Uses aesh Table utility for formatted output
- NodeNameCompleter for node name tab completion in view/run commands
Rebase aesh branch on origin/main. Update Quarkus version from 999-SNAPSHOT to 3.38.0 with aesh 3.16.4. Fix Vert.x Buffer import changes (core → mutiny). Make CLI command fields package-private to avoid reflective access warnings. Convert remaining picocli commands to aesh: AddEDivisive, ListProcessing, RemoveProcessing, ResumeProcessing. Create standalone AddFingerprint command (replaces --fingerprint flag on AddJq/AddJs). Fix test command syntax (node jq → node add jq). Remove outdated null-value assertion for ephemeral-nullified intermediate nodes. RecalculateCmd placeholder — folder-level recalculate API was removed by PR Hyperfoil#210, needs reimplementation for CLI. Detection test failures remain — fingerprint and fixedthreshold nodes produce correct structure but detection values are not generated. Requires investigation into work queue completion in REPL test context.
Three root causes fixed: 1. Aesh @option with List<String> stays null — change fingerprint option from List<String> to String in AddFixedThreshold, AddRelativeDifference, and AddStdDevAnomaly. Split on commas in the command code instead. This was causing _fp-* fingerprint nodes to be created with empty sources, breaking the cascade chain (fp1 -> _fp-ftNode never triggered). 2. Aesh doesn't process backslash-escaped quotes inside double-quoted strings — update toCommand() to use single quotes for arguments containing double quotes (e.g., JQ expressions like .results."quarkus3-jvm".load.avThroughput). This was causing JQ compilation errors ('Unexpected character: backslash'). 3. Default display limit of 50 truncates QVSS test output — add --limit 200 to fixedthreshold_qvss_split_by_framework test. Also update upload test assertions: intermediate node values are ephemeral-nullified after processing (correct behavior). Tests now assert on leaf values only. All 483 non-CLI tests pass. CLI detection tests (fixedthreshold, relativedifference, stddev, QVSS throughput/split/regression) pass. Remaining CLI failures: upload_sqlpath (missing sqlpath command), and sporadic SQLite SQLITE_BUSY timeouts (pre-existing).
Switch fingerprint option from @option String to @OptionList List<String> in AddFixedThreshold, AddRelativeDifference, AddStdDevAnomaly, and AddEDivisive. @OptionList is the correct aesh annotation for multi-valued options — it handles both --fingerprint fp1 (single value) and --fingerprint fp1,fp2 (comma-separated) natively. Pin Quarkus version to 3.38.0 (ships aesh 3.16.4). Fix Vert.x Buffer imports in notification plugins (GitHubIssuePlugin, SlackPlugin, WebhookPlugin): io.vertx.core → io.vertx.mutiny.core.
Add 5 tests that simulate real user CLI workflow: cd into a folder then operate without specifying --to/--from explicitly. Tests cover: - cd + node add + upload + values (basic context flow) - cd + node add + node remove (context with node management) - cd + fixedthreshold + upload (detection nodes with context) - cd .. to exit folder context - cd + structure + recalculate (folder-level commands with context) Fix AddEDivisive: add missing folder context fallback. Every other node add command had 'if (groupName == null && invocation.hasFolderContext())' but AddEDivisive was missing it. Fix AddNotification: remove required=true on --to option. The required flag caused aesh to reject the command before execute() ran, making the folder context fallback code unreachable.
…ation
Critical fixes:
- AddSplit was a no-op: validated inputs but never called
nodeService.create(). Now actually creates the split node.
- UploadCmd and RunUploadCmd: add null check for path argument
to prevent NullPointerException.
- RemoveFolder: return FAILURE when folder is not found (was
returning SUCCESS). Also add null check for name argument.
RecalculateCmd reimplemented:
- Was a stub that printed 'not yet supported' and returned SUCCESS.
- Now iterates top-level nodes via NodeGroupServiceInterface and
calls folderService.recalculateNode() for each, waiting for all
CompletableFutures with a 10-minute timeout.
Help text and descriptions:
- NodeAddCmd: remove sqlpath/sqlpathall (don't exist), add
edivisive and fingerprint (do exist).
- NodeCmd: remove sqlpath from description.
Error message fixes:
- Replace 'NodeEntity group' with 'Node group' in ListNode and
ListValue (internal class name leak).
- Replace 'FolderEntity' with 'Folder' in RemoveFolder.
- Fix missing space in error messages in AddFixedThreshold and
AddRelativeDifference ('with name<value>' -> 'with name <value>').
RunUploadCmd was a full code duplicate of UploadCmd (identical logic, only the class name differed). Now extends UploadCmd with just its own @CommandDefinition. All fields, injection points, and execute() logic are inherited.
The Quarkus 3.38.0 BOM manages aesh-processor:3.16.4. Omitting the version from the annotationProcessorPaths entry lets Maven resolve it from the BOM, keeping the aesh version in sync with Quarkus automatically. No more manual version tracking needed.
UploadCmd improvements: - Print processing ID for each uploaded file (single file: 'Processing id: 42', directory: 'file.json -> processing id: 42') - Add --async flag: returns immediately without waiting for processing - Synchronous mode: after completion, queries ValueService.getDetectionDescendants() and displays detection summary with node name, type, details, and fingerprint New status command: - 'status 42' or 'status 42 43 44' checks processing state via WorkService.getTracker() - Returns PROCESSING, COMPLETED, FAILED, or 'not found' - Falls back to DB check (root value exists) when tracker is cleaned up New changes command: - 'changes 42' lists detection values for an upload via ValueService.getDetectionDescendants() - 'changes 42 --node throughput-regression' filters to a specific detection node - Formatted output with node name, detection type, key fields, and fingerprint Shared ChangeFormatter utility for consistent detection value display across UploadCmd and ChangesCmd.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replace the picocli-based single-command CLI with an aesh interactive REPL (Read-Eval-Print Loop) shell. Users can now run multiple commands in a single session with tab completion, history, and folder context.
Entity-centric command structure:
folder — add, list, remove, upload, export, import, structure,
recalculate, purge, values
node — add (jq/js/jsonata/sqlpath/sqlpathall/split/fixedthreshold/
relativedifference/stddev), list, remove, update
view — list, show, create, remove, update (--add/--remove/--reorder)
run — list, show, upload
notification — add, list, remove
legacy — load-tests, load-runs, verify
admin — create-user, create-team, add-member, list-users, list-teams,
create-api-key, list-api-keys, revoke-api-key
cd — set active folder context
upload — top-level shortcut for folder upload
Key features: