Skip to content

v1.2.0

Latest

Choose a tag to compare

@github-actions github-actions released this 19 Aug 04:43

Added

  • toksave doctor --fix repairs broken agent wiring: Previously --fix only reinstalled/repaired tool binaries (RTK, CodeGraph, ...); a hook or MCP entry reported as missing was never actually rewired — doctor just told you to re-run toksave. --fix now unwires and cleanly rewires every (agent, tool) pair verify_tool reports as not-wired, for all 9 agents × 6 tools, then re-verifies and records the manifest entry. Tools whose underlying binary was never installed are left alone rather than wiring a config that points at nothing. Plain doctor (no --fix) makes no changes, as before.
  • toksave uninstall warns on residual wiring: after unwire_tool, uninstall now re-checks verify_tool and warns if a hook/MCP entry survives instead of silently trusting the unwire succeeded.

Fixed

  • RTK hook never fires for Warp, Antigravity, Codex, Droid, or Devin: toksave rtk-hook <agent> only recognized tool_name values bash|shell|run_command|execute_command|cmd|sh|pwsh, but the real tool names are agent-specific: Cursor sends Shell, Antigravity/Gemini CLI sends run_shell_command, Factory Droid sends Execute (exact case), Devin CLI sends exec. The hook silently produced no output for all of these, so RTK never rewrote a single command on those agents. Matchers are now per-agent and exact where the agent's real tool name is confirmed (against each agent's own hook docs and RTK's own hooks/README.md), falling back to a broad matcher for unlisted agents.
  • Wrong response JSON per agent: Cursor's real contract (confirmed against rtk-ai/rtk's own hook implementation) is a top-level {"permission":"allow","updated_input":{...}}, and it requires {} — not empty stdout — on every no-rewrite path; toksave was emitting Claude-shaped hookSpecificOutput.updatedInput, which Cursor ignores. Antigravity/Gemini's contract is {"decision":"allow","hookSpecificOutput":{"tool_input":{...}}}; toksave emitted modifiedToolInput, which Gemini CLI doesn't read. Codex, Droid, and Devin all use Claude's hookSpecificOutput.updatedInput shape, not modifiedToolInput — Codex was previously miscategorized into the wrong bucket.
  • Factory Droid RTK hook wired to a directory Droid never reads: toksave wrote ~/.factory-droid/hooks.json; Droid's real hooks file (confirmed against docs.factory.ai/harness/hooks and rtk-ai/rtk#912) is ~/.factory/hooks.json. Fixed the path and added self-healing cleanup of the old location on every wire/unwire.
  • Devin CLI RTK hook wired to the wrong file and tool name: toksave wrote a standalone ~/.devin/hooks.json with matcher Execute; Devin's real hooks (per docs.devin.ai/cli/extensibility/hooks/overview) are nested under the "hooks" key of ~/.config/devin/config.json (%APPDATA%\devin\config.json on Windows), and its shell tool is named exec, not Execute (that's Droid's tool name). Fixed both, with self-healing cleanup of the old file.
  • GitHub Copilot CLI RTK hook: fixed a typo'd filename (tokless-rtk.jsontoksave-rtk.json) and rewrote the hook to match Copilot CLI's real dual-format contract (docs.github.com/en/copilot/reference/hooks-reference): camelCase toolName/toolArgs (a JSON-encoded string) for the native CLI, snake_case tool_name/tool_input for the VS Code Copilot Chat extension, with a matcher: "bash" hook entry and a proper modifiedArgs rewrite instead of a deny-and-hope-they-retry response.
  • RTK prefix used a bare rtk that can fail on Windows / GUI-launched agents: if RTK was just installed and the agent's shell session predates the PATH update (or has a minimal PATH), the rewritten command failed with 'rtk' is not recognized. The hook now resolves the absolute path to the locally-managed rtk binary when present, falling back to bare rtk only when nothing is locally installed. Applied to the Rust hook and the OpenCode plugin.
  • Claude Code: ~/.claude/CLAUDE.md could carry a dangling @RTK.md reference after RTK's own RTK.md was removed; the strip logic only ran against AGENTS.md. Now strips from both.
  • Warp has no confirmed hook engine: extensive research against docs.warp.dev turned up no PreToolUse-style hook mechanism for the Warp Agent CLI or desktop app (unlike Claude, Cursor, Gemini CLI, Droid, and Devin, which all have documented hook contracts) — RTK itself doesn't list Warp as a supported agent either. toksave no longer writes a ~/.warp/hooks.json RTK entry; it relies on rtk being on PATH instead, and opportunistically cleans up any hook file a pre-1.2 toksave wrote plus dead /$bunfs/root/toksave references left behind by very old Warp CLI installs.
  • Antigravity CLI: dead ~/.antigravity fallback directory: with Gemini CLI being discontinued in favor of Antigravity CLI, toksave fell back to ~/.antigravity whenever ~/.gemini didn't exist yet (e.g. a machine with agy installed but never launched once). Antigravity CLI never creates or reads ~/.antigravity at all — confirmed by Google's own Gemini CLI migration guide and by two separate antigravity-cli CHANGELOG bug-fix entries, both pointing at the shared ~/.gemini/config/ directory. antigravity_paths() now always targets ~/.gemini, so hooks and instruction files wired before the CLI's first launch actually land where Antigravity reads from.
  • Antigravity CLI: wrong MCP config filename: toksave wrote CodeGraph/Context-Mode MCP servers to ~/.gemini/mcp.json and ~/.gemini/config/mcp.json; Antigravity CLI's real, documented file is ~/.gemini/config/mcp_config.json (per antigravity.google/docs/cli/gcli-migration). Fixed the filename.
  • MCP verify treated key-exists as success: a leftover /$bunfs/root/toksave command, a dead binary, or wrong runmcp argv still counted as wired, so doctor --fix printed all tools wired and skipped rewrite. Verify now requires the live toksave_abs() plus the expected runmcp argv. --fix also rewires tools whose probe_agent reports binary not found / bunfs / PowerShell-hostile forward-slash hook paths, tries tool_repair before rewire for missing npm tools, and prints a Windows PATH hint (%APPDATA%\npm, %LOCALAPPDATA%\Programs\toksave) when CodeGraph/Context-Mode still cannot be installed.
  • Windows hook/RTK paths assumed Git Bash: 1.0.3 wrote C:/Users/.../toksave.exe so Git Bash would not treat backslashes as escapes. That form is valid in cmd.exe and as MCP CreateProcess argv, but Windows PowerShell 5.1 (and typically pwsh 7) parse C: as Set-Location and /Users/... as a switch — machines with only cmd + PowerShell never run the hook. Shell strings (hook command and RTK prefixes) now use backslashes via toksave_hook_command() / winsh; MCP command stays forward-slash toksave_abs(). Doctor no longer treats backslash as stale. Re-run toksave init or toksave doctor --fix after upgrading. Git Bash is not required.
  • Official rtk init --auto-patch stacked a second Claude hook: rtk hook claude next to toksave rtk-hook claude made both fire (rtk rtk git status). Verify is now false while the native sibling exists; wire/doctor --fix removes it. Doctor also notes that rtk init --show reports the Claude hook missing when only toksave's wrapper is present — keep rtk init -g --no-patch.
  • Cursor CLI hooks went to $XDG_CONFIG_HOME/cursor: Cursor reads ~/.cursor/hooks.json (confirmed against Cursor's own hooks docs). Official RTK already writes that file; the XDG path left two competing configs. cursor_paths() now always uses ~/.cursor unless CURSOR_CONFIG_DIR is set, and native rtk hook cursor siblings are stripped on wire.
  • Absolute rtk prefix could rewrite twice: the hook skipped only a bare rtk prefix, so a second PreToolUse pass turned /path/to/rtk ls into /path/to/rtk /path/to/rtk ls. It now treats the resolved prefix (quoted when the path has spaces) as already rewritten.

Minimum RTK version for the binary hook engine used by all of the above: 0.37+.

Contributors

  • Huge thanks to @jondmarien for contributing exact per-agent RTK hook contracts, self-healing doctor/uninstall repairs, and Windows cmd/PowerShell compatibility in #28!