Releases: agungprasastia/toksave
Releases · agungprasastia/toksave
Release list
v1.2.0
Added
toksave doctor --fixrepairs broken agent wiring: Previously--fixonly reinstalled/repaired tool binaries (RTK, CodeGraph, ...); a hook or MCP entry reported as missing was never actually rewired — doctor just told you to re-runtoksave.--fixnow unwires and cleanly rewires every(agent, tool)pairverify_toolreports 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. Plaindoctor(no--fix) makes no changes, as before.toksave uninstallwarns on residual wiring: afterunwire_tool, uninstall now re-checksverify_tooland 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 recognizedtool_namevaluesbash|shell|run_command|execute_command|cmd|sh|pwsh, but the real tool names are agent-specific: Cursor sendsShell, Antigravity/Gemini CLI sendsrun_shell_command, Factory Droid sendsExecute(exact case), Devin CLI sendsexec. 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 ownhooks/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-shapedhookSpecificOutput.updatedInput, which Cursor ignores. Antigravity/Gemini's contract is{"decision":"allow","hookSpecificOutput":{"tool_input":{...}}}; toksave emittedmodifiedToolInput, which Gemini CLI doesn't read. Codex, Droid, and Devin all use Claude'shookSpecificOutput.updatedInputshape, notmodifiedToolInput— 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 againstdocs.factory.ai/harness/hooksandrtk-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.jsonwith matcherExecute; Devin's real hooks (perdocs.devin.ai/cli/extensibility/hooks/overview) are nested under the"hooks"key of~/.config/devin/config.json(%APPDATA%\devin\config.jsonon Windows), and its shell tool is namedexec, notExecute(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.json→toksave-rtk.json) and rewrote the hook to match Copilot CLI's real dual-format contract (docs.github.com/en/copilot/reference/hooks-reference): camelCasetoolName/toolArgs(a JSON-encoded string) for the native CLI, snake_casetool_name/tool_inputfor the VS Code Copilot Chat extension, with amatcher: "bash"hook entry and a propermodifiedArgsrewrite instead of a deny-and-hope-they-retry response. - RTK prefix used a bare
rtkthat 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-managedrtkbinary when present, falling back to barertkonly when nothing is locally installed. Applied to the Rust hook and the OpenCode plugin. - Claude Code:
~/.claude/CLAUDE.mdcould carry a dangling@RTK.mdreference after RTK's ownRTK.mdwas removed; the strip logic only ran againstAGENTS.md. Now strips from both. - Warp has no confirmed hook engine: extensive research against
docs.warp.devturned 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.jsonRTK entry; it relies onrtkbeing on PATH instead, and opportunistically cleans up any hook file a pre-1.2 toksave wrote plus dead/$bunfs/root/toksavereferences left behind by very old Warp CLI installs. - Antigravity CLI: dead
~/.antigravityfallback directory: with Gemini CLI being discontinued in favor of Antigravity CLI, toksave fell back to~/.antigravitywhenever~/.geminididn't exist yet (e.g. a machine withagyinstalled but never launched once). Antigravity CLI never creates or reads~/.antigravityat all — confirmed by Google's own Gemini CLI migration guide and by two separateantigravity-cliCHANGELOG 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.jsonand~/.gemini/config/mcp.json; Antigravity CLI's real, documented file is~/.gemini/config/mcp_config.json(perantigravity.google/docs/cli/gcli-migration). Fixed the filename. - MCP verify treated key-exists as success: a leftover
/$bunfs/root/toksavecommand, a dead binary, or wrongrunmcpargv still counted as wired, sodoctor --fixprintedall tools wiredand skipped rewrite. Verify now requires the livetoksave_abs()plus the expectedrunmcpargv.--fixalso rewires tools whoseprobe_agentreportsbinary not found/ bunfs / PowerShell-hostile forward-slash hook paths, triestool_repairbefore 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.exeso 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) parseC:as Set-Location and/Users/...as a switch — machines with only cmd + PowerShell never run the hook. Shell strings (hookcommandand RTK prefixes) now use backslashes viatoksave_hook_command()/winsh; MCPcommandstays forward-slashtoksave_abs(). Doctor no longer treats backslash as stale. Re-runtoksave initortoksave doctor --fixafter upgrading. Git Bash is not required. - Official
rtk init --auto-patchstacked a second Claude hook:rtk hook claudenext totoksave rtk-hook claudemade both fire (rtk rtk git status). Verify is now false while the native sibling exists; wire/doctor --fixremoves it. Doctor also notes thatrtk init --showreports the Claude hook missing when only toksave's wrapper is present — keeprtk 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~/.cursorunlessCURSOR_CONFIG_DIRis set, and nativertk hook cursorsiblings are stripped on wire. - Absolute
rtkprefix could rewrite twice: the hook skipped only a barertkprefix, so a second PreToolUse pass turned/path/to/rtk lsinto/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!
v1.1.0
Added
- Cursor CLI agent: Full support for the Cursor Agent CLI (
cursor/cursor-cli). Wires user-global~/.cursor/config shared with the Cursor editor: nativehooks.jsonpreToolUse+cli-config.jsonShell(rtk *)allow for RTK,mcp.jsonfor CodeGraph and Context-Mode, andAGENTS.mdinstruction owners for Caveman, Ponytail, and Principles, with official brand iconassets/agents/cursor.png. Special thanks to @jondmarien in #26. - Warp Agent CLI MCP wiring: Warp / Oz now writes CodeGraph and Context-Mode to the official desktop file (
~/.warp/.mcp.json) and the standalone Agent CLI MCP file, in addition to the existing~/.warp/mcp.json. Detection also treats theozbinary and CLI config dir as installed. Doctor probe includes the new MCP paths. Special thanks to @jondmarien in #25.
Contributors
- Huge thanks to @jondmarien for contributing support for Cursor CLI and Warp Agent CLI!
v1.0.3
Fixed
- Windows: backslash paths break Git Bash hooks:
toksave_abs()returned native Windows paths (C:\Users\...\toksave.exe) which break in Git Bash (backslashes interpreted as escape characters). Now normalizes to forward slashes (C:/Users/.../toksave.exe) on Windows — valid in cmd.exe, PowerShell, and Git Bash. Users must re-runtoksave initafter upgrading to rewrite configs with safe paths. (@jondmarien in #24) - Doctor probe false positives on non-toksave MCP entries:
toksave doctorprobed every"command"key in agent config files, including user-owned MCP servers (e.g.node, shell builtins[,if), reporting spuriousbinary not foundwarnings. Probe now filters to toksave-owned commands only viais_toksave_exe()check. (@jondmarien in #24)
v1.0.2
Fixed
- Codex RTK unwire deletes user
PreToolUsehooks:unwire(Rtk)removed the wholePreToolUsearray, deleting user-owned hooks and potentiallyhooks.json. It now removes only the managedrtk-hook codexentry. Regression test added. - Codex Principles unwire accepts malformed
hooksconfig: A non-objecthooksvalue was silently left in place while ownership metadata was removed. Unwire now returns a config error without changing either file or manifest. - Agent selector mismeasures Unicode hints: Hint truncation counted Unicode characters instead of terminal display columns; wide CJK characters or emoji could still wrap a selector row. It now uses Unicode display width.
v1.0.1
Fixed
- Agent selector corrupts after terminal wrapping: Long agent URLs could wrap on narrow terminals, while the interactive redraw assumed every option consumed one row. URLs are now truncated to the current terminal width so redraw height stays correct.
- Agent selector corrupts on terminal events: The selector reused a fixed number of cursor-up operations between frames; terminal resize or focus events could leave stale frames on screen. It now renders in an alternate screen and clears each frame.
- Agent selector columns drift in raw mode: Raw terminal mode disables automatic LF-to-CRLF conversion, so option rows began at the previous row's ending column. Selector rows now explicitly return to column zero.
- UI progress bar splits multi-word agent names:
Progress::stopsplit status messages on the first space, causing multi-word agent labels (Claude Code,GitHub Copilot,Devin / Cascade,Warp / Oz) to wrap after the progress bar (✔ Claude [████...] 100% Code). Addedparse_label_and_tailinsrc/util/ui.rswhich matches against known agent/tool labels (sorted longest-first) before splitting. Unit tests added. (@jondmarien in #23) - Doctor probe misreports managed hooks as missing:
MANAGED_HOOKSinsrc/util/probe.rsdid not listcodex-perm-hookorcontext-mode-hook, causingtoksave doctorto treat them as unmanaged external binaries and report "binary not found". Both now registered. (@jondmarien in #23) - Caveman version mismatch after update:
installed_version()always returned the hardcoded embedded fallback1.9.1, causingtoksave doctorto perpetually report an upgrade available. Now writes the fetched release version tocache_dir()/caveman.versionon install and reads it first. Bumped embeddedCAVEMAN_SKILL_VERSIONto1.10.0. (@jondmarien in #23) - Legacy Bun binary paths persist across upgrades: Old
/$bunfs/root/toksavevirtual paths in~/.claude/settings.jsonand~/.codex/hooks.jsonpersisted because rewiring logic was not stripping stale paths. Claudeoverride_claude_rtk_hooknow replaces any existingrtk-hook claudecommand (including legacy paths) with the active binary path. Codex RTK wiring usesmerge_hook_groupfor deduplication. (@jondmarien in #23) - Codex
unwire(Principles)leaves orphanPermissionRequesthook:wire(Principles)added acodex-perm-hooktoPermissionRequest, butunwire(Principles)only calledremove_ownerwithout cleaning the hook. Now removes managedPermissionRequestentries and prunes emptyhooksobject.
Changed
- Status coloring in
doctorandupdate:all tools wiredand up-to-date versions now print in green;not installed/not on PATHin red; outdated versions in yellow. Consistent across both commands. (@jondmarien in #23) - Generic
merge_hook_group/remove_hook_group: Refactoredmerge_pretool_useandremove_pretool_useinsrc/util/json.rsto delegate to genericmerge_hook_group/remove_hook_groupthat work with any hook key (PreToolUse,PermissionRequest, etc.). Backward-compatible — existing callers unchanged. - CI
fail-fast: false:.github/workflows/ci.ymlmatrix strategy no longer cancels sibling OS jobs on single-job failures. (@jondmarien in #23)
Added
- Wiring matrix heatmap: Added
scripts/generate_wiring_heatmap.py(stdlib-only) that generates color-coded SVG heatmaps (assets/wiring-matrix-dark.svg,assets/wiring-matrix-light.svg) of the tool x agent wiring matrix. README updated with<picture>element for light/dark theme support. (@jondmarien in #23)
Contributors
Thanks to community contributor:
- @jondmarien: Fix UI label splitting, doctor probe hooks, Caveman update detection, legacy path cleanup, status coloring, CI matrix, wiring heatmap (#23)
v1.0.0
Added
- 100% Native Rust Core: Complete rewrite from TypeScript/Bun to Rust 2024 edition — delivering zero-runtime dependency, faster execution, memory safety, and standalone cross-platform binaries.
- Explicit
initsubcommand:toksave initnow accepted explicitly (was default-only). - Preflight git/node dep warning: Before
init, toksave warns when github-channel tools need git or npm-channel tools need a minimum Node version, and skips those tools with a remediation hint instead of failing mid-install. - Install failure diagnostics: Failed tool installation now reports which command failed, its exit code, captured stderr tail, and remediation hints (ensure Node 18+ / npm / deno are on PATH, check proxy, retry).
- Per-tool phase progress:
toksave install <agent>shows per-tool progress phases (resolve, install, wire) instead of one indeterminate spinner. - Runtime probe in
toksave doctor: Probes each agent's installed binaries and hooks at runtime — detects missing binaries, Windows backslash paths that break Git Bash hooks, and hooks that fail to run (3s live-run check); reportshooks.json/config.toml/mcp.jsonMCP server entries pointing at missing binaries. No hooks are modified. - Codex
config.tomlMCP probe: Reads[mcp_servers.*]fromconfig.tomlviatoml_edit(not regex) to detect broken MCP entries alongside the JSON-based walker. expected_bin_dirs+ PATH prepend intoksave init: The workspace PATH is prepended with agent binary dirs so freshly installed tools resolve in new shells.- Legacy fence cleanup: Old TokSave instruction fences (non-toksave markers) are stripped when regenerating
AGENTS.mdblocks. - Owner-consolidated
AGENTS.mdupdates: Rewrites group existing agent/RTK owners into one TokSave block instead of appending duplicates; a full-filewrite_ownerno longer overwrites the entireAGENTS.md.
Changed
initdetects agents before installing tools: Agent detection and selection now run before any tool installation. When no agent is detected,toksave initprints "Nothing selected." and exits without touching the filesystem (previously tools were installed and wired first, then "Nothing selected."). Selection options (all/high/leave-all) apply to upgrade runs; a fresh machine with no agents short-circuits cleanly.- Rust edition
2021→2024: Upgraded the crate to the 2024 edition.env::set_var/remove_varbecameunsafein 2024; call sites inrunmcp/detectgotunsafeblocks with inlined safety comments (main-thread before thread spawn), and env-mutating tests gotunsafeblocks guarded byenv_test_lock/ENV_LOCK.
Fixed
- RTK hook no longer clobbers user PreToolUse hooks: Warp, Devin, and Droid wire/unwire used to replace the whole
PreToolUsearray or drop the key outright, destroying user-owned hooks. Wire now keeps existing entries, replacing only toksave-managed ones (matched by command marker), and unwire drops only ours — removing the key only when it becomes empty. - Windows: bare npm shims now spawn correctly: Tools installed by npm ship an extensionless POSIX shell shim (
context-mode) next to a.cmdtwin. TokSave used to prefer/resolve the bare shim and spawn it directly, failing withos error 193 (%1 is not a valid Win32 application). Command resolution now prefers PATHEXT-qualified candidates on Windows, andrunmcp/process spawning picks the.cmdtwin — fixingtoksave runmcp <npm-tool>,toksave index, and version probes on Windows. updateinstalls missing npm tools:latest_version()read.versionfrom the full npm registry document, which only exists on the/latestand versioned endpoints — so every npm tool resolved as "up to date" andtoksave updatenever installed missing tools. Now fetched viaregistry.npmjs.org/<pkg>/latest; missing tools are reported as(not installed)and installed.- Uninstall drops empty config files and ghost keys: After uninstall, agents left empty
{}JSON configs, empty[mcp_servers]TOML tables, and emptyhooks/mcpServersobjects behind (opencodeconfig.json, codexconfig.toml+hooks.json, copilot/droid/devin/warpmcp.json+hooks.json,.claude.json,.claude/settings.json). Unwire now prunes empty top-level JSON containers (write_json_pruned), prunes empty TOML tables recursively (prune_empty_tables) and deletes the file when it serializes to{}/empty (write_toml_pruned/write_json_pruned), while preserving user-owned keys like opencode's$schema. - Invalid
toksave install <tool>remediation hints: Health-check and repair hints referencedtoksave install <tool>, butinstallis not a clap subcommand (error: unrecognized subcommand). All hints now point to the real commandtoksave init -t <tool>. updatemislabeled "up to date" when latest couldn't be resolved: A tool that resolved its installed version but failed to fetch the latest (offline / GitHub rate limit) printed→ ? (up to date), silently claiming freshness. It now prints? (latest unknown — could not check).
v0.8.5
Added
- Warp / Oz Agent Support: Added full support for Warp / Oz AI Agent (
warp/ozCLI flag) with MCP (mcp.json) andAGENTS.mdinstructions wiring across all 6 tools, with official brand iconassets/agents/warp.png. (@jondmarien in #22)
Fixed
- Warp hooks.json never clobbered on wire/unwire:
loadHooks()returned{}for an unparseablehooks.json, so the next write destroyed the user's hooks. It now returnsnullon malformed JSON and wire/unwire/verify skip the write.removeHookGroup()previously removed the entire matched hook group, deleting co-located user hooks — it now removes only the TokSavertk-hookentry and keeps groups that still hold user hooks. Regression tests added. - Immutable sort without spread copy: Replaced
[...owners].sort(...)withowners.toSorted(...)in agent instructions rendering (ES2023, no intermediate array allocation).
Changed
- Dead code removal & command refactors: Removed unused exports and deprecated helpers across the codebase (~720 lines):
src/util/progress.ts,src/util/separators.ts, barrel filessrc/agents/index.tsandsrc/commands/index.ts,src/content/rtk-rules.ts, plus unused functions injson,toml,colors,errors,manifest,mcpspawn,npm,paths,unified-block,version, anddownloadutilities. Refactored command approval (copilot) to use aSet, agent detection ininitto use aMap, anddisable/doctor/uninstall/updateto usereduce/Setfor clearer, faster logic. EnablednoImplicitAnyintsconfig.jsonfor stricter type checking.
Contributors
Thanks to community contributor:
- @jondmarien: Add Warp / Oz agent support with MCP and AGENTS.md wiring, official brand icon (#22)
v0.8.4
Added
- Devin / Cascade Agent: Added full support for Devin / Cascade AI agent (
devin/cascadeflag) with MCP (mcp.json) andAGENTS.mdinstructions wiring for all 6 tools. (@jondmarien in #19)
Fixed
runmcpCLI argument parsing: Added.argument("[args...]")and.allowExcessArguments(true)torunmcpcommand registration in Commander. Prevents "too many arguments for 'runmcp'" failures when agents launch MCP servers with parameters. (@jondmarien in #19)- Bare MCP tool binary resolution:
runmcpnow automatically resolves bare tool names (e.g.codegraph,context-mode) to their installed executables on PATH or user bin directories (~/.local/bin, mise shims, etc.). (@jondmarien in #19) - GUI agent PATH expansion:
runmcpnow ensuresPATHincludes user tool paths (~/.local/bin, mise node shims, etc.) so GUI desktop agents with minimal PATH environments can locatenode,codegraph, andcontext-mode. (@jondmarien in #19) - Caveman install fallback:
cavemantool installation now succeeds gracefully even if global npm installation fails or npm is absent, ensuring instruction-based skill wiring still completes. (@jondmarien in #19) toksave doctordeep MCP verification:doctornow performs executable-level verification (checkAgentMcpHealth) forcodegraphandcontext-mode, catching unresolvable or crashing MCP configurations rather than relying solely on config file presence. (@jondmarien in #19)
Contributors
Thanks to community contributor:
- @jondmarien: Add Devin/Cascade agent support, fix runmcp CLI args & PATH expansion, doctor deep MCP checks (#19)
v0.8.3
Fixed
- Manifest recorded before verify:
initcalledrecordWire()beforeverifyTool(). Failed wiring still left a manifest entry. Now records only after verify passes. - RTK verify required PATH: Claude Code and OpenCode
verify("rtk")requiredisOnPath("rtk")in addition to the hook/plugin. Fresh installs with RTK not yet on PATH failed verify after a successful wire. Verify now checks hook/plugin only; PATH health stays in doctor. - Copilot IDE instructions stale after unwire: Unwire for codegraph/context-mode/caveman/ponytail/principles removed CLI owners but did not re-sync
.github/copilot-instructions.md. Now callssyncCopilotIdeInstructions(); empty body deletes the IDE file.
v0.8.2
Added
- Verify-after-wire regression test: 6 new tests confirm dry-run wire does not pass verify for any agent×tool combo. Exposes missing dryRun guards in wire functions.
Fixed
- WireCaveman dryRun writes owner marker: Claude Code and Antigravity
wireCaveman()calledwriteOwner()even withdryRun: true, causing verify to falsely report caveman as wired.writeOwnernow correctly skipped on dryRun.