# Mercury Toolbox V2 Design ## Goal Promote the repository from a generic AI-friendly CLI toolbox into the formally named `Mercury Toolbox` / `水星工具箱`, add four new high-leverage commands for search-to-context, diagnostics, log reduction, and binary string triage, and ship a first-class Windows + PowerShell installation path that automatically places the toolbox on the user PATH. ## Scope - Rename the toolbox brand in repository-level docs, workspace metadata, install-facing text, and user help from the generic placeholder wording to `Mercury Toolbox` / `水星工具箱`. - Add four new commands: - `hitsnip` - `diagpick` - `logshape` - `stringscan` - Keep natural binary names such as `snip`, `outline`, `hitsnip`, and `diagpick`; do not introduce a global binary prefix. - Add a user-facing PowerShell installer that: - builds the workspace release binaries - installs all toolbox binaries into `$env:LOCALAPPDATA\MercuryToolbox\bin` - automatically adds that directory to the user PATH if missing - reports what changed and how to verify the install - Add a complementary uninstall path and installation documentation. - Preserve the shared CLI contract: - compact ASCII text output by default - `--json` for machine consumption - PowerShell-friendly stdin behavior - stable exit code mapping ## Non-Goals - No GUI, TUI, or long-running background service. - No package publishing, Scoop bucket, installer EXE, or code signing in this iteration. - No heavyweight parser stack such as tree-sitter, Roslyn, or full symbol servers. - No single “master” control binary; the toolbox remains a workspace of small independent commands. ## Product Direction The existing toolbox already covers “find a file”, “probe the environment”, and “read a known target”. The new batch fills the remaining gaps that are especially painful for AI-assisted terminal workflows: - `hitsnip` answers “I already have search hits; now give me the smallest useful context.” - `diagpick` answers “this compiler or runtime log is noisy; show me the actionable diagnostics.” - `logshape` answers “this log is too repetitive; summarize the patterns before I read it.” - `stringscan` answers “this binary or generated blob is opaque; show me the strings that reveal identity, runtime, and ecosystem.” The installation work is part of the feature set, not a side quest. A toolbox that is annoying to install has near-zero real-world value even if the commands are good. ## Branding And Naming ### Repository Name - Primary English name: `Mercury Toolbox` - Primary Chinese name: `水星工具箱` - Documentation should treat these as the formal product name, not as aliases for the old placeholder wording. ### Binary Names - Keep natural command names: - `jsonlgrep` - `recent` - `pathshadow` - `portping` - `binmeta` - `fileprobe` - `outline` - `snip` - `chunkcat` - `hitsnip` - `diagpick` - `logshape` - `stringscan` - Do not add `mercury-` prefixes. - The installer owns product-level grouping; the binaries stay small and task-specific. ## Installation Design ### Main Installation Path - Add `scripts/install-toolbox.ps1` - Default behavior: - verify `cargo` exists - run `cargo build --release --workspace` - collect all known toolbox executables from `target\release` - create `$env:LOCALAPPDATA\MercuryToolbox\bin` if needed - copy all toolbox executables into that directory - inspect the user PATH - append the install directory if missing - print a compact summary of installed commands and PATH status ### PATH Policy - PATH updates target the user-level environment variable, not machine-wide PATH. - The script should avoid duplicate path entries by normalizing path comparison. - Current-session PATH may also be patched so the commands are usable immediately after install without opening a new shell. ### Safety And UX - Support `-NoPathUpdate` for explicit opt-out. - Support `-InstallRoot ` for advanced/manual installs, while defaulting to `$env:LOCALAPPDATA\MercuryToolbox`. - Support `-Configuration Debug|Release`, defaulting to `Release`. - Text output should clearly distinguish: - install root - bin directory - copied binaries - whether PATH was already configured, updated, or skipped ### Uninstall Path - Add `scripts/uninstall-toolbox.ps1` - Default behavior: - remove installed binaries from the Mercury Toolbox bin directory - remove the Mercury Toolbox bin directory from the user PATH when present - leave unrelated files untouched ### Fallback Installation Path - README also documents manual per-command install via `cargo install --path crates/`. - This is a fallback path for Rust-native users, not the primary recommendation. ## Command Designs ### `hitsnip` #### Purpose Convert search hits into deduplicated, compact context windows so neither humans nor AI have to manually reopen each hit. #### Inputs - Explicit files plus line references in one of these forms: - `path:line` - `path:line:column` - stdin text from tools such as `rg -n` - JSONL hit records with at least `path` and `line` #### Output - Text mode: - one header per merged snippet - numbered lines under each snippet - compact reason metadata such as hit count and merged line span - JSON mode: - one JSON array of snippet objects - fields: - `path` - `start_line` - `end_line` - `hit_lines` - `hit_count` - `lines` #### Behavior - Merge nearby hits in the same file when the distance between hit windows is at most `--max-gap`. - Expand each hit by `--context` lines. - Deduplicate repeated identical hit lines. - Ignore malformed lines with clear usage/runtime errors rather than panicking. #### Key Flags - `--context ` - `--max-gap ` - `--limit ` - `--input-format auto|lines|jsonl` - shared `--json` ### `diagpick` #### Purpose Extract actionable diagnostics from compiler, build, and runtime logs and optionally attach source context. #### Inputs - Plain text logs from stdin or files - JSONL records with fields such as `path`, `line`, `column`, `severity`, `message` #### Recognized Text Patterns - Rust diagnostics: - `error[E0425]: ...` - `--> path:line:column` - MSVC/C#/Unity-style: - `path(line,column): error CSxxxx: ...` - `path:line:column: error: ...` - Generic runtime stack/log references where a path and line are present #### Output - Text mode: - one compact record per diagnostic - optional source snippet below when `--with-source` is enabled - JSON mode: - array of diagnostics with stable fields: - `path` - `line` - `column` - `severity` - `code` - `message` - `source` - `tool_hint` #### Key Flags - `--with-source` - `--context ` - `--limit ` - `--severity error|warning|note|all` ### `logshape` #### Purpose Collapse repetitive logs into pattern groups before anyone spends tokens reading the raw stream. #### Inputs - Plain log lines from stdin or files #### Heuristic Normalization - Replace volatile fragments with placeholders: - timestamps - decimal and hex numbers - UUID-like tokens - long paths and addresses - Preserve level-like prefixes such as `INFO`, `WARN`, `ERROR` when possible #### Output - Text mode: - one compact line per template - includes count and a representative sample - JSON mode: - array of groups with fields: - `pattern` - `count` - `first_line` - `last_line` - `sample` #### Key Flags - `--top ` - `--min-count ` - `--show-samples` - `--keep-level` ### `stringscan` #### Purpose Expose the high-signal strings inside binaries, generated files, and opaque artifacts for reverse engineering and quick triage. #### Inputs - One or more file paths from argv or stdin #### Output - Text mode: - one compact summary line per file in summary mode - optional per-string output when filtering by category - JSON mode: - per-file reports with: - `path` - `is_binary` - `string_count` - `categories` - `matches` #### Heuristic Categories - `url` - `path` - `dll` - `namespace` - `unity` - `dotnet` - `il2cpp` - `bepinex` - `generic` #### Key Flags - `--min-len ` - `--kind all|url|path|dll|namespace|unity|dotnet|il2cpp|bepinex|generic` - `--unique` - `--limit ` - `--details` ## Shared Fixtures Add fixtures that support these commands without introducing heavyweight dependencies: - `fixtures/hits/rg-output.txt` - `fixtures/diag/rust-errors.txt` - `fixtures/diag/unity-errors.txt` - `fixtures/logs/repetitive.log` - `fixtures/binaries/stringscan-sample.bin` The binary fixture should embed obvious markers such as URLs, DLL names, Unity namespace fragments, and BepInEx-like strings so category detection can be tested reliably. ## Testing Strategy - Unit tests: - hit parsing and merge planning for `hitsnip` - diagnostic parsing helpers for `diagpick` - normalization and grouping for `logshape` - string extraction and category heuristics for `stringscan` - installer path normalization and PATH edit helpers - Integration tests: - `--help` examples for all new binaries - PowerShell pipeline flows - JSON output shape - install/uninstall script dry-run or temp-root behavior - Verification gates stay under the existing Jade standard, including `check-jade.ps1`. ## Risks - Search-hit parsing can get messy when input mixes drive-letter paths and colon-separated line syntax. - Prefer a path-aware parser that handles Windows drive prefixes before splitting on the final line/column segments. - Diagnostic parsers can drift when tools change exact wording. - Keep the patterns heuristic and additive rather than pretending to be a full parser for each toolchain. - Over-normalizing logs can merge meaningfully different failures. - Keep the normalization rule set conservative in v1. - Binary string scanning can explode in output volume. - Default to concise summaries and require explicit detail flags for large per-string dumps. - PATH editing is user-hostile if it duplicates entries or stomps unrelated content. - Use minimal, append-only edits with idempotent detection.