Contributing
Это содержимое пока не доступно на вашем языке.
Thanks for taking the time. This is a small project, so the process is short.
Getting set up
Section titled “Getting set up”Requires Rust 1.88 or newer (edition 2024). Install via rustup.
-
Clone the repository
Terminal window git clone https://github.com/LebedevKondakovSergeyVach/Terminal-Session-Proxy-Manager.gitcd Terminal-Session-Proxy-Manager -
Build the project
Terminal window cargo build -
Run the tests
Terminal window cargo test
To try your build without installing it:
cargo run -- statuscargo run -- profile listBefore you open a pull request
Section titled “Before you open a pull request”Run what CI runs. Warnings are build failures.
cargo fmt --all -- --check && cargo clippy --all-targets --locked -- -D warnings && cargo test --lockedCI also passes --all-features; the crate defines no features, so this checks
the same code.
Things that are easy to get wrong
Section titled “Things that are easy to get wrong”Every user-facing string is translated. Use i18n.t("key"), or
i18n.format("key", &[a, b]) when it has {} placeholders, and add the key to
both locales/en.json and locales/ru.json. Tests assert the two files
define identical key sets, so a one-sided addition fails the build. Adding a
subcommand also needs a cmd_<name> key in both files, otherwise --help
prints the raw key.
Never overwrite a config that failed to parse. Defaults are written only
when a file is absent. Overwriting an unparsable config.json discards every
profile the user has.
Quote anything a shell will evaluate. The env on output is consumed by the
shell’s eval, and profile fields come from a file the user can edit or import
from a URL. Route values through proxy_env::shell_quote.
Failure means a non-zero exit code. Return Err rather than printing an
error and returning Ok — people write proxy profile use "$p" || fallback.
No private data in defaults. AppConfig::default may reference only
loopback addresses and well-known public endpoints.
Project Structure
Section titled “Project Structure”Директорияdocs/ Documentation markdown files
- …
Директорияlocales/
- en.json English translation keys
- ru.json Russian translation keys
Директорияsrc/
Директорияcmd/ Subcommands logic (ping, monitor, etc.)
- …
Директорияconfig/ Config loading and defaults
- …
- cli.rs CLI parsing tree (clap)
- main.rs Entry point
Директорияtests/
- cli.rs End-to-end binary tests
Директорияwebsite/ Astro Starlight documentation site
- …
- AGENTS.md Rules for AI agents
- Cargo.toml
Name tests as sentences describing the guarantee — using_an_unknown_profile_exits_non_zero
rather than test_profile — and assert one thing per test.
- Pure logic goes in a
#[cfg(test)] mod testsnext to the code. - Anything involving argv, exit codes, or files goes in
tests/cli.rs. - Integration tests must isolate state with
TSPM_CONFIG,TSPM_SETTINGSandTSPM_LANG; use theClihelper at the top oftests/cli.rs. A test must never touch the real~/.config. - Please don’t add tests that need network access. They are slow and flaky.
When fixing a bug, add the test that fails without the fix.
Documentation
Section titled “Documentation”If you change commands or configuration, update README.md and
README.ru.md, the matching file in docs/ and its .ru.md twin, and add a
CHANGELOG.md entry under Unreleased plus its CHANGELOG.ru.md twin.
Those same files are the documentation website. website/ holds an Astro
Starlight site whose pages are generated from them, so editing one is editing
the other. Two things follow:
-
Keep them plain CommonMark. They are read on GitHub as well as on the site, so no JSX and no
importline. Site-only structure — tabs, cards, steps, asides — is written as<!--site:...-->comments, which GitHub renders as nothing and the generator expands.website/AGENTS.mddocuments the syntax. -
Verify the site still builds:
Terminal window cd website && npm ci && npm test && npm run buildThe build regenerates every page and fails on a dead internal link, so a link to a document that has no page will stop it.
Branching
Section titled “Branching”main <-- release/X.Y.Z <-- feat/… fix/… docs/…Branch your work off the open release branch, not off main, and open the
pull request against that same release branch:
git checkout release/X.Y.Z && git pullgit checkout -b fix/dashboard-empty-listmain only ever moves when a release branch is merged into it, and that merge
publishes the GitHub release, the Homebrew tap and the tspm crate. CI rejects
a pull request that targets the wrong branch or
uses an unrecognised branch prefix. Valid task prefixes: feat/, fix/,
docs/, chore/, refactor/, test/, perf/, ci/, build/.
Full rules, including how a release is cut, are in
.ai/GIT_WORKFLOW.md.
Changelog
Section titled “Changelog”Any pull request touching src/, locales/, shell/, configs/ or
Cargo.toml needs an entry under ## [Unreleased] in CHANGELOG.md and the
matching entry in CHANGELOG.ru.md. CI checks both: a behaviour change without a
CHANGELOG.md entry fails, and so does a CHANGELOG.md change without its
Russian twin, because both changelogs are published. Docs-only and CI-only
changes are exempt.
Commits
Section titled “Commits”Conventional Commits: feat:, fix:,
docs:, chore:, refactor:, test:, perf:, ci:, build:.
Enable the repository’s Git hooks once per clone:
git config core.hooksPath .githookscommit-msg rejects tool attribution lines such as Co-Authored-By: or
“Generated with …”, and pre-push refuses pushes to main and tag pushes —
releases are cut by merging, and CI creates the tag.
Releases
Section titled “Releases”Maintainers only. Cutting a release means opening release/X.Y.Z from main,
setting the version and changelog, and merging it into main when ready — the
pipeline does the rest. Never tag by hand as part of another change.
Using an AI agent
Section titled “Using an AI agent”Point it at AGENTS.md first; it encodes the rules above in the
form agents follow. Claude Code loads it through CLAUDE.md; Cursor routes
to it through .cursor/rules/. Path rules and task skills live in .claude/;
.ai/PROJECT_OVERVIEW.md maps ownership and execution flows.
