refactor: address high-priority debt and publish to PyPI

- Fix TOCTOU race conditions by wrapping read-modify-write cycles
  under single-file locks in execution_state, portfolio_service,
  precheck_state, state_manager, and precheck_service.
- Add missing test coverage (96 tests total):
  - test_review_service.py (15 tests)
  - test_check_api.py (6 tests)
  - test_external_gate.py main branches (+10 tests)
  - test_trade_execution.py new commands (+8 tests)
- Unify all agent-consumed JSON messages to English.
- Config-ize hardcoded values (volume filter, schema_version) via
  get_user_config with sensible defaults.
- Add 1-hour TTL to exchange cache with force_new override.
- Add ruff and mypy to dev dependencies; fix all type errors.
- Add __all__ declarations to 11 service modules.
- Sync README with new commands, config tuning docs, and PyPI badge.
- Publish package as coinhunter==1.0.0 on PyPI with MIT license.
- Deprecate coinhunter-cli==1.0.1 with runtime warning.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-16 01:21:27 +08:00
parent 01bb54dee5
commit 62c40a9776
53 changed files with 2338 additions and 671 deletions

View File

@@ -23,17 +23,19 @@
</p>
<p align="center">
<a href="https://pypi.org/project/coinhunter/"><img src="https://img.shields.io/pypi/v/coinhunter?style=flat-square&color=3776ab" /></a>
<a href="#"><img src="https://img.shields.io/badge/python-3.10%2B-3776ab?style=flat-square&logo=python&logoColor=white" /></a>
<a href="#"><img src="https://img.shields.io/badge/status-active%20development-22c55e?style=flat-square" /></a>
<a href="#"><img src="https://img.shields.io/badge/architecture-cli%20%2B%20commands%20%2B%20services-8b5cf6?style=flat-square" /></a>
<a href="#"><img src="https://img.shields.io/badge/tests-needed-ef4444?style=flat-square" /></a>
</p>
---
## What is this?
`coinhunter-cli` is the **executable tooling layer** for CoinHunter — an installable Python CLI that handles trading operations, market probes, precheck orchestration, and review workflows.
`coinhunter` is the **executable tooling layer** for CoinHunter — an installable Python CLI that handles trading operations, market probes, precheck orchestration, and review workflows.
> **Note:** The old package name `coinhunter-cli` is deprecated. Please install `coinhunter` going forward.
| Layer | Responsibility | Location |
|-------|----------------|----------|
@@ -74,7 +76,8 @@ src/coinhunter/
│ ├── smart_executor_parser.py
│ ├── execution_state.py
│ ├── precheck_service.py
│ ├── precheck_constants.py # thresholds & paths
│ ├── review_service.py # review generation logic
│ ├── precheck_constants.py # thresholds
│ ├── time_utils.py # UTC/local time helpers
│ ├── data_utils.py # json, hash, float, symbol norm
│ ├── state_manager.py # state load/save/sanitize
@@ -96,21 +99,13 @@ src/coinhunter/
## Installation
### Quick user install
### From PyPI (recommended)
```bash
./scripts/install_local.sh
pip install coinhunter
```
Creates:
- Virtualenv: `~/.local/share/coinhunter-cli/venv`
- Launcher: `~/.local/bin/coinhunter`
### Editable dev install
```bash
pip install -e .
```
This installs the latest stable release and creates the `coinhunter` console script entry point.
Verify:
@@ -119,6 +114,22 @@ coinhunter --help
coinhunter --version
```
### Development install (editable)
If you're working on this repo locally:
```bash
pip install -e ".[dev]"
```
Or use the convenience script:
```bash
./scripts/install_local.sh
```
A thin wrapper that runs `pip install -e .` and verifies the entrypoint is on your PATH.
---
## Command Reference
@@ -136,6 +147,9 @@ coinhunter exec hold # record a HOLD decision
coinhunter exec buy ENJUSDT 50 # buy $50 of ENJUSDT
coinhunter exec flat ENJUSDT # sell entire ENJUSDT position
coinhunter exec rotate PEPEUSDT ETHUSDT # rotate exposure
coinhunter exec orders # list open spot orders
coinhunter exec order-status ENJUSDT 123456 # check specific order
coinhunter exec cancel ENJUSDT 123456 # cancel an open order
coinhunter gate # external gate orchestration
coinhunter review 12 # generate review context (last 12h)
coinhunter recap 12 # generate review report (last 12h)
@@ -208,6 +222,45 @@ Run the external gate:
coinhunter gate
```
The gate reads `trigger_command` from `~/.coinhunter/config.json` under `external_gate`.
- By default, no external trigger is configured — gate runs precheck and marks state, then exits cleanly.
- Set `trigger_command` to a command list to integrate with your own scheduler:
```json
{
"external_gate": {
"trigger_command": ["hermes", "cron", "run", "JOB_ID"]
}
}
```
- Set to `null` or `[]` to explicitly disable the external trigger.
### Dynamic tuning via `config.json`
You can override internal defaults without editing code by adding keys to `~/.coinhunter/config.json`:
```json
{
"external_gate": {
"trigger_command": ["hermes", "cron", "run", "JOB_ID"]
},
"exchange": {
"min_quote_volume": 200000,
"cache_ttl_seconds": 3600
},
"logging": {
"schema_version": 2
}
}
```
| Key | Default | Effect |
|-----|---------|--------|
| `exchange.min_quote_volume` | `200000` | Minimum 24h quote volume for a symbol to appear in market snapshots |
| `exchange.cache_ttl_seconds` | `3600` | How long the ccxt exchange instance (and `load_markets()` result) is cached |
| `logging.schema_version` | `2` | Schema version stamped on every JSONL log entry |
---
## Runtime Model
@@ -248,14 +301,17 @@ The codebase is actively maintained and refactored in small, safe steps.
- ✅ Extracted `smart-executor` into `commands/` + `services/`
- ✅ Extracted `precheck` into 9 focused service modules
- ✅ Migrated all active command modules into `commands/`
- ✅ Extracted `review_engine.py` core logic into `services/review_service.py`
- ✅ Removed eager `PATHS` instantiation across services and commands
- ✅ Fixed `smart_executor.py` lazy-loading facade
- ✅ Standardized install to use `pip install -e .`
- ✅ Made `external_gate` trigger_command configurable (no longer hardcodes hermes)
- ✅ Removed dead `auto-trader` command
- ✅ Backward-compatible root facades preserved
**Next priorities:**
- 🧪 Add pytest coverage for runtime paths, state manager, and trigger analyzer
- 🔧 Extract `review_engine.py` core logic into `services/`
- 🔧 Unify output contract (JSON-first with `--pretty` option)
- 🔧 Add basic CI (lint + compileall + pytest)
- 🔧 Unify output contract (JSON-first with `--pretty` option)
---