emq-cli 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- emq_cli-0.2.1/.gitignore +28 -0
- emq_cli-0.2.1/ARCHITECHTURE.md +47 -0
- emq_cli-0.2.1/LICENSE +21 -0
- emq_cli-0.2.1/PKG-INFO +84 -0
- emq_cli-0.2.1/README.md +73 -0
- emq_cli-0.2.1/docs/design.md +89 -0
- emq_cli-0.2.1/docs/referance/EMQuantAPI_Python.md +1412 -0
- emq_cli-0.2.1/docs/user-manual.md +651 -0
- emq_cli-0.2.1/pyproject.toml +68 -0
- emq_cli-0.2.1/src/emq/__init__.py +1 -0
- emq_cli-0.2.1/src/emq/__main__.py +4 -0
- emq_cli-0.2.1/src/emq/cli.py +43 -0
- emq_cli-0.2.1/src/emq/commands/__init__.py +0 -0
- emq_cli-0.2.1/src/emq/commands/_common.py +94 -0
- emq_cli-0.2.1/src/emq/commands/auth.py +57 -0
- emq_cli-0.2.1/src/emq/commands/market.py +63 -0
- emq_cli-0.2.1/src/emq/commands/portfolio.py +180 -0
- emq_cli-0.2.1/src/emq/commands/quota.py +57 -0
- emq_cli-0.2.1/src/emq/commands/raw.py +139 -0
- emq_cli-0.2.1/src/emq/core/__init__.py +0 -0
- emq_cli-0.2.1/src/emq/core/config.py +27 -0
- emq_cli-0.2.1/src/emq/core/emquant_loader.py +65 -0
- emq_cli-0.2.1/src/emq/core/errors.py +17 -0
- emq_cli-0.2.1/src/emq/core/logging.py +12 -0
- emq_cli-0.2.1/src/emq/core/normalize.py +73 -0
- emq_cli-0.2.1/src/emq/core/output.py +125 -0
- emq_cli-0.2.1/src/emq/core/session.py +133 -0
- emq_cli-0.2.1/src/emq/core/state.py +64 -0
- emq_cli-0.2.1/src/emq/types.py +19 -0
- emq_cli-0.2.1/src/emq/vendor/__init__.py +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/__init__.py +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/EmQuantAPI.py +2092 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x64/ServerList.json.e +1 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x64/image/EMApp.ico +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x64/image/Tips_error.png +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x64/image/edit_bg.png +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x64/image/tab1_bg.png +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x64/image/tab2_bg.png +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x64/image/tab3_bg.png +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x64/libEMQuantAPIx64.so +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x64/loginactivator +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x64/loginactivator_ubuntu +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x86/ServerList.json.e +1 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x86/image/EMApp.ico +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x86/image/Tips_error.png +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x86/image/edit_bg.png +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x86/image/tab1_bg.png +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x86/image/tab2_bg.png +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x86/image/tab3_bg.png +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x86/libEMQuantAPI.so +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x86/loginactivator +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/linux/x86/loginactivator_ubuntu +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/mac/ChoiceToHQ.xml +349 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/mac/ServerList.json.e +1 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/mac/ServerSelect.txt +1 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/mac/bjse_code_conversion.txt +249 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/mac/config.e +1 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/mac/filesumpc.ini +19 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/mac/image/EMApp.ico +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/mac/image/Tips_error.png +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/mac/image/edit_bg.png +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/mac/image/tab1_bg.png +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/mac/image/tab2_bg.png +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/mac/image/tab3_bg.png +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/mac/libEMQuantAPIx64.dylib +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/mac/loginactivator_mac +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/mac/precentflag.dat +1 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/windows/EmQuantAPI.dll +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/windows/EmQuantAPI_x64.dll +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/windows/LoginActivator.exe +0 -0
- emq_cli-0.2.1/src/emq/vendor/emquantapi/python3/libs/windows/ServerList.json.e +1 -0
- emq_cli-0.2.1/tests/test_cli.py +369 -0
- emq_cli-0.2.1/tests/test_session.py +74 -0
emq_cli-0.2.1/.gitignore
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Virtual environments
|
|
7
|
+
.venv/
|
|
8
|
+
venv/
|
|
9
|
+
|
|
10
|
+
# Distribution / packaging
|
|
11
|
+
build/
|
|
12
|
+
dist/
|
|
13
|
+
*.egg-info/
|
|
14
|
+
|
|
15
|
+
# Tool caches
|
|
16
|
+
.mypy_cache/
|
|
17
|
+
.pytest_cache/
|
|
18
|
+
.ruff_cache/
|
|
19
|
+
.coverage
|
|
20
|
+
coverage.xml
|
|
21
|
+
|
|
22
|
+
# OS / editor
|
|
23
|
+
.DS_Store
|
|
24
|
+
.idea/
|
|
25
|
+
.vscode/
|
|
26
|
+
|
|
27
|
+
# EmQuant API local login artifact
|
|
28
|
+
src/emq/vendor/emquantapi/python3/libs/mac/logininfo.log
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# EMQ CLI Architecture Map
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The CLI is structured by business domains and a shared core layer:
|
|
6
|
+
|
|
7
|
+
- `src/emq/cli.py`: root command and global options.
|
|
8
|
+
- `src/emq/commands/*`: domain command handlers (`auth`, `market`, `portfolio`, `quota`, `raw`).
|
|
9
|
+
- `src/emq/core/*`: common runtime services.
|
|
10
|
+
- `src/emq/vendor/emquantapi/python3`: vendored EmQuant SDK and native libraries.
|
|
11
|
+
|
|
12
|
+
## Core Modules
|
|
13
|
+
|
|
14
|
+
- `config.py`: constants, env names, vendor paths.
|
|
15
|
+
- `emquant_loader.py`: dynamic import + native library path patching.
|
|
16
|
+
- `session.py`: login lifecycle and auto-login.
|
|
17
|
+
- `state.py`: local credential state persistence.
|
|
18
|
+
- `normalize.py`: convert `EmQuantData` into row-based data.
|
|
19
|
+
- `output.py`: envelope creation + `json/table/csv` rendering.
|
|
20
|
+
- `errors.py`: domain exceptions and exit codes.
|
|
21
|
+
- `logging.py`: CLI logging initialization.
|
|
22
|
+
|
|
23
|
+
## Command Flow
|
|
24
|
+
|
|
25
|
+
1. Root callback parses global options (`--output`, logging, auto-login).
|
|
26
|
+
2. Domain command validates inputs and invokes core session.
|
|
27
|
+
3. Loader returns EmQuant client from vendored SDK.
|
|
28
|
+
4. SDK result is normalized into row records.
|
|
29
|
+
5. Output layer renders the unified envelope in selected format.
|
|
30
|
+
|
|
31
|
+
## Session Model
|
|
32
|
+
|
|
33
|
+
1. `auth login` logs in and stores credentials in `~/.emq/state.json`.
|
|
34
|
+
2. Business commands call `ensure_login()` to auto-login if needed.
|
|
35
|
+
3. `auth logout` calls `stop()` and clears local state.
|
|
36
|
+
4. `auth status` supports local-only and remote probe modes.
|
|
37
|
+
|
|
38
|
+
## Data and Error Model
|
|
39
|
+
|
|
40
|
+
All commands emit:
|
|
41
|
+
|
|
42
|
+
- `success`: boolean
|
|
43
|
+
- `error`: `{code,message,source}` or `null`
|
|
44
|
+
- `meta`: command metadata + row count
|
|
45
|
+
- `data`: row records
|
|
46
|
+
|
|
47
|
+
Errors from SDK (`ErrorCode != 0`) are mapped to `source=emquant`.
|
emq_cli-0.2.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 emq-cli contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
emq_cli-0.2.1/PKG-INFO
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: emq-cli
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: EMQ CLI with vendored EmQuantAPI integration.
|
|
5
|
+
Author: emq-cli contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Python: >=3.11
|
|
9
|
+
Requires-Dist: typer<1.0.0,>=0.16.0
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+
# emq-cli
|
|
13
|
+
|
|
14
|
+
`emq` is a domain-oriented command line tool for EmQuantAPI with vendored runtime libraries.
|
|
15
|
+
|
|
16
|
+
## Requirements
|
|
17
|
+
|
|
18
|
+
- Python 3.11+
|
|
19
|
+
- [uv](https://docs.astral.sh/uv/)
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
uv sync --dev
|
|
25
|
+
uv run emq --help
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Login once (credentials from flags or env):
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
export EMQ_USER='your_user'
|
|
32
|
+
export EMQ_PASS='your_pass'
|
|
33
|
+
uv run emq auth login
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Sample market query:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
uv run emq market series 000001.SZ CLOSE --start 2025-01-01 --end 2025-12-31 --output table
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Quick portfolio order:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
uv run emq portfolio qorder --code MYPORT --stock 300059.SZ --volume 1000 --price 10.5 --date 2025-01-15
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Command Domains
|
|
49
|
+
|
|
50
|
+
- `auth`: `login`, `logout`, `status`
|
|
51
|
+
- `market`: `snapshot`, `series`
|
|
52
|
+
- `portfolio`: `create`, `list`, `order`, `qorder`
|
|
53
|
+
- `quota`: `usage`
|
|
54
|
+
- `raw`: `css`, `csd`, `pquery`, `porder`
|
|
55
|
+
|
|
56
|
+
## Output
|
|
57
|
+
|
|
58
|
+
Every command uses a unified envelope and supports:
|
|
59
|
+
|
|
60
|
+
- `--output json` (default)
|
|
61
|
+
- `--output table` (ASCII)
|
|
62
|
+
- `--output csv`
|
|
63
|
+
|
|
64
|
+
`--output` can be placed either before the domain command (global) or at the end of leaf commands (override).
|
|
65
|
+
If both are provided, the leaf command `--output` takes precedence.
|
|
66
|
+
|
|
67
|
+
## Credential Persistence
|
|
68
|
+
|
|
69
|
+
- `auth login` saves credentials to `~/.emq/state.json` (plain text, initial version).
|
|
70
|
+
- Business commands auto-login from saved state or environment variables.
|
|
71
|
+
- `auth logout` clears local state and calls SDK logout.
|
|
72
|
+
|
|
73
|
+
## Development
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
uv run ruff check .
|
|
77
|
+
uv run mypy src
|
|
78
|
+
uv run pytest
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Notes
|
|
82
|
+
|
|
83
|
+
- The vendored SDK lives in `src/emq/vendor/emquantapi/python3`.
|
|
84
|
+
- Root `EMQuantAPI_Python` should not be kept after migration.
|
emq_cli-0.2.1/README.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# emq-cli
|
|
2
|
+
|
|
3
|
+
`emq` is a domain-oriented command line tool for EmQuantAPI with vendored runtime libraries.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Python 3.11+
|
|
8
|
+
- [uv](https://docs.astral.sh/uv/)
|
|
9
|
+
|
|
10
|
+
## Quick Start
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
uv sync --dev
|
|
14
|
+
uv run emq --help
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Login once (credentials from flags or env):
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
export EMQ_USER='your_user'
|
|
21
|
+
export EMQ_PASS='your_pass'
|
|
22
|
+
uv run emq auth login
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Sample market query:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
uv run emq market series 000001.SZ CLOSE --start 2025-01-01 --end 2025-12-31 --output table
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Quick portfolio order:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
uv run emq portfolio qorder --code MYPORT --stock 300059.SZ --volume 1000 --price 10.5 --date 2025-01-15
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Command Domains
|
|
38
|
+
|
|
39
|
+
- `auth`: `login`, `logout`, `status`
|
|
40
|
+
- `market`: `snapshot`, `series`
|
|
41
|
+
- `portfolio`: `create`, `list`, `order`, `qorder`
|
|
42
|
+
- `quota`: `usage`
|
|
43
|
+
- `raw`: `css`, `csd`, `pquery`, `porder`
|
|
44
|
+
|
|
45
|
+
## Output
|
|
46
|
+
|
|
47
|
+
Every command uses a unified envelope and supports:
|
|
48
|
+
|
|
49
|
+
- `--output json` (default)
|
|
50
|
+
- `--output table` (ASCII)
|
|
51
|
+
- `--output csv`
|
|
52
|
+
|
|
53
|
+
`--output` can be placed either before the domain command (global) or at the end of leaf commands (override).
|
|
54
|
+
If both are provided, the leaf command `--output` takes precedence.
|
|
55
|
+
|
|
56
|
+
## Credential Persistence
|
|
57
|
+
|
|
58
|
+
- `auth login` saves credentials to `~/.emq/state.json` (plain text, initial version).
|
|
59
|
+
- Business commands auto-login from saved state or environment variables.
|
|
60
|
+
- `auth logout` clears local state and calls SDK logout.
|
|
61
|
+
|
|
62
|
+
## Development
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
uv run ruff check .
|
|
66
|
+
uv run mypy src
|
|
67
|
+
uv run pytest
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Notes
|
|
71
|
+
|
|
72
|
+
- The vendored SDK lives in `src/emq/vendor/emquantapi/python3`.
|
|
73
|
+
- Root `EMQuantAPI_Python` should not be kept after migration.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# EMQ CLI Detailed Design
|
|
2
|
+
|
|
3
|
+
## 1. Goals
|
|
4
|
+
|
|
5
|
+
- Provide domain-driven EMQ CLI commands.
|
|
6
|
+
- Vendor EmQuant Python runtime in package without external install step.
|
|
7
|
+
- Persist login until explicit logout.
|
|
8
|
+
- Standardize output across commands.
|
|
9
|
+
|
|
10
|
+
## 2. Command Contracts
|
|
11
|
+
|
|
12
|
+
### auth
|
|
13
|
+
|
|
14
|
+
- `auth login [--user] [--password] [--force-login/--no-force-login]`
|
|
15
|
+
- `auth logout`
|
|
16
|
+
- `auth status [--check]`
|
|
17
|
+
|
|
18
|
+
### market
|
|
19
|
+
|
|
20
|
+
- `market snapshot <codes> <indicators> [--options]`
|
|
21
|
+
- `market series <codes> <indicators> --start <date> --end <date> [--options]`
|
|
22
|
+
|
|
23
|
+
### portfolio
|
|
24
|
+
|
|
25
|
+
- `portfolio create --code --name --initial-fund [--remark] [--options]`
|
|
26
|
+
- `portfolio list [--options]`
|
|
27
|
+
- `portfolio order --code <combinCode> --orders-file <json> [--remark] [--options]`
|
|
28
|
+
- `portfolio qorder --code <combinCode> --stock <code> --volume <n> --price <p> --date <date> [--time <time>] [--type <type>] [--remark] [--options]`
|
|
29
|
+
|
|
30
|
+
### quota
|
|
31
|
+
|
|
32
|
+
- `quota usage [--start] [--end] [--func] [--indicators] [--options]`
|
|
33
|
+
|
|
34
|
+
### raw
|
|
35
|
+
|
|
36
|
+
- `raw css <codes> <indicators> [--options]`
|
|
37
|
+
- `raw csd <codes> <indicators> --start --end [--options]`
|
|
38
|
+
- `raw pquery [--options]`
|
|
39
|
+
- `raw porder --code <combinCode> --orders-file <json> [--remark] [--options]`
|
|
40
|
+
|
|
41
|
+
## 3. SDK Loading
|
|
42
|
+
|
|
43
|
+
- Use `importlib` to load `EmQuantAPI.py` from vendored path.
|
|
44
|
+
- Patch `UtilAccess.GetLibraryPath()` to return platform-specific native library path.
|
|
45
|
+
- Native library location is selected by OS and architecture.
|
|
46
|
+
|
|
47
|
+
## 4. Authentication State
|
|
48
|
+
|
|
49
|
+
- State file: `~/.emq/state.json`.
|
|
50
|
+
- File permission target: `0600`.
|
|
51
|
+
- Credential resolution priority:
|
|
52
|
+
1. CLI options
|
|
53
|
+
2. env `EMQ_USER` / `EMQ_PASS`
|
|
54
|
+
3. saved local state
|
|
55
|
+
|
|
56
|
+
## 5. Unified Output
|
|
57
|
+
|
|
58
|
+
Envelope schema:
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"success": true,
|
|
63
|
+
"error": null,
|
|
64
|
+
"meta": {},
|
|
65
|
+
"data": []
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`table` and `csv` are rendered from normalized row records.
|
|
70
|
+
|
|
71
|
+
## 6. Error Strategy
|
|
72
|
+
|
|
73
|
+
- User/config validation errors: `source=cli`, exit code `2`.
|
|
74
|
+
- SDK errors: `source=emquant`, exit code `3`.
|
|
75
|
+
- Unexpected command failures are wrapped into envelope errors.
|
|
76
|
+
|
|
77
|
+
## 7. Logging
|
|
78
|
+
|
|
79
|
+
- Configured in root callback.
|
|
80
|
+
- Supports `--log-level` and optional `--log-file`.
|
|
81
|
+
|
|
82
|
+
## 8. Testing Scope
|
|
83
|
+
|
|
84
|
+
- Command tree availability.
|
|
85
|
+
- Output format behavior.
|
|
86
|
+
- Login precedence and auto-login semantics.
|
|
87
|
+
- Raw option passthrough and order file validation.
|
|
88
|
+
- SDK error mapping.
|
|
89
|
+
- SDK mocking via `FakeClient`/`FakeEmqData` with call recording for verification.
|