7.7 KiB
AGENTS.md
Purpose
This repo is a small Python Flask service that converts subscription links (vmess, vless, trojan, ss) into local SOCKS5 proxies via xray-core.
Almost all backend logic, API routes, and the inline web UI live in main.py.
Agents should prefer minimal, in-place changes over architectural rewrites.
Repository Layout
main.py: app entrypoint, dataclasses, parsers, proxy manager, schedulers, Flask routes, and embedded HTML/CSS/JS.requirements.txt: runtime dependencies.start.sh: local bootstrap script.Dockerfile: image build.docker-compose.yml: recommended container run path.config.yaml.example: optional config sample.config/: persisted JSON state.data/: runtime files such as generated xray configs.bin/: xray binary/assets.
Extra Agent Rules
I checked for repo-specific agent instruction files:
.cursor/rules/: not present..cursorrules: not present..github/copilot-instructions.md: not present.
There are no Cursor or Copilot rules to merge into this file right now.
Environment
- Python: README says
3.10+. - Docker image:
python:3.13-slim. - Default web port:
8080. - App downloads
xray-coreon startup ifbin/xrayis missing. - Runtime state is persisted under
config/anddata/.
Setup Commands
Local environment
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
Run locally
python3 main.py
Run via helper script
chmod +x start.sh
./start.sh
Build Docker image
docker build -t airtosocks .
Run with Docker Compose
docker-compose up -d
docker-compose logs -f
docker-compose down
Build, Lint, And Test Reality
This repository currently has no formal lint or test setup.
- No
tests/directory was found. - No
pytestorunittesttest files were found. - No
ruff,black,isort,flake8,pylint,mypy,tox, ornoxconfig was found.
Agents should say this explicitly instead of pretending a missing command exists.
Verification Commands That Work Today
Syntax check
python3 -m py_compile main.py
Compile Python files
python3 -m compileall .
Manual app run
python3 main.py
HTTP smoke checks
curl http://127.0.0.1:8080/api/links
curl http://127.0.0.1:8080/api/subscriptions
curl http://127.0.0.1:8080/api/random
Container smoke checks
docker-compose up -d
curl http://127.0.0.1:8080/api/links
docker-compose logs --tail=200
docker-compose down
Single-Test Guidance
There is no real single-test command yet because there is no test suite.
If tests are added later, prefer pytest and document commands like:
pytest
pytest tests/test_parser.py
pytest tests/test_parser.py::test_parse_vmess
Until then, a “single test” means a targeted manual verification of the exact parser, route, or runtime behavior touched by the change.
Config Notes
Optional runtime config lives in config.yaml and currently supports:
port: 8080
check_interval: 600
When changing config behavior:
- Preserve compatibility for missing keys.
- Keep defaults aligned across code,
README.md, andconfig.yaml.example. - Do not silently rename config fields.
Code Style
The repo does not use an autoformatter today. Match the existing style unless the user asks for cleanup.
Imports
- Keep standard library imports before third-party imports.
- Do not reorder the whole import block for cosmetic reasons.
- Add new imports near related imports.
- Prefer explicit imports over wildcard imports.
Formatting
- Follow normal Python/PEP 8 conventions without broad reformatting.
- Use 4-space indentation.
- Preserve surrounding quote style; Python code here mostly uses single quotes.
- Avoid reflowing large inline HTML, CSS, or JS unless required.
- Keep diffs small and local.
Types
- Continue the existing
typingstyle:Optional,List,Dict,Tuple,Any. - Add type hints for new helpers when practical.
- Use
@dataclassfor record-like state models. - Do not introduce a new validation or typing framework without a concrete need.
Naming
snake_casefor variables, functions, and methods.PascalCasefor classes.UPPER_SNAKE_CASEfor module constants.- Use descriptive domain names like
subscription_id,socks_port,last_check,available_count.
Data Modeling And Persistence
- Persist structured state through dataclasses and
asdict(...). - New persisted fields need safe defaults so old JSON continues to load.
- Consider compatibility with existing files in
config/. - Do not casually rename persisted fields.
Error Handling
- Follow the existing pattern: catch failures near parsing, file I/O, network calls, and subprocess operations.
- Use
logger.error(...)orlogger.warning(...), then return a safe fallback or JSON error. - Avoid crashing daemon threads for recoverable problems.
- Prefer specific exceptions when obvious, but broad
except Exception as eis already common here. - API handlers should return meaningful JSON error payloads with sensible HTTP status codes.
Logging
- Use the module-level
logger, notprint. - Keep log messages short and operational.
- Include useful identifiers such as node name, subscription name, or port.
- Do not log secrets or full credentials from proxy links unless absolutely necessary.
Concurrency And Shared State
ProxyManagerprotects mutable state withthreading.RLock; preserve that discipline.- Be careful when changing
nodes,subscriptions,pools,used_ports, orxray_processes. - Keep background threads daemonized when matching the current pattern.
- Do not introduce async or heavier concurrency models for small tasks.
Files, Processes, And Runtime Data
- Runtime files belong under
config/ordata/. - Keep xray config generation deterministic and JSON-serializable.
- Follow the existing
subprocess.Popen(...)pattern for xray processes. - Release ports and clean up subprocess state on failure paths.
Flask And API Conventions
- Keep Flask route handlers thin.
- Put behavior in
ProxyManageror small helpers rather than in the route body. - Return
jsonify(...)for API responses. - Validate request JSON defensively.
- Keep API response shapes stable unless a breaking change is explicitly requested.
Frontend Conventions
- The frontend is intentionally inline inside the
/route. - For small UI changes, edit the embedded HTML/JS directly instead of adding a frontend build system.
- Preserve the current fetch-based interaction pattern.
- Keep the existing visual language unless the task asks for redesign work.
Comments And Docs
- Existing comments/docstrings are short and often Chinese; match the surrounding language in touched code.
- Add comments only when behavior is not obvious from the code.
- Update
README.md,config.yaml.example, and this file when commands or behavior change.
Change Strategy For Agents
- Prefer surgical edits.
- Avoid splitting
main.pyinto modules unless explicitly requested. - Respect persisted data compatibility.
- Ignore unrelated runtime files unless the task specifically involves them.
- If you add tests or lint tooling, immediately document the new commands here.
Recommended Post-Change Checks
For most Python-only changes:
python3 -m py_compile main.py
For API behavior changes:
- Start the app with
python3 main.py. - Hit the affected endpoint with
curl. - Confirm there is no traceback and the response shape is correct.
For Docker-related changes:
docker build -t airtosocks .
docker-compose up -d
curl http://127.0.0.1:8080/api/links
docker-compose down