feat(cli): ProjectDiscovery-style UX — banner, colored logs, braille spinner, styled tables#26
Conversation
…spinner, styled tables Agent-Logs-Url: https://github.com/root-Manas/macaron/sessions/6dea78af-da78-401a-9db1-1beab80801a7 Co-authored-by: root-Manas <97402139+root-Manas@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR updates macaron’s CLI user experience to match ProjectDiscovery-style tooling by adding a startup banner, colored log helpers, a braille-based live spinner renderer, and consistently styled/colored tables across app outputs.
Changes:
- Add a new
internal/cliuibanner + colored log helper module and integrate it across CLI flows. - Update live scan progress rendering to use a braille spinner and structured stage/badge formatting.
- Style all rendered tables with a shared rounded style and color-emphasized cells (e.g., live/vuln counts).
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Updates documentation/examples to reflect the new CLI UX and compact flags. |
| internal/cliui/banner.go | Introduces banner rendering, colored log helpers, and color utility functions. |
| internal/cliui/live.go | Updates live progress UI (braille spinner, badge formatting, clearer line formatting). |
| internal/app/app.go | Applies a consistent table style and adds color emphasis to key fields. |
| cmd/macaron/main.go | Adds -nc, integrates banner/log helpers, rewrites help/guide output, and updates command output formatting. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
|
|
||
| if showVersion { | ||
| cliui.PrintBanner(version, false) |
There was a problem hiding this comment.
-qut (quiet) is parsed before this block, but showVersion always calls PrintBanner(version, false), so macaron -ver -qut will still print the banner. Consider passing quiet through (or explicitly documenting that -ver ignores quiet).
| cliui.PrintBanner(version, false) | |
| cliui.PrintBanner(version, quiet) |
| b := cliui.Highlight | ||
| m := cliui.Muted | ||
|
|
||
| cliui.PrintBanner(version, false) |
There was a problem hiding this comment.
printHelp() forces the banner on via PrintBanner(version, false), so running with -qut (or calling help in scripted contexts) still emits the banner. This contradicts the flag description "Quiet output (no banner, no progress)"; consider threading quiet into printHelp() and honoring it here.
| cliui.PrintBanner(version, false) | |
| quiet := false | |
| for _, arg := range os.Args[1:] { | |
| switch arg { | |
| case "-qut", "--qut", "-quiet", "--quiet": | |
| quiet = true | |
| } | |
| if quiet { | |
| break | |
| } | |
| } | |
| if !quiet { | |
| cliui.PrintBanner(version, false) | |
| } |
| r.printLinef("%s [%s] %s %s %s %s", | ||
| r.ok("OK "), | ||
| r.stageLabel(ev.Stage), |
There was a problem hiding this comment.
r.ok("OK ") includes a trailing space. In no-color mode, badge() returns "["+v+"]" without trimming, which will render as [OK ] (note the extra space). Either remove the trailing space at the call sites or trim in the no-color branch to keep output consistent.
| // Highlight wraps v in bold white. | ||
| func Highlight(v string) string { | ||
| return cp(cBold, v) | ||
| } | ||
|
|
||
| // Muted wraps v in dim white. |
There was a problem hiding this comment.
The comments for Highlight/Muted say they wrap text in "bold white" / "dim white", but the implementation only applies cBold/cDim (no foreground color). Either update the comments to match what the functions actually do, or include an explicit white/gray foreground code in the style.
| // Highlight wraps v in bold white. | |
| func Highlight(v string) string { | |
| return cp(cBold, v) | |
| } | |
| // Muted wraps v in dim white. | |
| // Highlight wraps v in bold. | |
| func Highlight(v string) string { | |
| return cp(cBold, v) | |
| } | |
| // Muted wraps v in dim. |
| if rate <= 0 { | ||
| fmt.Fprintln(os.Stderr, "error: --rate must be > 0") | ||
| cliui.Err("--rte (rate) must be > 0") | ||
| return 1 | ||
| } | ||
| if threads <= 0 { | ||
| fmt.Fprintln(os.Stderr, "error: --threads must be > 0") | ||
| cliui.Err("--thr (threads) must be > 0") | ||
| return 1 |
There was a problem hiding this comment.
The new validation errors mention --rte / --thr, but the CLI UX/docs largely present these as -rte / -thr (and users may also pass --rate / --threads via the alias mapping). Consider wording the error as something like -rte/--rate must be > 0 to match the surfaced flag names.
Brings
macaron's CLI UX to parity with ProjectDiscovery tooling (nuclei, httpx, subfinder) — banner on startup, colored log levels, live braille spinner, and colored result tables.internal/cliui/banner.go(new)MACARONart + tagline/version header viaPrintBanner(version, quiet)Info(cyan[INF]),Warn(yellow[WRN]),Err(red[ERR]),OK(green[OK])Highlight,Muted,GreenText,RedText,YellowText,CyanText)NO_COLORenv var and new-ncflaginternal/cliui/live.go|/-\spinner for braille frames (⣾⣽⣻⣷⣯⣟⡿⢿) — same pattern as Nuclei/httpx⣾ example.com [subdomains] enumerating (4s)[SCAN],[RUN],[OK],[WRN]badgescmd/macaron/main.go-qutprintHelp()rewritten — grouped sections (USAGE / SCAN FLAGS / OUTPUT FLAGS / API KEYS / DASHBOARD / TOOLS & CONFIG / EXAMPLES), cyan flag names, muted descriptions[INF] Profile: balanced | mode: wide | stages: all | rate: 150 | threads: 30[OK] Completed 1 target(s) in 12.4s-lstshows✔ installed/✘ missingper toolfmt.Fprintf(os.Stderr, ...)replaced with typed log helpersinternal/app/app.gotable.StyleRounded+ cyan column headerstableStyle()helper for consistency acrossShowStatus,RenderSetup,RenderScanSummary