wealthbox-cli 2.3.1__tar.gz → 2.4.0__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.
- wealthbox_cli-2.4.0/.github/dependabot.yml +20 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/.github/workflows/ci.yml +33 -4
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/.github/workflows/release-binaries.yml +2 -2
- wealthbox_cli-2.4.0/.pre-commit-config.yaml +22 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/CHANGELOG.md +107 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/CONTRIBUTING.md +78 -3
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/PKG-INFO +26 -1
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/README.md +23 -0
- wealthbox_cli-2.4.0/docs/cli-reference.md +854 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/pyproject.toml +4 -1
- wealthbox_cli-2.4.0/src/wealthbox_tools/cli/_client.py +138 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/_config.py +4 -1
- wealthbox_cli-2.4.0/src/wealthbox_tools/cli/_factory.py +284 -0
- wealthbox_cli-2.4.0/src/wealthbox_tools/cli/_format.py +259 -0
- wealthbox_cli-2.4.0/src/wealthbox_tools/cli/_resolve.py +175 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/_skill_bootstrap.py +6 -1
- wealthbox_cli-2.4.0/src/wealthbox_tools/cli/_util.py +103 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/doctor.py +2 -1
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/events.py +25 -30
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/notes.py +23 -22
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/opportunities.py +23 -29
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/projects.py +21 -21
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/tasks.py +30 -20
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/workflows.py +23 -21
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/client/activity.py +6 -3
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/client/base.py +71 -10
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/client/categories.py +9 -6
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/client/comments.py +10 -6
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/client/contacts.py +18 -12
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/client/events.py +16 -10
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/client/households.py +9 -5
- wealthbox_cli-2.4.0/src/wealthbox_tools/client/me.py +14 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/client/notes.py +15 -9
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/client/opportunities.py +16 -10
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/client/projects.py +15 -9
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/client/tasks.py +16 -10
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/client/users.py +9 -6
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/client/workflows.py +21 -13
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/self_upgrade.py +3 -2
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/uv.lock +186 -1
- wealthbox_cli-2.3.1/docs/cli-reference.md +0 -364
- wealthbox_cli-2.3.1/src/wealthbox_tools/cli/_util.py +0 -557
- wealthbox_cli-2.3.1/src/wealthbox_tools/client/me.py +0 -11
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/.github/workflows/docs.yml +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/.gitignore +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/LICENSE +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/SECURITY.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/docs/agents/domain.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/docs/agents/issue-tracker.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/docs/agents/triage-labels.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/docs/getting-started.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/docs/index.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/docs/overrides/main.html +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/docs/promotion.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/mkdocs.yml +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/__init__.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/__init__.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/_skill_paths.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/_skill_platforms.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/activity.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/categories.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/config.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/contacts.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/firm.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/households.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/internals.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/main.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/me.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/prefs.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/self_cmd.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/skills.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/cli/users.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/client/__init__.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/firm/__init__.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/firm/archive.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/firm/diff.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/internals/__init__.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/internals/skill_ref_gen.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/models/__init__.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/models/activity.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/models/comments.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/models/common.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/models/contacts.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/models/custom_fields.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/models/enums.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/models/events.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/models/households.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/models/notes.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/models/opportunities.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/models/projects.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/models/tasks.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/models/workflows.py +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/py.typed +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/skills/wealthbox-crm/SKILL.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/skills/wealthbox-crm/bootstrap.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/skills/wealthbox-crm/firm-examples/contacts.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/skills/wealthbox-crm/firm-examples/events.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/skills/wealthbox-crm/firm-examples/notes.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/skills/wealthbox-crm/firm-examples/opportunities.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/skills/wealthbox-crm/firm-examples/projects.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/skills/wealthbox-crm/firm-examples/tasks.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/skills/wealthbox-crm/firm-examples/workflows.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/skills/wealthbox-crm/references/contacts.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/skills/wealthbox-crm/references/events.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/skills/wealthbox-crm/references/households.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/skills/wealthbox-crm/references/lookups.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/skills/wealthbox-crm/references/notes.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/skills/wealthbox-crm/references/opportunities.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/skills/wealthbox-crm/references/projects.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/skills/wealthbox-crm/references/tasks.md +0 -0
- {wealthbox_cli-2.3.1 → wealthbox_cli-2.4.0}/src/wealthbox_tools/skills/wealthbox-crm/references/workflows.md +0 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
|
|
3
|
+
updates:
|
|
4
|
+
# Keep GitHub Actions up to date
|
|
5
|
+
- package-ecosystem: "github-actions"
|
|
6
|
+
directory: "/"
|
|
7
|
+
schedule:
|
|
8
|
+
interval: "weekly"
|
|
9
|
+
open-pull-requests-limit: 5
|
|
10
|
+
commit-message:
|
|
11
|
+
prefix: "chore(ci)"
|
|
12
|
+
|
|
13
|
+
# Keep Python dependencies up to date (pyproject.toml)
|
|
14
|
+
- package-ecosystem: "pip"
|
|
15
|
+
directory: "/"
|
|
16
|
+
schedule:
|
|
17
|
+
interval: "weekly"
|
|
18
|
+
open-pull-requests-limit: 10
|
|
19
|
+
commit-message:
|
|
20
|
+
prefix: "chore(deps)"
|
|
@@ -19,17 +19,36 @@ jobs:
|
|
|
19
19
|
- run: uv run ruff check src/ tests/
|
|
20
20
|
|
|
21
21
|
test:
|
|
22
|
-
runs-on:
|
|
22
|
+
runs-on: ${{ matrix.os }}
|
|
23
23
|
strategy:
|
|
24
24
|
matrix:
|
|
25
|
+
os: [ubuntu-latest]
|
|
25
26
|
python-version: ["3.11", "3.12", "3.13"]
|
|
27
|
+
include:
|
|
28
|
+
- os: windows-latest
|
|
29
|
+
python-version: "3.12"
|
|
26
30
|
steps:
|
|
27
31
|
- uses: actions/checkout@v6
|
|
28
32
|
- uses: astral-sh/setup-uv@v8.1.0
|
|
29
33
|
with:
|
|
30
34
|
python-version: ${{ matrix.python-version }}
|
|
31
35
|
- run: uv sync --extra dev
|
|
32
|
-
-
|
|
36
|
+
- name: Run tests (ubuntu, with coverage gate)
|
|
37
|
+
if: matrix.os == 'ubuntu-latest'
|
|
38
|
+
run: uv run pytest --cov=src/wealthbox_tools --cov-report=term --cov-fail-under=91
|
|
39
|
+
- name: Run tests (windows, no coverage gate)
|
|
40
|
+
if: matrix.os == 'windows-latest'
|
|
41
|
+
run: uv run pytest
|
|
42
|
+
|
|
43
|
+
typecheck:
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@v6
|
|
47
|
+
- uses: astral-sh/setup-uv@v8.1.0
|
|
48
|
+
with:
|
|
49
|
+
python-version: "3.12"
|
|
50
|
+
- run: uv sync --extra dev
|
|
51
|
+
- run: uv run mypy src/
|
|
33
52
|
|
|
34
53
|
skill-ref-drift:
|
|
35
54
|
needs: [lint, test]
|
|
@@ -44,7 +63,7 @@ jobs:
|
|
|
44
63
|
- run: git diff --exit-code -- src/wealthbox_tools/skills/wealthbox-crm/references/
|
|
45
64
|
|
|
46
65
|
publish:
|
|
47
|
-
needs: [lint, test, skill-ref-drift]
|
|
66
|
+
needs: [lint, test, typecheck, skill-ref-drift]
|
|
48
67
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
49
68
|
runs-on: ubuntu-latest
|
|
50
69
|
permissions:
|
|
@@ -55,7 +74,17 @@ jobs:
|
|
|
55
74
|
- uses: astral-sh/setup-uv@v8.1.0
|
|
56
75
|
with:
|
|
57
76
|
python-version: "3.12"
|
|
77
|
+
- name: Check changelog matches version
|
|
78
|
+
run: |
|
|
79
|
+
python - <<'PY'
|
|
80
|
+
import re, pathlib, sys
|
|
81
|
+
ver = re.search(r'^version\s*=\s*"([^"]+)"', pathlib.Path("pyproject.toml").read_text(encoding="utf-8"), re.M).group(1)
|
|
82
|
+
m = re.search(r'^##\s*\[([0-9]+\.[0-9]+\.[0-9]+)\]', pathlib.Path("CHANGELOG.md").read_text(encoding="utf-8"), re.M)
|
|
83
|
+
top = m.group(1) if m else None
|
|
84
|
+
print(f"pyproject={ver} changelog={top}")
|
|
85
|
+
sys.exit(0 if top == ver else 1)
|
|
86
|
+
PY
|
|
58
87
|
- run: uv build
|
|
59
88
|
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
60
89
|
with:
|
|
61
|
-
|
|
90
|
+
skip-existing: true
|
|
@@ -59,10 +59,10 @@ jobs:
|
|
|
59
59
|
binary: wbox-windows-x64.exe
|
|
60
60
|
steps:
|
|
61
61
|
- name: Checkout
|
|
62
|
-
uses: actions/checkout@
|
|
62
|
+
uses: actions/checkout@v6
|
|
63
63
|
|
|
64
64
|
- name: Set up Python
|
|
65
|
-
uses: actions/setup-python@
|
|
65
|
+
uses: actions/setup-python@v6
|
|
66
66
|
with:
|
|
67
67
|
python-version: "3.12"
|
|
68
68
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.15.12
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff
|
|
6
|
+
files: ^(src|tests)/
|
|
7
|
+
|
|
8
|
+
- repo: local
|
|
9
|
+
hooks:
|
|
10
|
+
- id: mypy
|
|
11
|
+
name: mypy (strict)
|
|
12
|
+
language: system
|
|
13
|
+
entry: uv run mypy src/
|
|
14
|
+
pass_filenames: false
|
|
15
|
+
types: [python]
|
|
16
|
+
|
|
17
|
+
- id: skill-ref-drift
|
|
18
|
+
name: skill-ref drift check
|
|
19
|
+
language: system
|
|
20
|
+
entry: bash -c 'uv run wbox internals regen-skill-refs && git diff --exit-code -- src/wealthbox_tools/skills/wealthbox-crm/references/'
|
|
21
|
+
pass_filenames: false
|
|
22
|
+
always_run: true
|
|
@@ -4,6 +4,113 @@ All notable changes to `wealthbox-cli` are documented here. The format follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
|
|
5
5
|
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [2.4.0] - 2026-06-12
|
|
8
|
+
|
|
9
|
+
The notable user-facing change in this release is **differentiated CLI exit
|
|
10
|
+
codes** — scripts that branch on a specific non-zero code should read the note
|
|
11
|
+
below. Beyond that, 2.4.0 is largely an internal hardening release: `src/` is
|
|
12
|
+
now `mypy --strict` clean and gated in CI, the test matrix gained a Windows leg
|
|
13
|
+
and a coverage floor, and the CLI command layer was refactored onto a shared
|
|
14
|
+
resource-command factory. Command syntax, options, help text, and output are
|
|
15
|
+
unchanged.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- **Differentiated CLI exit codes (behavior change).** Previously every error
|
|
19
|
+
exited with code `1`. `wbox` now distinguishes failure classes: validation /
|
|
20
|
+
user errors and non-auth `4xx` responses (e.g. `404`, `422`) still exit `1`,
|
|
21
|
+
authentication errors (`401`/`403`) now exit **`2`**, and server errors
|
|
22
|
+
(`5xx`) now exit **`3`**. Scripts that branched on a specific non-zero code
|
|
23
|
+
for auth or server failures must be updated. (Click usage errors — unknown
|
|
24
|
+
flags, missing arguments — continue to exit `2` as before; that overlap is
|
|
25
|
+
pre-existing.)
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
- `WBOX_DEBUG` environment variable: set it to any non-empty value (e.g.
|
|
29
|
+
`WBOX_DEBUG=1`) to print the full Python traceback to stderr alongside the
|
|
30
|
+
friendly one-line error message. The mapped exit code is unchanged, so it is
|
|
31
|
+
safe to enable in scripts.
|
|
32
|
+
- Documented the existing `WBOX_BRIEF` / `--brief` output mode (strips `*_html`
|
|
33
|
+
duplicate fields to cut response size) in the README and CLI reference.
|
|
34
|
+
|
|
35
|
+
### Security
|
|
36
|
+
- Token config file (`config.json`) and the rate-limit state file are now
|
|
37
|
+
written with `0600` permissions on POSIX so other local users cannot read a
|
|
38
|
+
stored token.
|
|
39
|
+
- Malformed `Retry-After` response header values are truncated to 100
|
|
40
|
+
characters before being logged, bounding a hostile/oversized header.
|
|
41
|
+
|
|
42
|
+
### Internal
|
|
43
|
+
- **Typing:** `src/` is now `mypy --strict` clean (zero errors, zero
|
|
44
|
+
`type: ignore`). Client mixins share a typed request protocol and
|
|
45
|
+
`fetch_all_pages` returns a typed pagination envelope. A new `typecheck` CI
|
|
46
|
+
job runs `mypy src/` and gates publishing.
|
|
47
|
+
- **CI:** added a `windows-latest` test leg (Python 3.12), a coverage floor
|
|
48
|
+
(`--cov-fail-under=91` on the Ubuntu leg), a publish-time check that the top
|
|
49
|
+
CHANGELOG version matches `pyproject.toml`, a weekly Dependabot config, and a
|
|
50
|
+
`.pre-commit-config.yaml` (ruff, mypy, skill-ref drift).
|
|
51
|
+
- **Refactor:** `cli/_util.py` was split into `_client`, `_format`, `_resolve`,
|
|
52
|
+
and `_factory` modules (with `_util` kept as a re-export shim). The `notes`,
|
|
53
|
+
`projects`, `tasks`, `events`, `opportunities`, and `workflows` command
|
|
54
|
+
groups now generate their commands from a shared resource-command factory;
|
|
55
|
+
`contacts` remains hand-written. No change to the CLI surface.
|
|
56
|
+
- **Tests:** added coverage for delete commands, project/workflow updates,
|
|
57
|
+
contacts list filters, HTTP base-client edge cases (missing/malformed
|
|
58
|
+
`Retry-After`, `5xx`, missing collection key), exit codes, and an
|
|
59
|
+
update-model contract meta-test (every `*UpdateInput` rejects an empty
|
|
60
|
+
payload).
|
|
61
|
+
|
|
62
|
+
## [2.3.1] - 2026-06-01
|
|
63
|
+
|
|
64
|
+
Patch release fixing a startup crash introduced in 2.3.0. `wbox` crashed on
|
|
65
|
+
launch in clean environments because `skill_ref_gen.py` imported `click` at
|
|
66
|
+
module level — and `typer` 0.26+ dropped `click` as a dependency, so it was
|
|
67
|
+
no longer guaranteed to be present. The fix defers the import inside the
|
|
68
|
+
hidden `regen-skill-refs` dev command so normal CLI invocations never touch
|
|
69
|
+
it. CI also gains `skip_existing` on the PyPI publish step to survive
|
|
70
|
+
re-pushed tags without a spurious 400 error.
|
|
71
|
+
|
|
72
|
+
### Fixed
|
|
73
|
+
- `wbox` startup crash (`ModuleNotFoundError: click`) in environments where
|
|
74
|
+
`click` is not installed. The `skill_ref_gen` import is now deferred to
|
|
75
|
+
the body of the hidden `regen-skill-refs` command, which is only ever
|
|
76
|
+
invoked during development.
|
|
77
|
+
- PyPI publish job now uses `skip_existing: true` so re-pushing a tag
|
|
78
|
+
(e.g. to re-run a failed release workflow) does not fail with a 400 from
|
|
79
|
+
PyPI when the wheel was already uploaded on the first push.
|
|
80
|
+
|
|
81
|
+
## [2.3.0] - 2026-06-01
|
|
82
|
+
|
|
83
|
+
Feature release. Adds writable contact-role support (`--advisor-role`),
|
|
84
|
+
fixing a long-standing gap where advisor assignments could not be set through
|
|
85
|
+
the CLI at all — even the `--more-fields` / `--json` escape hatches rejected
|
|
86
|
+
the payload because `ContactRoleAssignment` modeled the wrong write shape.
|
|
87
|
+
Also improves the Windows bootstrap installer (idempotent re-runs,
|
|
88
|
+
`-SkipSkills` opt-out, token re-use) and clarifies install/upgrade
|
|
89
|
+
documentation for `uv tool` and `pipx` users.
|
|
90
|
+
|
|
91
|
+
### Added
|
|
92
|
+
- `--advisor-role ROLE:USER` flag on `contacts add person|household|org|trust`
|
|
93
|
+
and `contacts update`. Resolves role names and user substrings against the
|
|
94
|
+
workspace category list so human-readable values like
|
|
95
|
+
`"Associate Advisor:Jane Smith"` are accepted (#94).
|
|
96
|
+
- `install.ps1` gains a `-SkipSkills` switch for CI and non-agent installs
|
|
97
|
+
that don't need the bundled agent skill.
|
|
98
|
+
|
|
99
|
+
### Fixed
|
|
100
|
+
- `ContactRoleAssignment` now uses `{id, value}` (the Wealthbox write shape)
|
|
101
|
+
instead of `{id, type}`, unblocking all contact-role write paths including
|
|
102
|
+
`--more-fields` (#94).
|
|
103
|
+
- `install.ps1` re-runs are now idempotent: if the skill directory already
|
|
104
|
+
exists the installer runs `wbox skills upgrade` instead of erroring.
|
|
105
|
+
- `install.ps1` no longer prompts for a token when one is already stored in
|
|
106
|
+
`%APPDATA%\wbox\config.json` or `WEALTHBOX_TOKEN`.
|
|
107
|
+
|
|
108
|
+
### Changed
|
|
109
|
+
- README and `docs/getting-started.md` now include a per-install-method
|
|
110
|
+
upgrading table and clarify that `wbox self upgrade` is for bundle installs
|
|
111
|
+
only; `uv tool upgrade` / `pipx upgrade` are the correct paths for
|
|
112
|
+
managed installs.
|
|
113
|
+
|
|
7
114
|
## [2.2.1] - 2026-05-13
|
|
8
115
|
|
|
9
116
|
Bug-fix release. `wbox self upgrade` was silently no-op'ing for users who
|
|
@@ -42,6 +42,30 @@ uv run wbox config set-token
|
|
|
42
42
|
|
|
43
43
|
---
|
|
44
44
|
|
|
45
|
+
## Pre-commit hooks
|
|
46
|
+
|
|
47
|
+
The repo ships a `.pre-commit-config.yaml` with three hooks: ruff lint, mypy strict, and a skill-ref drift check. Install them once after cloning:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# uv
|
|
51
|
+
uv tool install pre-commit
|
|
52
|
+
pre-commit install
|
|
53
|
+
|
|
54
|
+
# or pip
|
|
55
|
+
pip install pre-commit
|
|
56
|
+
pre-commit install
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Run all hooks manually at any time:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pre-commit run --all-files
|
|
63
|
+
# or without a local install:
|
|
64
|
+
uv tool run pre-commit run --all-files
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
45
69
|
## Running Tests
|
|
46
70
|
|
|
47
71
|
```bash
|
|
@@ -50,6 +74,14 @@ uv run pytest
|
|
|
50
74
|
|
|
51
75
|
Tests use [respx](https://lundberg.github.io/respx/) to mock HTTP at the transport layer — no real API calls are made.
|
|
52
76
|
|
|
77
|
+
### Coverage gate
|
|
78
|
+
|
|
79
|
+
CI enforces `--cov-fail-under=91` on the ubuntu test leg. Run locally with:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
uv run pytest --cov=src/wealthbox_tools --cov-report=term
|
|
83
|
+
```
|
|
84
|
+
|
|
53
85
|
## Code Style
|
|
54
86
|
|
|
55
87
|
```bash
|
|
@@ -57,7 +89,7 @@ uv run ruff check src/ tests/
|
|
|
57
89
|
```
|
|
58
90
|
|
|
59
91
|
- **ruff** for linting (E, F, I rules; 120-char line length)
|
|
60
|
-
- **mypy** in strict mode
|
|
92
|
+
- **mypy** in strict mode (`uv run mypy src/` must exit 0)
|
|
61
93
|
|
|
62
94
|
---
|
|
63
95
|
|
|
@@ -87,14 +119,57 @@ Three layers under `src/wealthbox_tools/`:
|
|
|
87
119
|
|
|
88
120
|
---
|
|
89
121
|
|
|
122
|
+
## Skill reference files
|
|
123
|
+
|
|
124
|
+
Any change to CLI command signatures or help text **must** regenerate the skill reference files before committing:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
uv run wbox internals regen-skill-refs
|
|
128
|
+
git add src/wealthbox_tools/skills/wealthbox-crm/references/
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The generated files live under `src/wealthbox_tools/skills/wealthbox-crm/references/` and are checked in. The `skill-ref-drift` CI job and the pre-commit hook both fail on stale refs.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Standing verification
|
|
136
|
+
|
|
137
|
+
Run all of these before opening a PR (CI enforces each):
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
uv run ruff check src/ tests/
|
|
141
|
+
uv run pytest
|
|
142
|
+
uv run mypy src/
|
|
143
|
+
uv run wbox internals regen-skill-refs && git diff --exit-code -- src/wealthbox_tools/skills/wealthbox-crm/references/
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Releasing
|
|
149
|
+
|
|
150
|
+
Releases follow semantic versioning. Bump patch for fixes, minor for features, major for breaking changes.
|
|
151
|
+
|
|
152
|
+
1. Bump `version` in `pyproject.toml`.
|
|
153
|
+
2. Add a `## [X.Y.Z]` entry at the top of `CHANGELOG.md` (CI enforces that the changelog version matches `pyproject.toml` before publishing to PyPI).
|
|
154
|
+
3. Verify locally: `uv run ruff check src/ tests/ && uv run pytest && uv run mypy src/`
|
|
155
|
+
4. Commit: `vX.Y.Z: <description>`
|
|
156
|
+
5. Tag: `git tag vX.Y.Z`
|
|
157
|
+
6. Push: `git push origin main --tags`
|
|
158
|
+
|
|
159
|
+
CI builds and publishes to PyPI automatically on `v*` tags once lint, tests, typecheck, and skill-ref-drift all pass.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
90
163
|
## CI
|
|
91
164
|
|
|
92
165
|
Pull requests and pushes to `main` run GitHub Actions CI:
|
|
93
166
|
|
|
94
167
|
- **Lint:** `ruff check src/ tests/`
|
|
95
|
-
- **Test:** `pytest` across Python 3.11, 3.12, 3.13
|
|
168
|
+
- **Test:** `pytest` across Python 3.11, 3.12, 3.13 (ubuntu) + 3.12 (windows); coverage gate `--cov-fail-under=91` on ubuntu
|
|
169
|
+
- **Typecheck:** `mypy src/` (strict)
|
|
170
|
+
- **Skill-ref drift:** regenerates refs and asserts no git diff
|
|
96
171
|
|
|
97
|
-
|
|
172
|
+
All four jobs must pass before merging.
|
|
98
173
|
|
|
99
174
|
---
|
|
100
175
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wealthbox-cli
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
4
4
|
Summary: CLI and client library for the Wealthbox CRM API
|
|
5
5
|
Project-URL: Homepage, https://github.com/massive-value/wealthbox-cli
|
|
6
6
|
Project-URL: Documentation, https://massive-value.github.io/wealthbox-cli/
|
|
@@ -33,9 +33,11 @@ Requires-Dist: typer<1.0,>=0.12
|
|
|
33
33
|
Provides-Extra: dev
|
|
34
34
|
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
35
35
|
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
36
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
36
37
|
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
37
38
|
Requires-Dist: respx>=0.21; extra == 'dev'
|
|
38
39
|
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
40
|
+
Requires-Dist: types-tabulate>=0.9; extra == 'dev'
|
|
39
41
|
Description-Content-Type: text/markdown
|
|
40
42
|
|
|
41
43
|
# Wealthbox CLI
|
|
@@ -152,6 +154,29 @@ wbox notes add "Discussed retirement plan" --contact 12345
|
|
|
152
154
|
```
|
|
153
155
|
|
|
154
156
|
Full command reference: [CLI Reference](https://massive-value.github.io/wealthbox-cli/cli-reference/). Output formats: `json` (default), `table`, `csv`, `tsv`. Date format: ISO 8601 (`2026-05-01T10:00:00-07:00`). See [Getting Started](https://massive-value.github.io/wealthbox-cli/getting-started/) for pipx, env-var auth, and project-scoped installs.
|
|
157
|
+
|
|
158
|
+
**Exit codes** — `wbox` returns differentiated exit codes so scripts can branch on the failure class:
|
|
159
|
+
|
|
160
|
+
| Code | Meaning |
|
|
161
|
+
| ---- | ------- |
|
|
162
|
+
| `0` | Success |
|
|
163
|
+
| `1` | Validation / user error (bad input, a non-auth `4xx` from the API such as `404`/`422`) |
|
|
164
|
+
| `2` | Authentication error (API `401`/`403`) |
|
|
165
|
+
| `3` | Server error (API `5xx`) |
|
|
166
|
+
|
|
167
|
+
Note: Click also exits `2` for usage errors (an unknown flag or a missing required argument); that overlap with the auth code is pre-existing and acceptable, since usage errors are caught by the parser before the command runs. Set `WBOX_DEBUG=1` to print the full Python traceback to stderr alongside the friendly message (the exit code is unchanged) — handy when reporting bugs.
|
|
168
|
+
|
|
169
|
+
**Brief mode** — Wealthbox duplicates every text field as HTML markup (`content_html`, `description_html`, `body_html`, etc.), making responses 3–5x larger. Pass `--brief` or set `WBOX_BRIEF=1` to recursively strip all `*_html` keys from the JSON output before it is printed. Plain-text counterparts are kept; all other fields are unaffected. Any non-empty value is truthy (same convention as `WBOX_DEBUG`).
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# One-off: flag form
|
|
173
|
+
wbox --brief notes list
|
|
174
|
+
|
|
175
|
+
# Persistent in a script or agent session
|
|
176
|
+
export WBOX_BRIEF=1
|
|
177
|
+
wbox notes list
|
|
178
|
+
wbox tasks list
|
|
179
|
+
```
|
|
155
180
|
</details>
|
|
156
181
|
|
|
157
182
|
<details>
|
|
@@ -112,6 +112,29 @@ wbox notes add "Discussed retirement plan" --contact 12345
|
|
|
112
112
|
```
|
|
113
113
|
|
|
114
114
|
Full command reference: [CLI Reference](https://massive-value.github.io/wealthbox-cli/cli-reference/). Output formats: `json` (default), `table`, `csv`, `tsv`. Date format: ISO 8601 (`2026-05-01T10:00:00-07:00`). See [Getting Started](https://massive-value.github.io/wealthbox-cli/getting-started/) for pipx, env-var auth, and project-scoped installs.
|
|
115
|
+
|
|
116
|
+
**Exit codes** — `wbox` returns differentiated exit codes so scripts can branch on the failure class:
|
|
117
|
+
|
|
118
|
+
| Code | Meaning |
|
|
119
|
+
| ---- | ------- |
|
|
120
|
+
| `0` | Success |
|
|
121
|
+
| `1` | Validation / user error (bad input, a non-auth `4xx` from the API such as `404`/`422`) |
|
|
122
|
+
| `2` | Authentication error (API `401`/`403`) |
|
|
123
|
+
| `3` | Server error (API `5xx`) |
|
|
124
|
+
|
|
125
|
+
Note: Click also exits `2` for usage errors (an unknown flag or a missing required argument); that overlap with the auth code is pre-existing and acceptable, since usage errors are caught by the parser before the command runs. Set `WBOX_DEBUG=1` to print the full Python traceback to stderr alongside the friendly message (the exit code is unchanged) — handy when reporting bugs.
|
|
126
|
+
|
|
127
|
+
**Brief mode** — Wealthbox duplicates every text field as HTML markup (`content_html`, `description_html`, `body_html`, etc.), making responses 3–5x larger. Pass `--brief` or set `WBOX_BRIEF=1` to recursively strip all `*_html` keys from the JSON output before it is printed. Plain-text counterparts are kept; all other fields are unaffected. Any non-empty value is truthy (same convention as `WBOX_DEBUG`).
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# One-off: flag form
|
|
131
|
+
wbox --brief notes list
|
|
132
|
+
|
|
133
|
+
# Persistent in a script or agent session
|
|
134
|
+
export WBOX_BRIEF=1
|
|
135
|
+
wbox notes list
|
|
136
|
+
wbox tasks list
|
|
137
|
+
```
|
|
115
138
|
</details>
|
|
116
139
|
|
|
117
140
|
<details>
|