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#1457
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#1457
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 #1458.
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 #1458.
Per @KuSh's review on #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.
The generic fallback arm of `Commands::Npx` called `npm_cmd::run`, which
executes `npm` instead of `npx`. This broke every non-routed npx
invocation. `rtk npx cowsay hello` failed with `npm error Missing
script: "cowsay"` because the rewrite hook sends `npx ...` through as
`rtk npx ...`, and `rtk npx` was then running npm.
Mirror the existing prisma generic-subcommand passthrough pattern:
resolve npx, forward all args, record a tracked passthrough, and
propagate the exit status.
Fixes#815
Branch names containing '/' (e.g. feature/user-auth, main...feature/auth)
were incorrectly treated as file paths by the string heuristic in
normalize_diff_args, causing '--' to be injected before them and making
git treat them as pathspecs — resulting in silent empty output (exit 0).
Replace looks_like_path() with a three-tier detection strategy:
- Explicit path prefixes (. ~) → always a path, no filesystem check needed
- Contains path separator (/ \) → use filesystem existence to distinguish
branch names (feature/auth, not on disk) from real paths (src/main.rs)
- Bare word with no separator → never inject '--', regardless of filesystem
state (avoids misfire when a file shares a name with a branch/ref)
Introduce normalize_diff_args_impl with injectable path-checker for
testability. Update all existing tests to use mock existence checks.
Add three regression tests: branch-with-slash, range-with-slash, and
bare-word-that-exists-on-disk.
Fixes: #1431
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The installer failed with "Failed to get latest version" when the GitHub
REST API returned 403 due to the anonymous rate limit (60 req/hour, shared
across NAT/CI). Switch the primary lookup to the `/releases/latest` 302
redirect, which doesn't count against the API quota. Keep the API call as
a fallback, and add a RTK_VERSION escape hatch for pinning.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Removing old guards, windows can now just use the binary hook engine from 0.37
Related issues:
- Fixes#502 : rtk init --global falls back to --claude-md on Windows
- Fixes#1353 : Feature request: hook-based mode on Windows
- Partially addresses #330 : Add hooks support for Windows
- Partially addresses #913 : Persistent "No hook installed" warning on Windows
- Partially addresses #1373 : Suppress "No hook installed" warning on Windows
- Partially addresses #682 : Config to suppress hook warning
- Related to #1248 : Windows PowerShell compatibility gaps
Supersedes community PRs:
- #1123 fix(init): enable hook installation on Windows
- #1027 fix(init): enable hook-based mode on Windows
- #809 feat: enable hook-based mode on Windows
- #452 feat: add Windows hook support for rtk init --global
- #551 feat: native cross-platform hook for Windows support
- #150 feat(hook): native cross-platform hook-rewrite command
- #1063 Feat/windows hooks
Replace \b with ($|\s) to only match end-of-string or whitespace.
Empty string and bare "^" patterns produce regexes that match all commands, silently disabling all rewrites on a config typo. Skip
trivial patterns with an eprintln warning.
Strip env prefix (sudo, VAR=val) before exclude check so PGPASSWORD=x psql matches ["psql"]. Match against full command instead of first token so ["git push"] matches "git push origin main".
Compile exclude entries as regex so ["^curl"] works as pattern.
Invalid regex falls back to prefix match with eprintln warning.
Non-regex patterns auto-anchor with ^ and \b to prevent substring matches (e.g. "go" won't exclude "golangci-lint").
- grep: use --no-ignore-vcs so .gitignore'd files aren't silently skipped
(matches grep -r behavior, avoids false negatives in large monorepos)
- grep: passthrough raw output for <=50 matches so AI agents can parse
standard file:line:content format without retry loops
- filter: replace smart_truncate heuristic with clean first-N-lines truncation
and a single [X more lines] suffix (eliminates synthetic // ... markers
that AI agents misread as code, causing parsing confusion and retries)