Skip to content

feat(shell): add rtk-shell, bash-wrapped shell for agent harnesses#2855

Open
guyzmo wants to merge 1 commit into
rtk-ai:developfrom
guyzmo:feature/rtk-shell
Open

feat(shell): add rtk-shell, bash-wrapped shell for agent harnesses#2855
guyzmo wants to merge 1 commit into
rtk-ai:developfrom
guyzmo:feature/rtk-shell

Conversation

@guyzmo

@guyzmo guyzmo commented Jul 6, 2026

Copy link
Copy Markdown

Summary

  • Add rtk-shell, a minimal shell wrapper that filters recognized CLI commands (git status, cargo test/build/clippy, etc.) through RTK's existing filters to cut token overhead for agent harnesses (e.g. opencode), while transparently forwarding anything it doesn't recognize to a real backing shell.
  • Three invocation modes: one-shot (rtk-shell -c "...", usable as $SHELL), persistent interactive session (with cd/env state persistence across commands), and an opt-in RC-file swap (rtk init) that auto-enables the shell when invoked by a known agent harness in non-interactive mode.
  • Extracts src/lib.rs so the module tree is shared between the rtk and rtk-shell binaries; adds src/shell/ (dispatch, oneshot, session) plus supporting changes to config, tracking, and hooks.

Design notes / known limitations

  • No PTY support — TUI/interactive-curses commands are forwarded to the backing shell unfiltered, not intercepted.
  • Windows is out of scope for this iteration.
  • Only git status/cargo test/build/check/clippy get real filtering in session mode today; other recognized commands intentionally fall back to raw passthrough (documented, not silent) pending follow-up work.
  • OPENCODE_SESSION_ID in the known-harness env var list is an unconfirmed placeholder — flagged for review.

Test plan

  • cargo fmt --all -- --check
  • cargo clippy --all-targets (zero warnings)
  • cargo test --all (2408 passed, 9 ignored, 0 failed)
  • Manual verification: session-mode output byte-for-byte matches one-shot mode for git status (git repo + non-git dir)
  • Manual verification: cd/pwd state persists across commands in a session
  • Manual verification: pipeline passthrough (echo hello | grep hello) still works
  • Manual verification: no sentinel/internal marker leakage in session transcripts
  • Reviewer: confirm OPENCODE_SESSION_ID env var name against opencode's actual harness detection surface

🤖 Generated with Claude Code

@CLAassistant

CLAassistant commented Jul 6, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@rtk-release-bot

Copy link
Copy Markdown
Contributor

Automatic message from CI checks : It seems like this branch is targeting the wrong branch, any contribution should target develop branch.

See CONTRIBUTING.md for details.

@rtk-release-bot rtk-release-bot Bot added the wrong-base PR targets master instead of develop label Jul 6, 2026
@guyzmo guyzmo changed the base branch from master to develop July 6, 2026 23:19
@guyzmo guyzmo force-pushed the feature/rtk-shell branch from 117db4c to 89661f8 Compare July 6, 2026 23:22
@FlorianBruniaux

Copy link
Copy Markdown
Collaborator

@guyzmo Nice work on the session internals here, the nonce-based sentinels, dual-stream draining threads, and the sentinel-leak regression tests show real care on the trickiest part of this (process concurrency).

One blocker before we get into the actual review: this PR targets master instead of develop. GitHub already flagged it (wrong-base label, merge state BLOCKED). Per repo convention, features and fixes go through develop, master is release-only.

Can you retarget the base branch to develop? Once that's sorted we'll dig into the rest.

@guyzmo

guyzmo commented Jul 7, 2026

Copy link
Copy Markdown
Author

@FlorianBruniaux I already rebased last night when I saw this.

I'm sorry, I'm not used for projects in git flow, especially using master for production. This is surprising ;-)

Maybe you should add something in agents.md to make the llm yell when a contributor does a PR against master? 😝

Implement rtk-shell: a minimal shell wrapper that filters recognized
CLI commands (git status, cargo test/build/clippy, etc.) through RTK
to achieve 60-90% token savings for agent harnesses like opencode,
while transparently forwarding unsupported commands to a real backing
shell.

Three invocation modes:
1. One-shot: `rtk-shell -c "..."` (mirrors `sh -c`), used as $SHELL
2. Persistent: `rtk-shell` interactive session with state persistence
3. RC swap: `rtk init --shell-mode` injects ~1KB guarded swap into RC
   files to auto-enable modes 1-2 when invoked by known harnesses

Implementation:
- Extract src/lib.rs (rtk crate) to share modules with rtk-shell binary
  (Cargo.toml: add [lib] target, [[bin]] for rtk-shell)
- New src/shell/ module: dispatch (classify line into Filterable/Forward
  segments), oneshot (run -c line via backing shell + filters), session
  (persistent backing shell with nonce-based sentinels to avoid deadlock,
  threaded stdout/stderr draining, signal forwarding, heredoc detection)
- Extend src/core/config.rs: ShellConfig (backing_shell, minimal_ps1)
- Extend src/core/tracking.rs: optional session_id column for metrics
- Add src/core/utils::exit_code_from_status (map signal deaths to
  128+signum, fixing Commands::Proxy/Commands::Run exit code gaps)
- Extend src/hooks/: Mode-3 RC injection (~/.rtk-shell-swap.sh) with
  recursion guard (RTK_IN_SHELL), env-var detection, isatty failsafe
- Fix module imports across all command modules (aws, container, dotnet,
  git, go, js/vitest, etc.) for new lib root
- Add tests/shell_integration_test.rs: git status filtering, exit codes,
  signal handling, cd/pwd persistence in session mode

Motivation: RTK's primary use case is reducing token overhead for
agentic interactions. The existing `rtk <cmd>` syntax requires explicit
rewriting via PreToolUse hooks. rtk-shell eliminates that friction by
becoming the $SHELL itself — agents get token savings by default.

This implementation targets agent harnesses (mode 2/$SHELL, mode 3 RC
swap) rather than human interactive use, per explicit design guidance.
Known limitations: no PTY/TUI (forward unfiltered), Windows out of scope,
OPENCODE_SESSION_ID placeholder (unconfirmed), most ecosystems beyond
git/cargo fall back to raw passthrough (intentional, documented).

Co-Authored-By: Claude <noreply@anthropic.com>
@guyzmo guyzmo force-pushed the feature/rtk-shell branch from 89661f8 to 67f5dfa Compare July 7, 2026 11:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

wrong-base PR targets master instead of develop

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants