feat: route ssh/scp (+ timeout wrapper) and add dedup_repeats TOML action#2948
Open
melchior123 wants to merge 2 commits into
Open
feat: route ssh/scp (+ timeout wrapper) and add dedup_repeats TOML action#2948melchior123 wants to merge 2 commits into
melchior123 wants to merge 2 commits into
Conversation
Adds a new `dedup_repeats` filter action that collapses consecutive identical lines into 'line [xN]', and wires up ssh/scp so the Claude Code / hook layer rewrites them to `rtk ssh` / `rtk scp`. Motivation: ssh is one of the highest-volume commands in agent sessions (remote diagnostics: journalctl, docker logs, dmesg), but it was never registered as a rewritable command, so its output bypassed RTK entirely. Log-like remote output is also highly repetitive, which the existing pipeline had no way to compress. Changes: - core/toml_filter.rs: new `dedup_repeats` bool action, applied as pipeline stage 4.5 (after strip/keep, before truncate). Collapses runs of identical lines (trailing whitespace ignored, blank lines never merged) into a ' [xN]' suffix. Non-lossy: the count preserves the information, so no tee fallback is triggered. - discover/rules.rs: register ^ssh\b -> rtk ssh and ^scp\b -> rtk scp. - filters/ssh.toml: enable dedup_repeats; strip additional connection noise (Last login, X11 forwarding request failed, shared connection closed). New inline test for the dedup path. - filters/scp.toml: new filter — strips banners/progress, keeps errors. All 2444 tests pass, clippy clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
timeout-wrapped commands ('timeout <N> ssh ...') bypassed all filters
because the command starts with 'timeout', not the inner command. Since
timeout takes a mandatory DURATION arg plus optional flags, it can't use
the fixed-word BUILTIN_TRANSPARENT_PREFIXES path.
Adds strip_timeout_prefix(): consumes 'timeout', option flags (-s/-k with
their separate args, --preserve-status/--foreground/-v), and the DURATION
token, routes the inner command, and re-prepends the wrapper verbatim.
9 new tests. All 2453 tests pass, clippy clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Summary
Makes
ssh/scpoutput flow through RTK, adds adedup_repeatsTOML action for repetitive log output, and strips thetimeoutwrapper so timeout-wrapped commands still route.Why:
sshis one of the highest-volume commands in real agent sessions — remote diagnostics likejournalctl,docker logs,dmesg,virsh list. A scan of my Claude Code history showed ~2000sshinvocations in 30 days, none compressed, becausesshwas never registered as a rewritable command (anssh.tomlfilter existed but nothing routed to it). A further ~140 were wrapped intimeout <N> ssh ..., which bypassed routing entirely because the command starts withtimeout. Remote log output is also highly repetitive, which the pipeline had no way to collapse.Changes
core/toml_filter.rs— newdedup_repeatsbool action, pipeline stage 4.5 (after strip/keep, before truncate). Collapses runs of consecutive identical lines into a[xN]suffix. Trailing whitespace ignored; blank lines never merged. Non-lossy — the count preserves the information, so no tee fallback triggers.discover/rules.rs— register^ssh\b→rtk sshand^scp\b→rtk scp.discover/registry.rs—strip_timeout_prefix(): strips atimeout [OPTS] DURATIONwrapper (mandatory duration + optional-s/-kwith args,--preserve-status, etc.), routes the inner command, and re-prepends the wrapper verbatim. Can't useBUILTIN_TRANSPARENT_PREFIXESbecause that path is fixed-word only.filters/ssh.toml— enablededup_repeats; strip additional connection noise (Last login,X11 forwarding request failed,Shared connection ... closed). New inline test for the dedup path.filters/scp.toml— new filter: strips banners/progress, keeps transfer errors.Examples
Testing
cargo test --all— 2453 passed, 0 failedcargo clippy --all-targets— clean-k/-swith args, scp inner, unknown inner → passthrough, composition with env prefixes).Notes / open questions
ssh/scpchanges default behavior for all users. The filters are conservative — banners and blank lines only, plus dedup — so a successful command's real stdout is preserved. Happy to gate behind config if you'd prefer opt-in.dedup_repeatsis generic and could be reused by other log-like filters (journalctl,docker logs) in follow-ups.