From 6766526afc0264f2b943e3e7c55dbd6237eb9208 Mon Sep 17 00:00:00 2001 From: ffalcinelli Date: Mon, 13 Jul 2026 10:29:16 +0200 Subject: [PATCH 1/5] feat: collapse unified diffs, add interactive diff expansion, upgrade scaffolding UI to fuzzy matching and auto-discover realms, and update documentation --- AGENTS.md | 6 +- Cargo.lock | 19 ++++ Cargo.toml | 2 +- GEMINI.md | 16 ++++ README.md | 13 ++- docs/index.html | 21 ++-- src/args.rs | 8 ++ src/cli/client.rs | 4 +- src/cli/group.rs | 2 +- src/cli/idp.rs | 2 +- src/cli/keys.rs | 2 +- src/cli/mod.rs | 38 ++++++++ src/cli/role.rs | 2 +- src/cli/user.rs | 4 +- src/lib.rs | 12 ++- src/plan/components.rs | 36 +++++-- src/plan/generic.rs | 29 ++++-- src/plan/mod.rs | 81 ++++++++++++++-- src/plan/realm.rs | 9 +- src/utils/ui.rs | 12 ++- tests/cli_interactive_test.rs | 50 ++++++---- tests/plan_components_test.rs | 5 + tests/plan_coverage_test.rs | 163 ++++++++++++++++++++++++++++++-- tests/profile_test.rs | 1 + tests/run_app_test.rs | 2 + tests/ultimate_coverage_test.rs | 2 +- 26 files changed, 455 insertions(+), 86 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index d1b02a0..1d59da9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -22,14 +22,14 @@ All business logic is located in the `src/` directory: * [`src/client.rs`](src/client.rs): Wrapper around the Keycloak Admin REST API. Handles authentication and provides a **generic CRUD interface** for resources. * [`src/models.rs`](src/models.rs): Strongly-typed Serde representations of Keycloak resources. Implements the `KeycloakResource` and `ResourceMeta` traits. * [`src/inspect.rs`](src/inspect.rs): Scans the remote Keycloak instance and serializes resources into local workspace files using a parallelized pipeline. -* [`src/plan/`](src/plan/): Calculates diffs and writes the plan. Uses the generic planning engine in `generic.rs`. +* [`src/plan/`](src/plan/): Calculates diffs and writes the plan. Uses the generic planning engine in `generic.rs`. Supports collapsed unified diff formatting (3 context lines) by default, `--verbose` full diff view, and interactive expansion choices during confirmation. * [`src/apply/`](src/apply/): Reconciles resources. Uses the generic reconciliation engine in `generic.rs` and stage-specific modules. * [`src/validate.rs`](src/validate.rs): Validates local configurations against expected structures and constraints. * [`src/clean.rs`](src/clean.rs): Removes unreferenced or invalid configuration files from the workspace. -* [`src/cli/`](src/cli/): Interactive CLI scaffolding menu. +* [`src/cli/`](src/cli/): Interactive CLI scaffolding menu. Styled with `dialoguer`'s `ColorfulTheme` and uses `FuzzySelect` for real-time query filtering. Auto-discovers existing realms in the workspace directory. * [`src/utils/secrets/`](src/utils/secrets/): Manages secret resolution (Env, HashiCorp Vault). * [`src/utils/yaml.rs`](src/utils/yaml.rs): Handles YAML serialization, sorting, and profile-specific deep-merging. -* [`src/utils/ui.rs`](src/utils/ui.rs): CLI visual formatting, progress bars, emojis, and styling. +* [`src/utils/ui.rs`](src/utils/ui.rs): CLI visual formatting, progress bars, emojis, and styling. Contains DialoguerUi which maps console prompts to ColorfulTheme and FuzzySelect. --- diff --git a/Cargo.lock b/Cargo.lock index 9fc9a2c..42a64d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -447,6 +447,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25f104b501bf2364e78d0d3974cbc774f738f5865306ed128e1e0d7499c0ad96" dependencies = [ "console", + "fuzzy-matcher", "shell-words", "tempfile", "zeroize", @@ -656,6 +657,15 @@ dependencies = [ "slab", ] +[[package]] +name = "fuzzy-matcher" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94" +dependencies = [ + "thread_local", +] + [[package]] name = "getrandom" version = "0.2.17" @@ -1928,6 +1938,15 @@ dependencies = [ "syn", ] +[[package]] +name = "thread_local" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" +dependencies = [ + "cfg-if", +] + [[package]] name = "tinystr" version = "0.8.2" diff --git a/Cargo.toml b/Cargo.toml index fb24035..67bafc7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ similar = "2.7.0" async-trait = "0.1.86" async-recursion = "1.1.1" console = "0.16.3" -dialoguer = "0.12.0" +dialoguer = { version = "0.12.0", features = ["fuzzy-select"] } futures = "0.3.32" indicatif = "0.18.4" diff --git a/GEMINI.md b/GEMINI.md index 519adc8..507c616 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -84,6 +84,22 @@ To support a new Keycloak resource (e.g., "Event Listeners"): --- +## ๐Ÿ“บ Terminal UI & Diff Viewer Enhancements + +### 1. Minimal Unified Diffs (Collapsed by Default) +To reduce terminal clutter, `kaji plan` and `kaji drift` default to showing collapsed unified diffs (with 3 context lines around changes). A `--verbose` or `-v` flag allows users to output full file diffs. + +### 2. Interactive Diff Expansion +During `kaji plan --interactive`, the prompt is a selection menu with `Yes` (include change), `No` (skip change), and `Show Full Diff` (expand to full verbose diff). Selecting `Show Full Diff` displays the complete diff and prompts the user again. + +### 3. Styled Fuzzy Scaffolding Menu +The interactive menu (`kaji cli`) utilizes `dialoguer::theme::ColorfulTheme` for polished, colorful CLI prompts. It replaces standard selects with `dialoguer::FuzzySelect`, allowing users to type to search and filter options instantly. + +### 4. Workspace Realm Auto-Discovery +All scaffolding prompts dynamically scan the workspace to discover existing realms. The user is presented with a `FuzzySelect` list of discovered realms plus a `` option, avoiding manual typing for existing projects. + +--- + ## ๐Ÿงช Testing Strategy `kaji` employs a multi-layered testing strategy: diff --git a/README.md b/README.md index 528c9e5..e982a2a 100644 --- a/README.md +++ b/README.md @@ -230,12 +230,16 @@ kaji validate ``` ### `plan` -Calculates the "diff" between local files and the remote server. +Calculates the "diff" between local files and the remote server. By default, it shows a minimal, clean unified diff (collapsed with 3 lines of context). ```bash # Plan for a specific profile kaji plan --profile prod -# Interactive: decide for each change whether to include it in the plan +# Show full resource diffs instead of collapsed unified diffs +kaji plan --verbose + +# Interactive: decide for each change whether to include it. +# Prompts you with: Yes (include), No (skip), Show Full Diff (to expand) kaji plan --interactive ``` @@ -250,9 +254,12 @@ kaji apply --profile prod --review ``` ### `drift` -A shortcut for `plan --changes-only`. +A shortcut for `plan --changes-only`. By default, it prints collapsed unified diffs. ```bash kaji drift --profile prod + +# Show full resource diffs for configuration drift +kaji drift --verbose ``` ### `clean` diff --git a/docs/index.html b/docs/index.html index 4aeafb5..ea4fe74 100644 --- a/docs/index.html +++ b/docs/index.html @@ -79,18 +79,19 @@

kaji plan
$ kaji plan --interactive
-// Calculating diff for realm 'master'...
+๐Ÿš€ Planning changes for realm: master
 
-  Clients:
-    [+] my-new-app         Create
-    [~] admin-cli           Update
-        root_url: "http://localhost" → "https://idp.example.com"
-    [-] legacy-app          Delete
+๐Ÿ“ Changes for Client admin-cli:
+@@ -15,5 +15,5 @@
+   protocol: openid-connect
+-  rootUrl: "http://localhost"
++  rootUrl: "https://idp.example.com"
+   publicClient: false
 
-  Roles:
-    [+] billing-manager    Create
-
-? Apply change to client 'my-new-app'? 
+? Include this change in the plan? +> Yes + No + Show Full Diff