CLAUDE.md 6.4 KB

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

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

python3 scripts/domain_updater.py --config config.json

Run scheduler entrypoint (updater + runtime-state commit/push)

bash scripts/run_update_and_commit.sh config.json

Force commit to runtime-state once (manual)

bash scripts/run_update_and_commit.sh --force-commit config.json
# or
GIT_FORCE_COMMIT=1 bash scripts/run_update_and_commit.sh config.json

Update VMess links from selected domain

python3 scripts/update_vmess_links.py \
  --input ./nodes.txt \
  --output ./nodes.updated.txt \
  --domain-file ./runtime/current_domain.txt

Update only matching node names

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

python3 -m http.server 8080 --directory runtime
curl http://127.0.0.1:8080/current_domain.json

Debian systemd install/uninstall

# 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.
  • Compares selected domain with runtime-state HEAD (runtime/current_domain.txt) and skips commit/push when unchanged (default behavior).
  • 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) when domain changes.
  • Supports manual force commit via --force-commit or GIT_FORCE_COMMIT=1; when no content changes it creates an empty commit with a manual: commit message that includes selected domain and UTC update time.
  • 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.
  • Repository systemd/* static templates are intentionally not maintained; install script dynamically generates unit files under /etc/systemd/system/.
  • 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.