Conversation
…1250) The installer previously ran `tar -xzf` on the downloaded archive with no pre-extraction verification. A malicious mirror could ship a tarball with `../` components or absolute paths and write files anywhere on the user's filesystem (CWE-22). Add a pre-extraction check that lists archive contents with `tar -tzf` and rejects any entry whose name starts with `/` or contains a `..` path component. The check is POSIX-compliant and adds negligible overhead for the single-binary RTK release tarball. Covered by scripts/test-install.sh, which exercises one safe archive and four crafted malicious archives (leading `..`, absolute path, mid-path `..`, trailing `..`) plus a regression guard that ensures the check remains in install.sh. Co-Authored-By: Claude <noreply@anthropic.com>
fix(install): reject archive with path traversal before extraction (#1250)
fix(git): preserve full status paths and untracked files
Previously `rtk docker compose logs --tail=20 web` would fall through to the passthrough handler because clap had no `--tail` field on the `Logs` subcommand, resulting in 0% token savings. Additionally, `run_compose_logs` always fetched 100 lines regardless of user input. - Add `#[arg(long, default_value_t = 100)] tail: u32` to `ComposeCommands::Logs` - Thread the value through to the docker invocation - Default unchanged (100 lines), so bare `rtk docker compose logs` behaves as before Ports the core fix from #580, retargeted onto current develop layout (`src/cmds/cloud/container.rs`). Relates to #578. Co-authored-by: Mihir Dash <137862945+slice-mihird@users.noreply.github.com>
fix(docker): forward --tail flag in compose logs
…iltering Several filters dropped or rewrote information an agent needs, producing output that was misleading rather than merely compressed. This fixes the clear-cut cases surfaced by the TheDecipherist/rtk-test suite: - ls: stop hiding the `.env` file (removed `.env`/`env` from NOISE_DIRS). - git status: restore the explicit "HEAD detached at <sha>" line instead of the opaque "* HEAD (no branch)". - log/docker logs: recognise CRITICAL/FATAL/ALERT/EMERGENCY/SEVERE (and NOTICE) as severities so those lines are no longer silently filtered; expose `log` as a `rtk pipe` filter and accept a positional filter name. - wc: forward stdin to the child so `cat file | rtk wc` counts the pipe instead of reporting 0 (new RunOptions::inherit_stdin). - jest/vitest: include skipped/pending test count in the compact summary. - pytest: surface xfailed/xpassed counts and list XFAIL/XPASS entries with their reasons (adds `-rxX`). - ruff/eslint: list individual violations with file:line:col, not just rule/file group counts. - pnpm/npm list: render the actual package list instead of the false-positive "All packages up-to-date" when there's no upgrade info. - git add: stay silent on a no-op instead of printing an ambiguous "ok". - git stash: pass git's own message through instead of collapsing to "ok". - docker ps: keep the Status column (health/restart info) and list stopped/exited containers; docker images: show all images with full names; docker compose ps: use `-a` so crashed services stay visible. All 1870 unit tests pass; cargo fmt + clippy clean.
## Problem (#963) `rtk git push` reportedly times out: users see `bash tool terminated command after exceeding timeout 30000 ms` while plain `git push` to the same remote completes fine. P1-critical because every Claude Code git push goes through rtk. ## Root cause `run_push` used `cmd.stdin(Stdio::inherit()).output()`. `Command::output()` captures both stdout and stderr until the child exits. Git push prints its progress (`Counting objects` / `Compressing objects` / `Writing objects`) to stderr and may prompt for SSH passphrases or HTTPS credentials. With stderr captured, Claude Code's bash tool saw zero output for 30+ seconds and killed the command — exactly the 30000 ms message in the issue. ## Fix Rewrite `run_push` on top of the streaming infrastructure that already exists for this exact purpose (`stream::run_streaming` + `FilterMode::Streaming`, added in 0.37.0). Add a counterpart to `BlockStreamFilter<H: BlockHandler>` in `src/core/stream.rs`: `LineStreamFilter<H: LineHandler>`. Where `BlockStreamFilter` defaults to DROP and emits only collected blocks, `LineStreamFilter` defaults to KEEP and lets handlers opt into dropping noise. Trait surface mirrors `BlockHandler`: - `should_skip(&mut self, line: &str) -> bool` — default false - `observe_line(&mut self, line: &str)` — default no-op - `format_summary(&self, exit_code, raw) -> Option<String>` This lets future streaming commands reuse the line-oriented pattern. `GitPushLineHandler` then becomes a tiny `LineHandler` impl: - `should_skip` drops the high-volume progress phases (Enumerating / Counting / Compressing / Writing objects, Delta compression, Total) and blank lines. - `observe_line` captures the up-to-date sentinel and the first ref update target (e.g. `master`) for the summary. - `format_summary` emits `ok <ref>` / `ok (up-to-date)` / `ok` on success; nothing on failure (raw error lines already flowed through). Stdin is inherited (`StdinMode::Inherit`) so SSH passphrase and HTTPS credential prompts still reach the user. Tracking now records the real raw output and the filtered output. ## Test plan - [x] `cargo fmt --all -- --check` - [x] `cargo clippy --all-targets -- -D warnings` — clean - [x] `cargo test --all` — 1880 passed, 0 failed, 6 ignored - Six unit tests cover the push handler: progress-prefix drop, up-to-date summary, remote message passthrough, no-summary-on-failure, first-ref-wins, and token-savings (>=60% on a representative payload). - Four unit tests cover the new `LineStreamFilter` trait: default-keep-all, skip-drops-matching, summary-propagates-exit-code, observe-only-called-for-kept-lines. ## Notes - Behaviour change: users now see git's native output line-by-line (with progress phases stripped) plus a final `ok <ref>` summary, instead of just the compact summary. This matches plain `git push` more closely and is what the issue reporter expects. - No regression for other filters: `run_pull`, `run_fetch`, `run_clone` are untouched; only `run_push` is modified. Closes #963 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- _Vibe Coded by Ousama Ben Younes_ _Developed With Ora Studio (Claude Code)_ Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- fix signal truncation gaps + kush reviews - added a new tee and hints function to give an hint with tail (avoid re-ingest of the head) - extracted patterns in constants
Co-authored-by: Cursor <cursoragent@cursor.com>
fix(kubectl): compact get pods and services aliases
fix(git): stream push output to avoid spurious 30s timeout (#963)
- docker ps reverts to plain (no -a augmentation) - docker ps -a / compose ps -a wired to the running/stopped split filter - ruff Violations: capped at 50 + force_tee_tail_hint recovery - tests for the ruff and pytest xfail caps
fix(filters): aggresivity batch fix
Replace all bare magic offset literals (e.g. 21 for cap=20) with named constants (MAX_XXX + 1) so offsets stay in sync if caps change. Fix compose_ps to tee pre-formatted lines instead of raw tab-separated input, so tail -n +N gives the agent readable content. All 13 affected modules updated: container, dotnet, gh, glab, go, lint, pnpm, pytest, rubocop, cargo, aws. 1884 tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix(tee): safe truncation caps and tee/hint coverage
Adds a TDD red test that asserts pre-existing user content in .github/copilot-instructions.md must survive 'rtk init --copilot'. Currently fails because run_copilot() uses write_if_changed() which truncates the file. Refs #1964
run_copilot() previously called write_if_changed() which truncated any pre-existing .github/copilot-instructions.md, destroying user-authored Copilot rules. This routes copilot-instructions.md through upsert_rtk_block() (the same idempotent marker-block helper already used for CLAUDE.md and AGENTS.md). The COPILOT_INSTRUCTIONS constant is wrapped in <!-- rtk-instructions v2 --> ... <!-- /rtk-instructions --> markers so subsequent inits replace only RTK-owned content; the rest of the file is preserved verbatim. Malformed pre-existing blocks (opening marker without closing) are refused with a remediation message rather than silently rewritten. Fixes #1964, #1891
…formed paths Adds five additional tests around copilot-instructions.md upsert: - idempotent re-init (no duplicated blocks, identical content) - stale RTK block in-place update with surrounding user content preserved - dry-run never creates or modifies the file - fresh install creates file with RTK marker block when no file exists - malformed pre-existing block (opening marker without closing) is refused with a clear error rather than silently rewritten Refs #1964
run_copilot(ctx) is now a thin wrapper around run_copilot_at(base, ctx); tests pass a TempDir path so they no longer mutate process-global cwd. This eliminates flakes when cargo test runs in parallel (the default). The public API is unchanged; only the internal seam moves. Refs #1964
The README badge and footer claimed MIT, but the LICENSE file is Apache License 2.0. Updates both references so the README matches the authoritative LICENSE file. Closes #1996 Co-Authored-By: Claude <noreply@anthropic.com>
Following tee and hint refacto Add global CAP constant to be inherited , to enable easier global configuration later
…he-2.0 docs(readme): fix license references to match LICENSE (Apache-2.0)
Address review feedback on #1976: - Extract write_rtk_block() shared dispatcher: eliminates the duplicated 4-arm RtkBlockUpsert match between run_claude_md_mode and the former upsert_copilot_instructions (now inlined). Both callers stay under the ~60-line guideline. - Unify malformed handling: both paths now bail!() with a diagnostic and the exact recovery command. CLAUDE.md previously warned and exited 0, silently skipping the OpenCode plugin step; behaviour is now consistent. - Reorder run_copilot_at: upsert copilot-instructions.md BEFORE writing the hook config so a malformed file aborts the install without leaving a stale .github/hooks/rtk-rewrite.json on disk. Regression coverage: - test_claude_md_mode_refuses_malformed_block mirrors the existing copilot malformed test against the shared dispatcher contract. - test_copilot_init_malformed_leaves_no_hook_on_disk pins the new write order so a future re-order regression is caught. cargo fmt / clippy --all-targets / test --bin rtk: clean (1909 passed).
fix(hooks/init): preserve user content in copilot-instructions.md
- Avoid underflow + 0 results caused by overwrite of global constant CAPS - Soon user will be able to apply global configuration, this will change global CAPS and should not cause any underflow or 0 results, if overwrite sub >= CAPS -> use CAPS.
refacto(truncations): Set global CAPS for truncation
Contributor
Author
|
Found a blocker : git status regression in savings with -uall -procelain Working on a fix , may revert #991 to merge this |
The compact `git status` path ran `git status --porcelain -b -uall`. The `-uall` flag expands fully-untracked directories into every file, while raw `git status` collapses them (e.g. `node_modules/`). This made rtk output larger than raw — measured ~29x on a 200-file untracked dir (5500B vs 191B) — violating RTK's compress-or-match-raw invariant and inflating tokens. Remove `-uall` so untracked directories collapse exactly like raw. This keeps #991's actual fix intact: all modified/staged/renamed/conflict paths are still shown with no grouped summaries or `... +N more` overflow markers (`-uall` never affected those lines). Untracked files in partially-tracked dirs and any paths git itself expands are still preserved by the formatter. Measured (rtk vs raw git status): - node_modules/ (200 files): 5500B (-2780%) -> 25B (+87% savings) - normal (8 mod + 2 untracked): +71% -> +76% - 17 modified (#991 case): unchanged at +58%, all 17 shown, 0 overflow markers Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
fix(git): drop -uall from compact status so output never exceeds raw
pszymkowiak
approved these changes
May 22, 2026
Collaborator
pszymkowiak
left a comment
There was a problem hiding this comment.
✅ Approved — revue approfondie
Revue ligne à ligne au HEAD 06476d17 (et non via gh pr diff, qui sert un diff caché périmé), complétée par des tests empiriques de git status sur plusieurs gros repos OSS.
Qualité élevée et homogène. Points forts :
core/truncate.rs: caps centralisés +reduced()const fnunderflow-safe, appliqué uniformément sur ~30 modules.- Récupération sur troncature (
force_tee_tail_hint) avec offsets corrects (MAX+1,MAX+2pour docker-images), convention documentée. git pushen streaming (#1531) : règle le timeout 30s, préserve lesremote:, ne résume pas sur échec.init.rs(#1976) :write_rtk_blockupsert par marqueurs +atomic_write+ refus des blocs malformés → préserve réellement le contenu utilisateur.- Hygiène RTK respectée : aucun
unwrap/async/Regex::new/panichors tests.
Le point que je jugeais bloquant a été corrigé : le commit « drop -uall from compact status so output never exceeds raw » fait que git status ne dépasse plus jamais la sortie brute (un dossier untracked redevient une seule ligne).
Points mineurs, non bloquants (à traiter idéalement avant le tag)
- Doc désynchronisée :
src/cmds/git/README.md:8indique encore--porcelain -b -uall(et « nested untracked files stay visible »), alors que-ualla été retiré du code. À corriger. format_status_innerreste sans cap ni test de savings : sur un gros codemod (beaucoup de fichiers tracked modifiés), la compression est modeste (~30–50 %). Acceptable comme choix produit (#991), mais un test de non-régression « never exceeds raw » serait précieux.
LGTM 🚢
docs(git): sync status README with --porcelain -b
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.
Fix
docker compose logs(high-volume, currently proxied raw) #578rtk git pushcommand, it sometimes times out #963