Releases: alexph-dev/qbo-cli
v0.9.0 — Refactor Marathon
Refactor Marathon — Zero Behavior Change
Full-package restructure following six software experts in sequence.
qbo_cli/cli.py went from 1936 → 109 LOC (−94%), split into 13
cohesive modules. 177/177 tests green at every commit boundary.
Highlights
- Packaging: ships PEP 561
py.typedmarker — downstream consumers now get type hints fromqbo_cli. - Version SoT:
__version__derives fromimportlib.metadata(installed wheels) orpyproject.toml(source checkouts). Single source of truth. - Tooling: mypy
check_untyped_defs = truefor stricter verification ofqbo_cli. RuffB(bugbear) rule added. - Security: OAuth CSRF state now uses
secrets.token_hex(canonical stdlib security API). - Internals:
QBOClient.requestsplit into focused helpers with hardened malformed-Fault fallback.TokenManagergains publicrefresh_if_needed(). GL report rendering now uses a pure_RenderCtxparameter object.
Modules after split
qbo_cli/
├── cli.py 109 # main() + dispatch only
├── constants.py 25
├── errors.py 16
├── qbo_query.py 10
├── report_registry.py 70
├── output.py 221
├── cli_options.py 91
├── config.py 83
├── auth.py 415
├── client.py 156
├── gl_report.py 727
├── commands.py 91
├── parser.py 179
└── py.typed 0
Waves
Applied in order: Uncle Bob (module extraction) → Fowler (refactoring catalog) → Beck (tidy-first, structure-only) → Metz (POODR) → Henney (naming) → Brett Cannon (packaging + compat). Each wave verified with ruff + mypy + pytest + CLI smoke + codex review. Full scoreboard and per-wave summary at 03_notes/2026-04-11-refactor-marathon/README.md.
Zero CLI behavior change
Every subcommand, every flag, every error message, every exit code: identical. 52 commits, 0 P1 findings from codex, 2 P2 fixes applied inline (_extract_error_detail malformed-Fault fallback, source-checkout __version__ regression).
Compatibility
- Python 3.9+ (unchanged floor)
- Same dependency set (
requests>=2.28) - Same CLI API
v0.8.0
What's New
Void transactions (qbo void)
Void keeps transactions on the books as $0, preserving the audit trail — unlike delete which removes them entirely. Works with Invoice, SalesReceipt, Payment, BillPayment, CreditMemo, and other voidable entities.
qbo void Invoice 1042Named profiles (--profile, --sandbox)
Isolate dev/prod credentials with named profiles. Mirrors Intuit's two-environment model (Development + Production key pairs).
qbo auth setup # production (default)
qbo --profile dev auth setup # development/sandbox
qbo --sandbox query "SELECT * FROM Customer" # shorthand for --profile devConfig file now uses profiled format:
{
"prod": { "client_id": "...", "client_secret": "..." },
"dev": { "client_id": "...", "client_secret": "...", "sandbox": true }
}Other changes
- Consolidated
docs/and02_docs/directories (docsis now a symlink to02_docs/) - 29 black-box sandbox CRUD edge-case tests
- Profile name validation (path traversal prevention, case normalization)
- Legacy flat config auto-detection with migration path
- Fixed SonarCloud reliability issues (float comparisons, variable shadowing)
v0.7.0
What's New
qbo search— generic local text search over query results- Flexible date input — DD.MM.YYYY, DD/MM/YYYY with
-b/-eshorthands -b/--beginalias for--startingl-report
Security & Performance
- OAuth
stateparameter validation (CSRF protection) - Lock file permissions restricted to
0o600 - O(n) account tree and GL section lookups (was O(n^2))
Fixes
gl-reportformat flags honored across all branches- LIKE wildcard
%no longer stripped in query escaping - Version single-sourced from
__init__.py - Python 3.9 compatibility restored
Infrastructure
- Simplified CLI parser and command dispatch
- GitHub Actions pinned to immutable commit SHAs
- Comprehensive test suite — 134 tests
- ast-grep rules for security and code quality linting
Full Changelog: v0.6.0...v0.7.0
v0.6.0
What's Changed
- fix: Honor user-specified MAXRESULTS and STARTPOSITION in queries (auto-pagination no longer overwrites explicit limits)
- ci: Lint (ruff) on every push/PR, auto-publish to PyPI on release
- style: Code formatted with ruff
Full Changelog
v0.4.1 — Security & Cleanup
Security
- Fix SQL injection in customer/account name queries (single-quote escaping)
~/.qbo/directory permissions hardened to700(was755)
Improvements
qbo --version/qbo -V- Imports moved to module level
- Removed redundant computations in JSON output
Upgrade
pip install --upgrade qbo-cliv0.4.0 — GL Reports & Smart Output
What's New
GL Report command (qbo gl-report)
- Hierarchical General Ledger reports for any account & customer
- Auto-discovers sub-account tree from QBO
- Output modes:
-o text(default),json,txns(flat transaction list),expanded(tree + transactions) --by-customer / -g: group by customer with smart depth-1 grouping--no-sub: roll up sub-accounts into parent-s alpha|amount: sort order for customer grouping--list-accounts: explore chart of accounts- Date range defaults to first transaction → today
Quality of life
qbo auth setup: interactive config wizard for first-run- Text table output is now the default for all commands
-o text/json/tsvworks on query, get, report, raw subcommands- Entity paths auto-lowercase (no more casing errors)
- Single entity
getshows clean key-value format
Install / Upgrade
pip install --force-reinstall git+https://github.com/alexph-dev/qbo-cli.git@v0.4.0v0.1.0 — Initial Release
First release of qbo-cli — the command-line interface for QuickBooks Online API.
Features
- OAuth2 authentication with auto token refresh and rotation
- Query entities using QBO's SQL-like syntax with automatic pagination
- CRUD operations on all QBO entity types
- Financial reports (P&L, Balance Sheet, Cash Flow, AR/AP aging)
- Raw API access for advanced use cases
- JSON and TSV output formats
- File-locked atomic token storage
Install
pip install qbo-cli
See README for setup instructions.