Changelog
All notable changes to this project are documented here.
The format follows Keep a Changelog, and this project adheres to Semantic Versioning.
3.0.0 — 2026-10-19
Section titled “3.0.0 — 2026-10-19”- Importing a
socks4://orsocks4a://URL keeps that protocol. Previously everysocks*URL was stored assocks5, so a SOCKS4 proxy was dialed with a SOCKS5 handshake. - Shell wrappers preserve command and child-process exit codes after handling
the dashboard handoff. Failures from
env onalso reach the caller.
Changed
Section titled “Changed”- Breaking: the command is now
tspm, including Homebrew installs andcargo install tspm. Runeval "$(tspm init zsh)"(orbash) in your shell startup file. Theproxyfunction andTSPM_*variables keep their names. - Breaking: configuration lives in
~/Library/Application Support/tspm/on macOS and${XDG_CONFIG_HOME:-~/.config}/tspm/on Linux. The program does not read or migrate the previous directory. To keep your profiles, move that directory yourself and update any absoluteconfig_pathinsettings.json. Explicit config/settings path overrides still work. - Shell handoff and debug files are
~/.tspm-eval,~/.tspm-debug-enabledand~/.tspm-debug.log. Previous files are ignored. Release archives and the Homebrew formula use thetspmname; the Rust library import istspm. - Homebrew selects the native macOS or Linux archive for arm64 or x86_64. The release workflow verifies all four archives and checksums before tagging and updates all four downloads in the formula together.
- Update
dirsfrom 6 to 7; both versions usedirs-sys0.5. - Update locked
clapto 4.6.7,clap_completeto 4.6.11,futuresto 0.3.34,reqwestto 0.13.5,serde_jsonto 1.0.154,thiserrorto 2.0.21 andtokioto 1.53.3.
2.4.0 — 2026-10-18
Section titled “2.4.0 — 2026-10-18”Security
Section titled “Security”- Update locked
rustlsfrom 0.23.45 to 0.23.46 to address RUSTSEC-2026-0346, RUSTSEC-2026-0347, RUSTSEC-2026-0348 and RUSTSEC-2026-0349. These describeDebugoutput of TLS secrets, application data sent to the outer server after an Encrypted Client Hello rejection, a large allocation during certificate decompression before authentication, and a key-exchange downgrade from an unauthenticated ServerHello.
- Install:
cargo install tspminstalls this release from crates.io. The command is stillterminal-session-proxy-manager. An earliercargo install --gitalready uses that binary; remove it withcargo uninstall terminal-session-proxy-managerbefore installingtspm.
2.3.1 — 2026-10-14
Section titled “2.3.1 — 2026-10-14”Documentation diagrams, more reliable website navigation and theme controls, and dependency security fixes.
Security
Section titled “Security”- Update locked
quinn-protofrom 0.11.17 to 0.11.18 to address RUSTSEC-2026-0338, RUSTSEC-2026-0340 and RUSTSEC-2026-0343, which describe panics in its QUIC stream, ACK-delay and datagram handling. This optional dependency is not enabled in the CLI’s current feature set. - Website: Remove the vulnerable
bracesdependency (GHSA-vfj7-8cjw-p6xm) from the documentation build by using Picomatch for thestarlight-llms-txtpage matcher, with compatibility tests.
- Docs: Bilingual diagrams explain where proxy environment settings apply,
how
proxy onupdates the current shell, and how the dashboard hands its selected profile back to the shell. - Website: Mermaid diagrams follow the active theme and open in a dialog with zoom, fit, drag, touch pan/pinch and keyboard controls. Closing the dialog restores focus to its opener; browser zoom shortcuts stay available.
- Docs: Refresh the Views counter image URL in both READMEs so GitHub requests a fresh badge instead of reusing the previous image-cache entry.
- Website: Documentation stays visible after Back/Forward navigation, including pages restored from the browser’s history cache. Cancelled page transitions no longer leave outgoing content hidden.
- Website: Light/Dark/Auto controls share their selection across the page, browser tabs and history navigation, and keep working when storage is blocked. Rapid theme changes safely replace an unfinished transition; reduced-motion preferences are respected.
Changed
Section titled “Changed”- Website: Documentation headers use the homepage logo and title on desktop. Mobile navigation and table of contents share a glass background; theme and language controls, GitHub buttons, sidebar groups and contents entries have clearer layout and boundaries.
- Contributing: Agent guidance now links to focused path rules and skills; release recovery, verification and ownership references match the current workflows. Completed planning archives were removed.
2.3.0 — 2026-09-16
Section titled “2.3.0 — 2026-09-16”The release that gives the project a home on the web. A bilingual documentation site is published from this repository’s own Markdown and works on phones as well as desktops. The CLI’s output is reworked for terminals and scripts that do not want decoration, and a TLS advisory is fixed.
Upgrading? Three output changes can affect scripts that read what the tool
prints — they are marked Breaking for scripts under Changed. Nothing
changes in config.json, settings.json, the command names, flags or exit
codes.
Security
Section titled “Security”- CLI:
rustlsupdated to 0.23.45 for RUSTSEC-2026-0285: TLS 1.3 handshake messages sent across an encryption-level boundary were accepted instead of rejected.reqwestuses it for every HTTPS request the tool makes —status,ping,speedtest,monitor, imports from a URL. - Website: The site’s build dependencies are updated past advisories in
astro(critical: remote code execution through AVIF image optimisation),sharp,svgoandjs-yaml. Astro moves to 7.3.2. These affect only the site build, not the CLI.
Documentation website
Section titled “Documentation website”- Website: A documentation site at
lebedevkondakovsergeyvach.github.io/Terminal-Session-Proxy-Manager,
in English and Russian (
/ru/), built with Astro Starlight. Its pages are generated fromREADME*.md,docs/*.md,CONTRIBUTING.mdand the changelogs at build time, so the site and the files on GitHub cannot drift apart. - Website: A home page with the project’s features side by side with terminal screenshots in light and dark variants, and quick-start tiles.
- Website: Material Design 3 styling whose whole palette is derived from the project’s rust orange, in light and dark, with smooth transitions between pages that fall back to a plain swap when reduced motion is requested.
- Website: A three-way theme switch — light, auto (follows the system) and dark — with a circular reveal when the theme changes.
- Website: Full-text search, with quick links to the main guides while the search box is empty, and a search interface translated into Russian.
- Website: Install instructions in tabs (Homebrew, Cargo, prebuilt binary), step-by-step guides, colour-coded callouts, terminal-framed code blocks with a copy button, and screenshots that zoom on click or tap.
- Website: Works on phones and touch screens:
- wide tables scroll sideways instead of being cut off;
- tab labels wrap on narrow screens instead of running off the edge;
- buttons, tabs and selects are at least 44px tall to tap;
- hover effects apply only with a mouse, so a tapped card no longer stays raised;
- the header fits a 320px-wide screen;
- on phones the theme and language controls of a docs page live in the menu.
- Website: A round home button beside the site title on every docs page, on phones and desktops, labelled “Home” / “На главную” for screen readers.
- Website: The project’s logo in the header of the home page, its own favicon, and an icon for home-screen bookmarks on iOS.
- Website: A custom 404 page in both languages, with links back into the documentation and a way home on every screen width.
- Website: A preview image for links shared on social networks and in
messengers, and
llms.txtfor machine readers. - Website: The build fails on a broken internal link, so a dead link cannot reach the published site.
Documentation
Section titled “Documentation”- Docs:
CHANGELOG.ru.md— the release history in Russian, published at/ru/changelog/.README.ru.mdnow links to it rather than to the English file. - Docs:
docs/SHELL_INTEGRATION.mdexplains why the shell function is needed, with a sequence diagram;docs/USAGE.mdopens with the subcommands grouped into four categories. - Docs: The READMEs carry a badge linking to the documentation site.
CLI and configuration
Section titled “CLI and configuration”- Config: OpenAI (
https://status.openai.com/api/v2/status.json) and Anthropic (https://www.anthropic.com) joined the defaultping_targets. Existing configs keep their own list. - CLI: After switching,
proxy switchandproxy use <key>end the confirmation line with[ON]or[OFF]— whether proxy variables are set in this shell. Through theproxyshell function,[ON]means the new profile has just been applied;[OFF]means it is saved and waits forproxy on. - CLI: The
proxy switchmenu is cleared from the screen when it closes, whether you chose a profile or cancelled. - CLI:
proxy pingprints HTTP 2xx responses in green and everything else in yellow.
Automation and contributing
Section titled “Automation and contributing”- CI:
website.ymlgates every pull request that touches the site or the documents it is built from — it runs the generator’s tests, builds the site and fails on a dead internal link.pages.ymlpublishes the site frommain. - CI: Dependabot watches the website’s npm dependencies as well as Cargo and the GitHub Actions.
- CI: The branch policy requires
CHANGELOG.ru.mdto change wheneverCHANGELOG.mddoes, since both are published. - Contributing: Git hooks in
.githooks/, enabled once per clone withgit config core.hooksPath .githooks.commit-msgrejects tool attribution lines (Co-Authored-By:, “Generated with …”);pre-pushrefuses pushes tomainand tag pushes, since merging a release branch is what publishes. - Contributing: One set of instructions for AI coding agents.
AGENTS.mdis the shared contract;CLAUDE.mdand.cursor/rules/are the entry points for Claude Code and Cursor; area rules live in.claude/rules/. The task skills in.claude/skills/gainstarlight-website, for work on the site, andagent-docs-audit, which checks the instruction set for drift..mcp.jsondeclares thecontext7andastro-docsdocumentation servers.
Changed
Section titled “Changed”CLI output
Section titled “CLI output”- CLI — Breaking for scripts:
proxy onandproxy offno longer print a confirmation line. They emit only the shell statements to be evaluated, soeval "$(proxy env on)"is now silent. A script that looked for that confirmation needs updating. - CLI — Breaking for scripts: the line
proxy use <key>andproxy switchprint after switching ends with the new[ON]/[OFF]tag, so its shape has changed. - CLI — Breaking for scripts:
proxy pinglabels a non-2xx responseWARN (… ms)in yellow; it used to beOKin green, like a success. - CLI: Emoji are gone from the translation strings and from the headers of
the reporting commands —
ping,diagnose,monitor,git,import,benchmark,speedtest— and from the dashboard’s port indicator. The prompt marker and the dashboard’s title bar keep theirs. The status labelsproxy pingprints are translated now, rather than fixed English. - CLI: The rule printed between report blocks is a plain line of
-instead of a bold cyan line of=, and report headers no longer start with spaces.
Documentation
Section titled “Documentation”- Docs:
docs/*.mdandCONTRIBUTING.mdare plain CommonMark, readable on GitHub as before. The site’s tabs, cards, steps and callouts are written as<!--site:…-->comments, which GitHub renders as nothing and the site generator expands. - Docs:
docs/CONFIGURATION.mdlists the full defaultping_targets, and its field table names every command that reads them. - Docs: Corrected descriptions of what several commands do:
benchmarktests profiles one after another, probing each profile’s ping targets at once — not every profile concurrently;Spaceinproxy dashsaves the selected profile as active without leaving; it does not update the shell, onlyEnterdoes;monitor, on a failed health check or with no proxy variable set, saves the fastest reachable profile as active but does not change the shell it runs in;profile setmakes the profile active without re-applying the shell’s variables;diagnoselists the main proxy variables, not every oneproxy onsets.
- Docs: The release notes in
.ai/GIT_WORKFLOW.mddescribe the pipeline as it runs: the tag is created after the binaries build, so a failed build leaves no tag behind, and the recovery steps follow from that.
Dependencies
Section titled “Dependencies”- CLI:
chacha200.10.1, which was yanked from crates.io, is replaced by 0.10.2.
Contributing
Section titled “Contributing”- Contributing: A change to
docs/, the READMEs,CONTRIBUTING.mdor a changelog also has to pass the site build (cd website && npm ci && npm test && npm run build), because those files are the site’s content. - Contributing: The changelog rule in
CONTRIBUTING.mdmatches what CI enforces — changes toshell/andconfigs/need an entry too, in bothCHANGELOG.mdandCHANGELOG.ru.md. The pull request template uses the same--lockedchecks andnpm cias the rest of the documentation. - Contributing:
CLAUDE.mdimportsAGENTS.mdinstead of only linking to it, so Claude Code actually loads the project rules; the skills moved from.agents/skills/(now symlinks) to.claude/skills/, where Claude Code finds them. Therelease-managerskill updates the changelog link footer, andcargo-auditasks where a security entry belongs once a release is cut. - CI: The branch policy compares a pull request against its merge base, so a documentation-only pull request is no longer blocked by other commits on the release branch.
- CI: Workflows default to read-only repository access; the
cargo auditjob gets only the extra permission it needs to report its results, which it previously failed to do.
Removed
Section titled “Removed”- CLI: The
env_on_msgandenv_off_msgtranslation keys, unused sinceproxy onandproxy offstopped printing a confirmation. - Contributing: The
aur-packagerskill — the project publishes no AUR package — and the unused.agents/mcp_config.json.
2.2.2 — 2026-08-21
Section titled “2.2.2 — 2026-08-21”- Release Automation: Retry the Homebrew tap update with the fixed tag-name reference.
2.2.1 — 2026-08-21
Section titled “2.2.1 — 2026-08-21”- Release Automation: Fixed a release issue where the Homebrew formula was not successfully updated during the v2.2.0 release. Triggering a patch release to force the
mislav/bump-homebrew-formula-actionto run correctly and synchronize the tap.
2.2.0 — 2026-08-20
Section titled “2.2.0 — 2026-08-20”A correctness and hardening release. Several long-standing bugs are fixed, including one that could destroy a user’s saved profiles, and one shell injection. Two changes affect scripts — see Changed.
- A malformed
config.jsonno longer destroys your profiles. The first attempt at this fix was incomplete and was caught in review:load()stopped overwriting the file, but the next command that saved —profile set/use/ remove,import, or Enter in the dashboard — still wrote the fallback defaults straight over it. A config that failed to parse is now marked as such, and any attempt to save over it fails with an explanation. Read-only commands keep working so the file can still be diagnosed. The same applies tosettings.json, where overwriting also silently droppedconfig_pathand pointed the tool at a different config. env onexits non-zero when no profile is active. It printed an error and exited0, soproxy_on && deploycarried on against an unproxied shell.profile setno longer resets an existing profile’s protocol.--protocolhad a default, so changing only the port silently rewrote anhttpprofile tosocks5.- IPv6 profiles produce usable URLs. A bare
::1was accepted but rendered ashttp://::1:1080, which no client can parse. Literals are now bracketed in URLs and left bare in the JVM-Dhttp.proxyHost=options, as each requires. - A proxy URL that cannot be applied is no longer treated as success. The
error from building the proxy was discarded, so the request went out
directly:
monitorreported a broken tunnel as healthy,benchmarkranked the broken profile fastest andbestthen selected it, andstatusand the dashboard showed the machine’s real IP as though it were the proxy’s. - The dashboard no longer corrupts its own display. Pressing
sran a benchmark whose progress spinner writes to stderr on a timer, interleaving with ratatui’s frames. - The dashboard selection no longer jumps when benchmark results arrive. The list re-sorted without remapping the cursor, so Enter applied whichever profile had slid under it.
- The shell wrapper reports the real exit status. The re-apply step became
the function’s own status and inverted it:
proxy use workreturned failure on success with the proxy off, andproxy use nopereturned success on failure with it on. runno longer lets the child command retarget the manager. The pre-parser scanned the whole command line, soproxy run mytool --lang enchanged which config the manager itself loaded.speedtestreports a dropped connection instead of a confident number. A mid-stream transport error was indistinguishable from a clean end of body.diagnoseresolves hostnames. The socket check only accepted IP literals, so a profile with a hostname always reported its port as closed.load()overwrote an unparsable config with the built-in defaults, so a single stray comma silently discarded every profile. A file that exists but fails to parse is now reported on stderr and left byte-for-byte intact. The same applies tosettings.json.proxy --helpno longer prints the raw keycmd_debug. Thedebugsubcommand had no translation. A test now asserts every subcommand has a description in both languages.proxy runaccepts flags for the child command.proxy run curl -sS URLfailed with “unexpected argument ‘-s’”; arguments after the program name are now forwarded verbatim.-hmeans--helpeverywhere again. It was bound to--hostonprofile set, shadowing the help flag on that subcommand.- The dashboard no longer panics on an empty profile list. Pressing an arrow
key computed
len() - 1on an empty list, which panicked inside the alternate screen and left the terminal unusable. - The terminal is restored however the dashboard exits. An RAII guard plus a panic hook replace the previous success-path-only cleanup, which left users in raw mode on the alternate screen after any error or panic.
- The dashboard exports the same variables as
env on. It set onlyHTTP_PROXY,HTTPS_PROXYandALL_PROXY, silently dropping the lowercase names and the JVM options. - Importing an unrelated JSON file no longer invents profiles. Because every field of the config has a serde default, any JSON object parsed successfully and “imported” the two built-in defaults.
git on/git offreport failures. The exit status ofgit configwas discarded, so a missinggitbinary still printed a success message.monitorno longer treats a 404 as healthy. It now probes a configurablehealth_check_urlthat answers204, instead of special-casing one API’s error response.- Benchmark results distinguish an unreachable proxy from a merely slow one; the
previous
9999sentinel conflated the two. NO_COLORis honoured per spec (any non-empty value) rather than only when set.
Security
Section titled “Security”- Shell injection in
env onand the dashboard hand-off. Output consumed byeval "$(...)"interpolated profile fields without quoting, so a host value from an edited or imported config could execute arbitrary commands. All values are now POSIX single-quoted, verified by a test that evaluates the generated script in a real shell. - Profiles are validated before being persisted, from
profile setand from imports alike: the host is checked against a character allowlist, the port must be non-zero, and the protocol must be one this tool supports.
- A documented branch model —
main<-release/X.Y.Z<- task branches — described in.ai/GIT_WORKFLOW.mdand enforced by.github/workflows/branch-policy.yml. Pull requests are checked for branch naming, a valid head/base pairing, and a changelog entry. - Releases publish themselves. Merging a release branch into
mainmakes CI verify the build, create thevX.Y.Ztag, build the four target binaries and bump the Homebrew tap. Tagging by hand still works and takes the same path. --config-file,--settings-fileand--langglobal options, with matchingTSPM_CONFIG,TSPM_SETTINGSandTSPM_LANGenvironment variables. This makes the tool scriptable and lets tests run in full isolation.- Configurable endpoints in
config.json:ipv4_api,ipv6_api,health_check_urlandspeedtest_url. These were hard-coded. - Full translations for
speedtest,monitor,gitand the TUI dashboard, which previously printed English regardless of the selected language. CONTRIBUTING.md,SECURITY.md,AGENTS.md,CLAUDE.md, issue and pull request templates, and Dependabot configuration.- Tests grew from 9 to 126, including an end-to-end suite in
tests/cli.rsthat drives the real binary against an isolated config.
Changed
Section titled “Changed”Two changes may affect existing scripts:
profile useandprofile removeexit non-zero on an unknown key. They printed an error and exited0, soproxy profile use "$p" || fallbackalways took the success branch.profile set --hostno longer has the short form-h. Use--host.
Also changed:
exportfails instead of printing nothing when no profile is active, soproxy export envfile > .envcannot silently truncate the file.settings set --langrejects an unknown language instead of silently selecting Russian.- The unused
enabledfield was removed fromconfig.json. Existing configs keep loading; the field is ignored. runpropagates the child’s exit code exactly.- Edition 2024, MSRV 1.88, and dependency upgrades: clap 4.6, tokio 1.48,
reqwest 0.13, thiserror 2.0, dirs 6.0, colored 3.1, indicatif 0.18,
dialoguer 0.12. The macOS config directory is unchanged by the
dirsupgrade. - Release builds use fat LTO, one codegen unit and stripped symbols.
- The release workflow tags only after every binary has built. Tagging first meant a failed build left the tag pushed with nothing published, and every retry then saw the tag and skipped the release permanently.
- CI gained an MSRV job, a
cargo auditjob,--lockedbuilds and a docs build. Releases now verify the tag matches the crate version, shipaarch64Linux binaries, and publish SHA-256 checksums.
2.1.1 — 2026-08-18
Section titled “2.1.1 — 2026-08-18”- Bilingual CLI help messages.
Changed
Section titled “Changed”- Default configuration uses safe generic profiles.
