wealthbox-cli 2.4.1__tar.gz → 2.5.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.
Files changed (112) hide show
  1. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/.github/workflows/ci.yml +6 -6
  2. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/.github/workflows/release-binaries.yml +221 -220
  3. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/CHANGELOG.md +75 -0
  4. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/PKG-INFO +3 -3
  5. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/README.md +1 -1
  6. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/pyproject.toml +1 -1
  7. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/_client.py +13 -0
  8. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/_resolve.py +69 -1
  9. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/_util.py +4 -0
  10. wealthbox_cli-2.5.0/src/wealthbox_tools/cli/comments.py +126 -0
  11. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/events.py +39 -14
  12. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/main.py +4 -0
  13. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/opportunities.py +6 -2
  14. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/tasks.py +43 -5
  15. wealthbox_cli-2.5.0/src/wealthbox_tools/cli/teams.py +37 -0
  16. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/users.py +19 -0
  17. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/workflows.py +66 -9
  18. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/client/__init__.py +2 -0
  19. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/client/base.py +54 -0
  20. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/client/tasks.py +23 -1
  21. wealthbox_cli-2.5.0/src/wealthbox_tools/client/teams.py +24 -0
  22. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/client/workflows.py +22 -1
  23. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/internals/skill_ref_gen.py +1 -0
  24. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/models/__init__.py +4 -0
  25. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/models/enums.py +29 -1
  26. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/models/events.py +3 -2
  27. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/models/tasks.py +3 -2
  28. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/skills/wealthbox-crm/SKILL.md +10 -0
  29. wealthbox_cli-2.5.0/src/wealthbox_tools/skills/wealthbox-crm/references/comments.md +129 -0
  30. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/skills/wealthbox-crm/references/events.md +17 -0
  31. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/skills/wealthbox-crm/references/lookups.md +26 -1
  32. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/skills/wealthbox-crm/references/opportunities.md +9 -2
  33. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/skills/wealthbox-crm/references/tasks.md +58 -4
  34. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/skills/wealthbox-crm/references/workflows.md +44 -7
  35. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/uv.lock +1 -1
  36. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/.github/dependabot.yml +0 -0
  37. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/.github/workflows/docs.yml +0 -0
  38. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/.gitignore +0 -0
  39. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/.pre-commit-config.yaml +0 -0
  40. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/CONTRIBUTING.md +0 -0
  41. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/LICENSE +0 -0
  42. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/SECURITY.md +0 -0
  43. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/docs/agents/domain.md +0 -0
  44. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/docs/agents/issue-tracker.md +0 -0
  45. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/docs/agents/triage-labels.md +0 -0
  46. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/docs/cli-reference.md +0 -0
  47. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/docs/getting-started.md +0 -0
  48. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/docs/index.md +0 -0
  49. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/docs/overrides/main.html +0 -0
  50. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/docs/promotion.md +0 -0
  51. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/mkdocs.yml +0 -0
  52. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/__init__.py +0 -0
  53. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/__init__.py +0 -0
  54. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/_config.py +0 -0
  55. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/_factory.py +0 -0
  56. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/_format.py +0 -0
  57. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/_skill_bootstrap.py +0 -0
  58. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/_skill_paths.py +0 -0
  59. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/_skill_platforms.py +0 -0
  60. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/activity.py +0 -0
  61. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/categories.py +0 -0
  62. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/config.py +0 -0
  63. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/contacts.py +0 -0
  64. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/doctor.py +0 -0
  65. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/firm.py +0 -0
  66. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/households.py +0 -0
  67. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/internals.py +0 -0
  68. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/me.py +0 -0
  69. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/notes.py +0 -0
  70. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/prefs.py +0 -0
  71. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/projects.py +0 -0
  72. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/self_cmd.py +0 -0
  73. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/cli/skills.py +0 -0
  74. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/client/activity.py +0 -0
  75. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/client/categories.py +0 -0
  76. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/client/comments.py +0 -0
  77. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/client/contacts.py +0 -0
  78. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/client/events.py +0 -0
  79. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/client/households.py +0 -0
  80. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/client/me.py +0 -0
  81. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/client/notes.py +0 -0
  82. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/client/opportunities.py +0 -0
  83. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/client/projects.py +0 -0
  84. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/client/users.py +0 -0
  85. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/firm/__init__.py +0 -0
  86. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/firm/archive.py +0 -0
  87. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/firm/diff.py +0 -0
  88. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/internals/__init__.py +0 -0
  89. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/models/activity.py +0 -0
  90. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/models/comments.py +0 -0
  91. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/models/common.py +0 -0
  92. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/models/contacts.py +0 -0
  93. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/models/custom_fields.py +0 -0
  94. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/models/households.py +0 -0
  95. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/models/notes.py +0 -0
  96. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/models/opportunities.py +0 -0
  97. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/models/projects.py +0 -0
  98. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/models/workflows.py +0 -0
  99. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/py.typed +0 -0
  100. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/self_upgrade.py +0 -0
  101. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/skills/wealthbox-crm/bootstrap.md +0 -0
  102. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/skills/wealthbox-crm/firm-examples/contacts.md +0 -0
  103. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/skills/wealthbox-crm/firm-examples/events.md +0 -0
  104. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/skills/wealthbox-crm/firm-examples/notes.md +0 -0
  105. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/skills/wealthbox-crm/firm-examples/opportunities.md +0 -0
  106. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/skills/wealthbox-crm/firm-examples/projects.md +0 -0
  107. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/skills/wealthbox-crm/firm-examples/tasks.md +0 -0
  108. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/skills/wealthbox-crm/firm-examples/workflows.md +0 -0
  109. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/skills/wealthbox-crm/references/contacts.md +0 -0
  110. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/skills/wealthbox-crm/references/households.md +0 -0
  111. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/skills/wealthbox-crm/references/notes.md +0 -0
  112. {wealthbox_cli-2.4.1 → wealthbox_cli-2.5.0}/src/wealthbox_tools/skills/wealthbox-crm/references/projects.md +0 -0
@@ -12,7 +12,7 @@ jobs:
12
12
  runs-on: ubuntu-latest
13
13
  steps:
14
14
  - uses: actions/checkout@v6
15
- - uses: astral-sh/setup-uv@v8.1.0
15
+ - uses: astral-sh/setup-uv@v8.2.0
16
16
  with:
17
17
  python-version: "3.12"
18
18
  - run: uv sync --extra dev
@@ -29,7 +29,7 @@ jobs:
29
29
  python-version: "3.12"
30
30
  steps:
31
31
  - uses: actions/checkout@v6
32
- - uses: astral-sh/setup-uv@v8.1.0
32
+ - uses: astral-sh/setup-uv@v8.2.0
33
33
  with:
34
34
  python-version: ${{ matrix.python-version }}
35
35
  - run: uv sync --extra dev
@@ -44,7 +44,7 @@ jobs:
44
44
  runs-on: ubuntu-latest
45
45
  steps:
46
46
  - uses: actions/checkout@v6
47
- - uses: astral-sh/setup-uv@v8.1.0
47
+ - uses: astral-sh/setup-uv@v8.2.0
48
48
  with:
49
49
  python-version: "3.12"
50
50
  - run: uv sync --extra dev
@@ -61,7 +61,7 @@ jobs:
61
61
  os: [ubuntu-latest, windows-latest]
62
62
  steps:
63
63
  - uses: actions/checkout@v6
64
- - uses: astral-sh/setup-uv@v8.1.0
64
+ - uses: astral-sh/setup-uv@v8.2.0
65
65
  with:
66
66
  python-version: "3.12"
67
67
  - name: Build and smoke-test clean install
@@ -76,7 +76,7 @@ jobs:
76
76
  runs-on: ubuntu-latest
77
77
  steps:
78
78
  - uses: actions/checkout@v6
79
- - uses: astral-sh/setup-uv@v8.1.0
79
+ - uses: astral-sh/setup-uv@v8.2.0
80
80
  with:
81
81
  python-version: "3.12"
82
82
  - run: uv sync --extra dev
@@ -92,7 +92,7 @@ jobs:
92
92
  environment: pypi
93
93
  steps:
94
94
  - uses: actions/checkout@v6
95
- - uses: astral-sh/setup-uv@v8.1.0
95
+ - uses: astral-sh/setup-uv@v8.2.0
96
96
  with:
97
97
  python-version: "3.12"
98
98
  - name: Check changelog matches version
@@ -1,220 +1,221 @@
1
- # Per-platform PyInstaller build + GitHub Release upload.
2
- #
3
- # Triggered on v* tags (and manually via workflow_dispatch for fork
4
- # validation). Builds a single-file ``wbox`` binary for each of the four
5
- # supported targets, computes its SHA-256, and uploads the binaries plus
6
- # a combined manifest as assets on the GitHub Release for the tag.
7
- #
8
- # The PyPI publish job lives in ci.yml and is intentionally not touched
9
- # here — both workflows fire on ``v*`` tags but operate independently.
10
- #
11
- # ----------------------------------------------------------------------
12
- # Manifest contract (LOCKED — downstream consumers: issue #42 install.sh
13
- # rewrite, issue #43 install.ps1 parity)
14
- # ----------------------------------------------------------------------
15
- # Manifest filename: SHA256SUMS.txt
16
- # Format: standard sha256sum-compatible. One record per line:
17
- # <hex-sha256><two-spaces><filename>
18
- # Sort order: ASCII-sorted by filename (stable across runs)
19
- # Binary filenames:
20
- # wbox-linux-x64
21
- # wbox-macos-arm64
22
- # wbox-macos-x64
23
- # wbox-windows-x64.exe
24
- # Manifest assets are attached to the same GitHub Release as the four
25
- # binaries. Install scripts can fetch SHA256SUMS.txt and a single binary
26
- # from the same release URL prefix and verify the binary against the
27
- # matching line.
28
- # ----------------------------------------------------------------------
29
-
30
- name: Release Binaries
31
-
32
- on:
33
- push:
34
- tags: ["v*"]
35
- workflow_dispatch: {}
36
-
37
- permissions:
38
- contents: read
39
-
40
- jobs:
41
- build:
42
- name: Build ${{ matrix.target }}
43
- runs-on: ${{ matrix.os }}
44
- strategy:
45
- fail-fast: false
46
- matrix:
47
- include:
48
- - os: ubuntu-latest
49
- target: linux-x64
50
- binary: wbox-linux-x64
51
- - os: macos-15-intel # Intel runner (x86_64) — macos-13 was retired Dec 2025
52
- target: macos-x64
53
- binary: wbox-macos-x64
54
- - os: macos-14 # Apple Silicon runner (arm64)
55
- target: macos-arm64
56
- binary: wbox-macos-arm64
57
- - os: windows-latest
58
- target: windows-x64
59
- binary: wbox-windows-x64.exe
60
- steps:
61
- - name: Checkout
62
- uses: actions/checkout@v6
63
-
64
- - name: Set up Python
65
- uses: actions/setup-python@v6
66
- with:
67
- python-version: "3.12"
68
-
69
- - name: Install runtime + build deps
70
- run: |
71
- python -m pip install --upgrade pip
72
- pip install .
73
- pip install pyinstaller
74
-
75
- - name: Build single-file binary (Unix)
76
- if: runner.os != 'Windows'
77
- shell: bash
78
- run: |
79
- pyinstaller \
80
- --onefile \
81
- --name "${{ matrix.binary }}" \
82
- --noconfirm \
83
- --collect-data wealthbox_tools \
84
- --copy-metadata wealthbox-cli \
85
- scripts/wbox_entry.py
86
- test -f "dist/${{ matrix.binary }}"
87
- chmod +x "dist/${{ matrix.binary }}"
88
-
89
- - name: Build single-file binary (Windows)
90
- if: runner.os == 'Windows'
91
- shell: pwsh
92
- run: |
93
- pyinstaller `
94
- --onefile `
95
- --name "${{ matrix.binary }}" `
96
- --noconfirm `
97
- --collect-data wealthbox_tools `
98
- --copy-metadata wealthbox-cli `
99
- scripts/wbox_entry.py
100
- if (-not (Test-Path "dist/${{ matrix.binary }}")) {
101
- throw "expected dist/${{ matrix.binary }} to exist"
102
- }
103
-
104
- - name: Smoke-test binary
105
- # `--version` only proves the entry point runs. `skills install`
106
- # exercises bundled package data — it reads
107
- # wealthbox_tools/skills/wealthbox-crm via importlib.resources — so
108
- # this fails loudly if --collect-data wealthbox_tools didn't bundle
109
- # the skill template. Runs against the fresh runner HOME with
110
- # --no-bootstrap to skip the post-install confirm prompt.
111
- run: |
112
- ./dist/${{ matrix.binary }} --version
113
- ./dist/${{ matrix.binary }} skills install --platform claude-code-user --no-bootstrap
114
-
115
- - name: Compute SHA-256 (Unix)
116
- if: runner.os != 'Windows'
117
- shell: bash
118
- working-directory: dist
119
- run: |
120
- if command -v sha256sum >/dev/null 2>&1; then
121
- sha256sum "${{ matrix.binary }}" > "${{ matrix.binary }}.sha256"
122
- else
123
- # macOS: shasum -a 256 emits sha256sum-compatible "<hash> <name>"
124
- shasum -a 256 "${{ matrix.binary }}" > "${{ matrix.binary }}.sha256"
125
- fi
126
- cat "${{ matrix.binary }}.sha256"
127
-
128
- - name: Compute SHA-256 (Windows)
129
- if: runner.os == 'Windows'
130
- shell: pwsh
131
- working-directory: dist
132
- run: |
133
- $hash = (Get-FileHash -Algorithm SHA256 "${{ matrix.binary }}").Hash.ToLower()
134
- # sha256sum format: "<hex> <filename>" (two spaces, LF line ending)
135
- $line = "$hash ${{ matrix.binary }}`n"
136
- [System.IO.File]::WriteAllText(
137
- (Join-Path $PWD "${{ matrix.binary }}.sha256"),
138
- $line
139
- )
140
- Get-Content "${{ matrix.binary }}.sha256"
141
-
142
- - name: Upload build artifact
143
- uses: actions/upload-artifact@v4
144
- with:
145
- name: wbox-${{ matrix.target }}
146
- path: |
147
- dist/${{ matrix.binary }}
148
- dist/${{ matrix.binary }}.sha256
149
- if-no-files-found: error
150
- retention-days: 7
151
-
152
- manifest-and-release:
153
- name: Combine manifest and upload to release
154
- needs: [build]
155
- runs-on: ubuntu-latest
156
- permissions:
157
- contents: write
158
- steps:
159
- - name: Download all build artifacts
160
- uses: actions/download-artifact@v4
161
- with:
162
- path: artifacts
163
-
164
- - name: Stage release files
165
- shell: bash
166
- run: |
167
- mkdir -p release
168
- # Each artifact directory contains one binary + one .sha256 file.
169
- find artifacts -type f \( -name 'wbox-*' -a ! -name '*.sha256' \) -exec cp -v {} release/ \;
170
- find artifacts -type f -name '*.sha256' -exec cp -v {} release/ \;
171
- ls -la release
172
-
173
- - name: Build combined SHA256SUMS.txt
174
- shell: bash
175
- working-directory: release
176
- run: |
177
- # Concatenate per-binary sums into a single sha256sum-compatible
178
- # manifest, ASCII-sorted by filename for stability.
179
- # Each .sha256 file is already in "<hex> <filename>" form.
180
- cat *.sha256 | LC_ALL=C sort -k 2 > SHA256SUMS.txt
181
- echo "----- SHA256SUMS.txt -----"
182
- cat SHA256SUMS.txt
183
- echo "--------------------------"
184
- # Verify the manifest against the staged binaries as a sanity check.
185
- sha256sum -c SHA256SUMS.txt
186
-
187
- - name: Upload combined manifest artifact
188
- uses: actions/upload-artifact@v4
189
- with:
190
- name: SHA256SUMS
191
- path: release/SHA256SUMS.txt
192
- if-no-files-found: error
193
-
194
- - name: Upload assets to GitHub Release
195
- if: startsWith(github.ref, 'refs/tags/')
196
- env:
197
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
198
- TAG: ${{ github.ref_name }}
199
- GH_REPO: ${{ github.repository }}
200
- shell: bash
201
- working-directory: release
202
- run: |
203
- # Ensure a release exists for the tag. If the PyPI publish job in
204
- # ci.yml or a manual release-create created it first, --clobber on
205
- # upload handles re-runs cleanly.
206
- if ! gh release view "$TAG" >/dev/null 2>&1; then
207
- gh release create "$TAG" \
208
- --title "$TAG" \
209
- --notes "Automated release for $TAG. Binaries built by release-binaries.yml; PyPI wheel published by ci.yml."
210
- fi
211
- # Upload all four binaries + the combined manifest. Per-platform
212
- # .sha256 sidecars are intentionally not uploaded SHA256SUMS.txt
213
- # is the single source of truth for installers.
214
- gh release upload "$TAG" \
215
- wbox-linux-x64 \
216
- wbox-macos-arm64 \
217
- wbox-macos-x64 \
218
- wbox-windows-x64.exe \
219
- SHA256SUMS.txt \
220
- --clobber
1
+ # Per-platform PyInstaller build + GitHub Release upload.
2
+ #
3
+ # Triggered on v* tags (and manually via workflow_dispatch for fork
4
+ # validation). Builds a single-file ``wbox`` binary for each of the four
5
+ # supported targets, computes its SHA-256, and uploads the binaries plus
6
+ # a combined manifest as assets on the GitHub Release for the tag.
7
+ #
8
+ # The PyPI publish job lives in ci.yml and is intentionally not touched
9
+ # here — both workflows fire on ``v*`` tags but operate independently.
10
+ #
11
+ # ----------------------------------------------------------------------
12
+ # Manifest contract (LOCKED — downstream consumers: issue #42 install.sh
13
+ # rewrite, issue #43 install.ps1 parity)
14
+ # ----------------------------------------------------------------------
15
+ # Manifest filename: SHA256SUMS.txt
16
+ # Format: standard sha256sum-compatible. One record per line:
17
+ # <hex-sha256><two-spaces><filename>
18
+ # Sort order: ASCII-sorted by filename (stable across runs)
19
+ # Binary filenames:
20
+ # wbox-linux-x64
21
+ # wbox-macos-arm64
22
+ # wbox-macos-x64
23
+ # wbox-windows-x64.exe
24
+ # Manifest assets are attached to the same GitHub Release as the four
25
+ # binaries. Install scripts can fetch SHA256SUMS.txt and a single binary
26
+ # from the same release URL prefix and verify the binary against the
27
+ # matching line.
28
+ # ----------------------------------------------------------------------
29
+
30
+ name: Release Binaries
31
+
32
+ on:
33
+ push:
34
+ tags: ["v*"]
35
+ workflow_dispatch: {}
36
+
37
+ permissions:
38
+ contents: read
39
+
40
+ jobs:
41
+ build:
42
+ name: Build ${{ matrix.target }}
43
+ runs-on: ${{ matrix.os }}
44
+ strategy:
45
+ fail-fast: false
46
+ matrix:
47
+ include:
48
+ - os: ubuntu-latest
49
+ target: linux-x64
50
+ binary: wbox-linux-x64
51
+ - os: macos-15-intel # Intel runner (x86_64) — macos-13 was retired Dec 2025
52
+ target: macos-x64
53
+ binary: wbox-macos-x64
54
+ - os: macos-14 # Apple Silicon runner (arm64)
55
+ target: macos-arm64
56
+ binary: wbox-macos-arm64
57
+ - os: windows-latest
58
+ target: windows-x64
59
+ binary: wbox-windows-x64.exe
60
+ steps:
61
+ - name: Checkout
62
+ uses: actions/checkout@v6
63
+
64
+ - name: Set up Python
65
+ uses: actions/setup-python@v6
66
+ with:
67
+ python-version: "3.12"
68
+
69
+ - name: Install runtime + build deps
70
+ run: |
71
+ python -m pip install --upgrade pip
72
+ pip install .
73
+ pip install pyinstaller
74
+
75
+ - name: Build single-file binary (Unix)
76
+ if: runner.os != 'Windows'
77
+ shell: bash
78
+ run: |
79
+ pyinstaller \
80
+ --onefile \
81
+ --name "${{ matrix.binary }}" \
82
+ --noconfirm \
83
+ --collect-data wealthbox_tools \
84
+ --copy-metadata wealthbox-cli \
85
+ scripts/wbox_entry.py
86
+ test -f "dist/${{ matrix.binary }}"
87
+ chmod +x "dist/${{ matrix.binary }}"
88
+
89
+ - name: Build single-file binary (Windows)
90
+ if: runner.os == 'Windows'
91
+ shell: pwsh
92
+ run: |
93
+ pyinstaller `
94
+ --onefile `
95
+ --name "${{ matrix.binary }}" `
96
+ --noconfirm `
97
+ --collect-data wealthbox_tools `
98
+ --copy-metadata wealthbox-cli `
99
+ scripts/wbox_entry.py
100
+ if (-not (Test-Path "dist/${{ matrix.binary }}")) {
101
+ throw "expected dist/${{ matrix.binary }} to exist"
102
+ }
103
+
104
+ - name: Smoke-test binary
105
+ # `--version` only proves the entry point runs. `skills install`
106
+ # exercises bundled package data — it reads
107
+ # wealthbox_tools/skills/wealthbox-crm via importlib.resources — so
108
+ # this fails loudly if --collect-data wealthbox_tools didn't bundle
109
+ # the skill template. Runs against the fresh runner HOME with
110
+ # --no-bootstrap to skip the post-install confirm prompt.
111
+ run: |
112
+ ./dist/${{ matrix.binary }} --version
113
+ ./dist/${{ matrix.binary }} skills install --platform claude-code-user --no-bootstrap
114
+
115
+ - name: Compute SHA-256 (Unix)
116
+ if: runner.os != 'Windows'
117
+ shell: bash
118
+ working-directory: dist
119
+ run: |
120
+ if command -v sha256sum >/dev/null 2>&1; then
121
+ sha256sum "${{ matrix.binary }}" > "${{ matrix.binary }}.sha256"
122
+ else
123
+ # macOS: shasum -a 256 emits sha256sum-compatible "<hash> <name>"
124
+ shasum -a 256 "${{ matrix.binary }}" > "${{ matrix.binary }}.sha256"
125
+ fi
126
+ cat "${{ matrix.binary }}.sha256"
127
+
128
+ - name: Compute SHA-256 (Windows)
129
+ if: runner.os == 'Windows'
130
+ shell: pwsh
131
+ working-directory: dist
132
+ run: |
133
+ $hash = (Get-FileHash -Algorithm SHA256 "${{ matrix.binary }}").Hash.ToLower()
134
+ # sha256sum format: "<hex> <filename>" (two spaces, LF line ending)
135
+ $line = "$hash ${{ matrix.binary }}`n"
136
+ [System.IO.File]::WriteAllText(
137
+ (Join-Path $PWD "${{ matrix.binary }}.sha256"),
138
+ $line
139
+ )
140
+ Get-Content "${{ matrix.binary }}.sha256"
141
+
142
+ - name: Upload build artifact
143
+ uses: actions/upload-artifact@v7
144
+ with:
145
+ name: wbox-${{ matrix.target }}
146
+ path: |
147
+ dist/${{ matrix.binary }}
148
+ dist/${{ matrix.binary }}.sha256
149
+ if-no-files-found: error
150
+ retention-days: 1
151
+
152
+ manifest-and-release:
153
+ name: Combine manifest and upload to release
154
+ needs: [build]
155
+ runs-on: ubuntu-latest
156
+ permissions:
157
+ contents: write
158
+ steps:
159
+ - name: Download all build artifacts
160
+ uses: actions/download-artifact@v8
161
+ with:
162
+ path: artifacts
163
+
164
+ - name: Stage release files
165
+ shell: bash
166
+ run: |
167
+ mkdir -p release
168
+ # Each artifact directory contains one binary + one .sha256 file.
169
+ find artifacts -type f \( -name 'wbox-*' -a ! -name '*.sha256' \) -exec cp -v {} release/ \;
170
+ find artifacts -type f -name '*.sha256' -exec cp -v {} release/ \;
171
+ ls -la release
172
+
173
+ - name: Build combined SHA256SUMS.txt
174
+ shell: bash
175
+ working-directory: release
176
+ run: |
177
+ # Concatenate per-binary sums into a single sha256sum-compatible
178
+ # manifest, ASCII-sorted by filename for stability.
179
+ # Each .sha256 file is already in "<hex> <filename>" form.
180
+ cat *.sha256 | LC_ALL=C sort -k 2 > SHA256SUMS.txt
181
+ echo "----- SHA256SUMS.txt -----"
182
+ cat SHA256SUMS.txt
183
+ echo "--------------------------"
184
+ # Verify the manifest against the staged binaries as a sanity check.
185
+ sha256sum -c SHA256SUMS.txt
186
+
187
+ - name: Upload combined manifest artifact
188
+ uses: actions/upload-artifact@v7
189
+ with:
190
+ name: SHA256SUMS
191
+ path: release/SHA256SUMS.txt
192
+ if-no-files-found: error
193
+ retention-days: 1
194
+
195
+ - name: Upload assets to GitHub Release
196
+ if: startsWith(github.ref, 'refs/tags/')
197
+ env:
198
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
199
+ TAG: ${{ github.ref_name }}
200
+ GH_REPO: ${{ github.repository }}
201
+ shell: bash
202
+ working-directory: release
203
+ run: |
204
+ # Ensure a release exists for the tag. If the PyPI publish job in
205
+ # ci.yml or a manual release-create created it first, --clobber on
206
+ # upload handles re-runs cleanly.
207
+ if ! gh release view "$TAG" >/dev/null 2>&1; then
208
+ gh release create "$TAG" \
209
+ --title "$TAG" \
210
+ --notes "Automated release for $TAG. Binaries built by release-binaries.yml; PyPI wheel published by ci.yml."
211
+ fi
212
+ # Upload all four binaries + the combined manifest. Per-platform
213
+ # .sha256 sidecars are intentionally not uploaded SHA256SUMS.txt
214
+ # is the single source of truth for installers.
215
+ gh release upload "$TAG" \
216
+ wbox-linux-x64 \
217
+ wbox-macos-arm64 \
218
+ wbox-macos-x64 \
219
+ wbox-windows-x64.exe \
220
+ SHA256SUMS.txt \
221
+ --clobber
@@ -4,6 +4,81 @@ 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.5.0] - 2026-09-20
8
+
9
+ Fills in the work-record commands an AI agent needs, and corrects two list
10
+ defaults that were quietly returning a slice of the data.
11
+
12
+ ### Fixed
13
+
14
+ - **`wbox tasks list --include-completed` returned completed tasks *only*.**
15
+ Wealthbox's `completed` parameter is a two-way switch, not an "include":
16
+ omitted or `false` means open only, `true` means completed only. The flag
17
+ mapped to `completed=true`, so it did the opposite of its name. It is now a
18
+ hidden alias for `--status all` and keeps working in existing prompts.
19
+ - **A bad `--category`, `--advisor-role`, or `--custom-field` value printed
20
+ "Unexpected error".** These resolvers raise `BadParameter` from inside the
21
+ command body, after Click's own parsing is finished, so the generic handler
22
+ caught them. `handle_errors` now renders them as the user errors they are.
23
+ The exit code was already 1 and has not changed.
24
+
25
+ ### Added
26
+
27
+ - **`wbox tasks list --status open|completed|all`** (default `open`). `all`
28
+ issues both calls in sequence and merges by `id`, keeping the copy with the
29
+ later `updated_at`. In a firm with 5,174 tasks, 4,994 of them complete, the
30
+ default was showing 3% of the record set without saying so.
31
+ - **`wbox workflows list --status all`**, alongside the existing `active`,
32
+ `completed`, and `scheduled`. The default is now an explicit `active`, which
33
+ is what the API did all along when given no status. `all` runs three
34
+ sequential calls and merges by `id`.
35
+ - **`wbox teams list`** and **`wbox users groups`**. Team IDs are what
36
+ `--assigned-to-team` expects and there was no way to look one up; group IDs
37
+ are what `visible_to` accepts. Both render `id`, `name`, and `member_count`,
38
+ with the full member list under `--verbose`.
39
+ - **`wbox comments list`**, filtered by `--task`, `--event`, `--note`,
40
+ `--opportunity`, `--project`, or `--workflow`, or by an
41
+ `--updated-since`/`--updated-before` window. An unfiltered call exits 1 with
42
+ a one-line reason: `GET /comments` costs about 8.5 seconds per page of 100
43
+ unfiltered, against about 1.5 seconds inside a one-month window.
44
+ - **`wbox workflows next` now lists the active step's outcomes** (`id`, `name`,
45
+ `action`, `go_to_step_id`) in JSON and on stderr, so they stay readable in
46
+ every `--format`. `complete-step --outcome-id` is the only way to branch such
47
+ a step and the IDs appeared nowhere else in the CLI. `complete-step`'s own
48
+ advance hint lists them too.
49
+ - **`--custom-field NAME=VALUE` on `tasks add|update` and `events add|update`**
50
+ (repeatable, accepts a name or a numeric ID). Names are resolved against
51
+ `wbox categories custom-fields --document-type Task|Event` and an unknown
52
+ name is a hard error listing the valid ones. That check is load-bearing:
53
+ Wealthbox accepts a custom-field payload keyed by name with a 200 and then
54
+ silently discards it.
55
+
56
+ ### Changed
57
+
58
+ - Help text on `wbox opportunities list` and `--include-closed` now says that
59
+ closed opportunities are dropped by default (117 records in the firm, 73
60
+ returned). No behavior change.
61
+ - New `references/comments.md`; the tasks, workflows, opportunities, events,
62
+ and lookups references document the defaults, the new flags, and the
63
+ teams/user-group lookups.
64
+
65
+ ### Not built
66
+
67
+ - **`wbox comments add`.** The token-authenticated v1 REST API cannot write a
68
+ comment: `POST /v1/comments` returns a response byte-identical to a
69
+ nonexistent path, as does `POST /v1/tasks/{id}/comments`. The write route
70
+ lives on Wealthbox's session-authenticated web surface (`POST /comments`
71
+ without the `/v1` prefix answers 302 to `/users/login`), which the official
72
+ Wealthbox MCP reaches over OAuth via its `CreateComment` tool. Supporting it
73
+ from `wbox` would mean driving a logged-in web session with CSRF tokens, a
74
+ different auth model than the rest of the CLI. `references/comments.md`
75
+ documents the MCP-writes / `wbox`-reads split; a comment created through the
76
+ MCP is immediately readable by `wbox comments list`.
77
+ - **`tasks add --parent`.** The API takes subtasks only as inline objects in a
78
+ parent task's create payload, never as a `parent` reference on a child. The
79
+ read side's `parent {id, type}` object has no write counterpart. Use
80
+ `--more-fields '{"subtasks": [...]}'`.
81
+
7
82
  ## [2.4.1] - 2026-06-12
8
83
 
9
84
  Patch release fixing a startup crash in 2.4.0. The `cli/_factory.py` module
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: wealthbox-cli
3
- Version: 2.4.1
3
+ Version: 2.5.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/
@@ -95,7 +95,7 @@ If you're new to Claude Code itself, [download it here](https://claude.ai/downlo
95
95
 
96
96
  ## What it covers
97
97
 
98
- Full read/write access for **contacts** (people, households, organizations, trusts), **tasks**, **events**, **notes**, **opportunities**, **projects**, and **workflows**. Read access for users, activity, and your firm's category lookups.
98
+ Full read/write access for **contacts** (people, households, organizations, trusts), **tasks**, **events**, **notes**, **opportunities**, **projects**, and **workflows**. Read access for users, teams, user groups, comments, activity, and your firm's category lookups.
99
99
 
100
100
  Anything you can do in Wealthbox manually, the agent can do for you — usually in one sentence.
101
101
 
@@ -53,7 +53,7 @@ If you're new to Claude Code itself, [download it here](https://claude.ai/downlo
53
53
 
54
54
  ## What it covers
55
55
 
56
- Full read/write access for **contacts** (people, households, organizations, trusts), **tasks**, **events**, **notes**, **opportunities**, **projects**, and **workflows**. Read access for users, activity, and your firm's category lookups.
56
+ Full read/write access for **contacts** (people, households, organizations, trusts), **tasks**, **events**, **notes**, **opportunities**, **projects**, and **workflows**. Read access for users, teams, user groups, comments, activity, and your firm's category lookups.
57
57
 
58
58
  Anything you can do in Wealthbox manually, the agent can do for you — usually in one sentence.
59
59
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "wealthbox-cli"
7
- version = "2.4.1"
7
+ version = "2.5.0"
8
8
  description = "CLI and client library for the Wealthbox CRM API"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -123,6 +123,19 @@ def handle_errors(func: Callable[_P, _R]) -> Callable[_P, _R]:
123
123
  typer.echo(traceback.format_exc(), err=True)
124
124
  raise typer.Exit(code=_EXIT_VALIDATION)
125
125
 
126
+ except typer.BadParameter as e:
127
+ # Raised from inside a command body by the id/name resolvers
128
+ # (categories, contact roles, custom fields) once a client is in
129
+ # hand. Click only renders BadParameter it raises itself during
130
+ # parsing, so without this the generic handler below would label a
131
+ # plain user typo "Unexpected error". Exit 1, matching every other
132
+ # validation failure. (typer re-exports BadParameter, so this needs
133
+ # no runtime `import click` — see the 2.3.1/2.4.1 crashes.)
134
+ typer.echo(f"Error: {e.format_message()}", err=True)
135
+ if _debug_enabled():
136
+ typer.echo(traceback.format_exc(), err=True)
137
+ raise typer.Exit(code=_EXIT_VALIDATION)
138
+
126
139
  except ValueError as e:
127
140
  typer.echo(f"Error: {e}", err=True)
128
141
  if _debug_enabled():