# CLAUDE.md This file provides guidance to Claude Code when working with this repository. ## Project Overview The repository supports two independent operating modes: - Server mode - Source: remote API - Main config: `config.server.json` - Main output: `runtime/` - Optional git automation: yes, via `runtime-state` - Router mode - Source: local `cfst` - Python config: `config.router.json` - BusyBox shell config: `router_local.conf` - Main output: `cfip_runtime/` - Optional git automation: no The old `config.json` and `config.example.json` are deprecated and should not be reintroduced. ## Common Commands ### Validate scripts ```bash env PYTHONPYCACHEPREFIX=/tmp/pycache python3 -m py_compile scripts/domain_updater.py env PYTHONPYCACHEPREFIX=/tmp/pycache 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 sh -n scripts/router_local_update.sh sh -n scripts/router_local_http.sh ``` ### Run server mode once ```bash python3 scripts/domain_updater.py --config config.server.json ``` ### Run local cfst mode once ```bash python3 scripts/domain_updater.py --config config.router.json ``` ### Print resolved output paths ```bash python3 scripts/domain_updater.py --config config.server.json --print-output-settings python3 scripts/domain_updater.py --config config.router.json --print-output-settings ``` ### Run server scheduler entrypoint ```bash bash scripts/run_update_and_commit.sh config.server.json ``` ### Force commit to runtime-state once ```bash bash scripts/run_update_and_commit.sh --force-commit config.server.json # or GIT_FORCE_COMMIT=1 bash scripts/run_update_and_commit.sh config.server.json ``` ### Update VMess links from selected value Server mode: ```bash python3 scripts/update_vmess_links.py \ --input ./nodes.txt \ --output ./nodes.updated.txt \ --domain-file ./runtime/current_domain.txt ``` Router mode: ```bash python3 scripts/update_vmess_links.py \ --input ./nodes.txt \ --output ./nodes.updated.txt \ --domain-file ./cfip_runtime/current_ip.txt ``` ### BusyBox router mode ```bash sh scripts/router_local_update.sh ./router_local.conf sh scripts/router_local_http.sh ./router_local.conf ``` ### Debian systemd install/uninstall ```bash sudo bash scripts/install_debian.sh --config config.server.json sudo bash scripts/install_debian.sh --config config.server.json --interval 5min sudo bash scripts/install_debian.sh --config config.server.json --git-push 0 sudo bash scripts/uninstall_debian.sh sudo bash scripts/uninstall_debian.sh --keep-auth-files ``` ## Testing and Verification - There is no dedicated `tests/` directory yet. - Primary verification is syntax checks plus manual script runs. - `--print-output-settings` is the quickest way to verify output path resolution without performing a full update. ## Architecture ### 1) Unified Python updater `scripts/domain_updater.py` is the shared core: - Supports `source.type = "api"` and `source.type = "cfst_local"` - Resolves output file paths from config instead of hardcoded runtime paths - Writes four runtime artifacts: - selected value text file - selected value JSON file - state file - export vars file - Supports fallback to the last good value from the configured state file ### 2) Server mode `config.server.json` defines: - API request settings - parser / record mapping / record filter - scoring and healthcheck behavior - output paths under `runtime/` `scripts/run_update_and_commit.sh`: - Resolves output paths by calling `domain_updater.py --print-output-settings` - Runs the updater - Compares the selected value with `runtime-state` - Syncs configured repo-local output files into the target worktree - Commits and optionally pushes ### 3) Router mode There are two router-side entry styles: - Python local mode via `config.router.json` - still uses `domain_updater.py` - executes local `cfst` - parses CSV and writes `cfip_runtime/` - BusyBox shell mode via `router_local.conf` - `scripts/router_local_update.sh` - `scripts/router_local_http.sh` - intended for routers without Python ### 4) Sub-Store consumer `substore/operator_template.js`: - Fetches a JSON runtime endpoint - Accepts either `domain` or `ip` - Rewrites VMess `server` for matched nodes - Uses `scriptResourceCache` with a short TTL ## Configuration Model ### `config.server.json` Main blocks: - `source` - `api` - `parser` - `record_mapping` - `record_filter` - `domain_filter` - `scoring` - `healthcheck` - `selection` - `output` - `v2ray` - `notify` ### `config.router.json` Main blocks: - `source` - `cfst_local` - `domain_filter` - `healthcheck` - `selection` - `output` - `v2ray` - `notify` ### `router_local.conf` Main groups: - `CFST_*` - `TOP_N` - `RUNTIME_DIR` - `VALUE_*` - `STATE_*` - `EXPORT_*` - `HTTP_PORT` ## Operational Notes - Server mode is the only mode intended to update `runtime-state`. - Router mode does not use git automation by default. - `runtime/` and `cfip_runtime/` are ignored on `main`; runtime artifacts are meant to be ephemeral locally. - Persistent `state.json` matters for fallback behavior in both modes. - Avoid reintroducing hardcoded assumptions about `runtime/current_domain.txt`; use config-driven paths instead.