# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview VMess domain rotator: fetch candidate domains from an API, select a preferred domain, write runtime artifacts, and optionally auto-commit/push runtime changes to a dedicated branch (`runtime-state`). ## Common Commands ### Validate scripts ```bash python3 -m py_compile scripts/domain_updater.py python3 -m py_compile scripts/update_vmess_links.py bash -n scripts/run_update_and_commit.sh bash -n scripts/install_debian.sh bash -n scripts/uninstall_debian.sh ``` ### Run domain selection once ```bash python3 scripts/domain_updater.py --config config.json ``` ### Run scheduler entrypoint (updater + runtime-state commit/push) ```bash bash scripts/run_update_and_commit.sh config.json ``` ### Update VMess links from selected domain ```bash python3 scripts/update_vmess_links.py \ --input ./nodes.txt \ --output ./nodes.updated.txt \ --domain-file ./runtime/current_domain.txt ``` ### Update only matching node names ```bash python3 scripts/update_vmess_links.py \ --input ./nodes.txt \ --output ./nodes.updated.txt \ --domain-file ./runtime/current_domain.txt \ --name-regex "(argo|cf|vm)" ``` ### Local runtime smoke test ```bash python3 -m http.server 8080 --directory runtime curl http://127.0.0.1:8080/current_domain.json ``` ### Debian systemd install/uninstall ```bash # Recommended default install (1h timer, push enabled, credential-helper mode) sudo bash scripts/install_debian.sh # Useful variants sudo bash scripts/install_debian.sh --interval 5min sudo bash scripts/install_debian.sh --git-push 0 sudo bash scripts/install_debian.sh --git-push-remote origin sudo bash scripts/install_debian.sh --git-http-username aurora --git-http-token-file /root/.config/vmess-token --git-use-credential-store 1 sudo bash scripts/uninstall_debian.sh sudo bash scripts/uninstall_debian.sh --keep-auth-files ``` ## Testing and verification status - There is currently no dedicated `tests/` directory or unit test suite. - Primary verification is syntax checks plus manual script runs. ## Architecture (big picture) ### 1) Domain selection pipeline `scripts/domain_updater.py` is the core pipeline: - Calls the configured API (`api` block in `config.json`). - Extracts candidates via `parser.field_paths`, `parser.json_paths`, or regex fallback. - Normalizes and de-duplicates domains/IPs. - Applies include/exclude filtering (`domain_filter`). - Optionally ranks records (`scoring`) using API fields/time windows or API order. - Optionally healthchecks candidates with TLS handshake (`healthcheck`). - Selects winner from scored/check results (`selection.top_n`). - Writes runtime artifacts under `runtime/`. - Resolves relative `output.runtime_dir` against the config file directory. - Falls back to `last_good_domain` from `runtime/state.json` when selection fails. ### 2) Runtime-state git automation `scripts/run_update_and_commit.sh` wraps the updater and git workflow: - Resolves git top-level robustly and skips git actions if not inside a git repo. - Requires non-empty `runtime/current_domain.txt` after updater run. - Copies runtime outputs into `runtime-state` (same branch or temporary worktree). - Commits only runtime outputs (`runtime/current_domain.txt`, `runtime/current_domain.json`, `runtime/state.json`, `runtime/substore_vars.json`). - Commits when `runtime-state` staged diff is non-empty (comparison is branch-targeted, not main-working-tree-only). - Targets `runtime-state` branch (configurable via `GIT_RUNTIME_BRANCH`) and includes branch safety check before staging. - Supports non-interactive push auth in two modes: - credential helper mode (`GIT_CREDENTIAL_HELPER`, e.g. `store`) - header mode (`GIT_HTTP_USERNAME` + `GIT_HTTP_TOKEN`/`GIT_HTTP_TOKEN_FILE`) - `GIT_PUSH_REQUIRED` defaults to `GIT_PUSH_ENABLED`; when enabled, push failure returns non-zero for systemd visibility. - Disables interactive git prompts via `GIT_TERMINAL_PROMPT=0`. ### 3) VMess subscription post-processing `scripts/update_vmess_links.py`: - Reads subscription lines (plain text or full base64 subscription). - Decodes each `vmess://` payload JSON. - Replaces `add` field with selected domain. - Optionally filters by node name regex (`ps` field). - Re-encodes output and prints JSON summary stats. ### 4) Sub-Store runtime consumer `substore/operator_template.js`: - Fetches `runtime/current_domain.json` over HTTP. - Caches domain in `scriptResourceCache` (default TTL 5 min). - Rewrites VMess `server` for matched node names. ## Config model (`config.json`) Key top-level blocks: - `api`: endpoint/method/headers/body/timeout - `parser`: domain extraction paths/regex - `domain_filter`: include suffixes / exclude regex - `scoring`: record ranking fields and strategy - `healthcheck`: TLS probe settings - `selection`: candidate cut (`top_n`) - `output`: runtime file names/paths - `v2ray`: optional token replacement rendering - `notify`: optional post-run command (`AUTODOMAIN`, `AUTODOMAIN_STATUS` env vars) ## Runtime artifacts Generated in `runtime/`: - `current_domain.txt`: selected domain (plain text) - `current_domain.json`: selected domain + status + metadata - `state.json`: persistent state, including `last_good_domain` - `substore_vars.json`: export-friendly variables ## Operational behavior that matters - Fallback behavior is stateful: `last_good_domain` persistence is critical for resilience. - `runtime-state` branch is intended to isolate frequently changing runtime outputs from `main` source history. - Debian installer (`scripts/install_debian.sh`) writes `/etc/vmess-domain-rotator.env`, configures oneshot service+timer, and sets push-required behavior when push is enabled. - Default install path is in-place (current git clone), default service user is `SUDO_USER`, and default auth mode is credential helper store. - Uninstaller removes systemd units and, by default, removes service auth/env files unless `--keep-auth-files` is set.