chois a Rust workspace for FreeAgent automation:crates/cho-sdk/owns OAuth, transport, resources, and finance heuristics;crates/cho-cli/exposes a compact JSON-first command surface;crates/cho-tui/is a read-first ratatui navigator over the same config, auth, and runtime state.
- Primary external references: FreeAgent docs hub, Introduction, OAuth, Changes feed
- Local source-of-truth files:
crates/cho-cli/src/main.rs,crates/cho-cli/src/registry.rs,crates/cho-sdk/src/api/specs.rs,crates/cho-sdk/src/client.rs,crates/cho-sdk/src/liabilities.rs,crates/cho-tui/src/routes.rs,crates/cho-tui/src/api.rs - Contract-heavy tests:
crates/cho-cli/tests/cli_contract.rs,crates/cho-cli/tests/cli_drift.rs,crates/cho-sdk/tests/http_contract.rs - Canonical repo instructions live in
AGENTS.md;CLAUDE.mdandREADME.mdmirror it in this repository
.
├── crates/
│ ├── cho-sdk/ reusable FreeAgent client, auth, resource specs, liabilities logic
│ ├── cho-cli/ clap CLI, audit log, output envelopes, command registry, tests
│ └── cho-tui/ ratatui app, route catalog, background fetch worker, cache
├── AGENTS.md canonical repo-level instructions
├── Cargo.toml workspace manifest and shared Rust deps/lints
├── package.json Bun quality gate and release/install wrapper
└── .husky/ pre-commit and commit-msg hooks
- Start in
crates/cho-cli/src/commands/for user-facing command changes,crates/cho-sdk/src/for API/auth/transport behavior, andcrates/cho-tui/src/for interactive navigation - Treat
crates/cho-cli/src/registry.rs,crates/cho-sdk/src/api/specs.rs, andcrates/cho-tui/src/routes.rsas catalog files that often need coordinated edits
| Layer | Choice | Notes |
|---|---|---|
| Workspace | Rust 2024 | three-crate workspace with shared deps in Cargo.toml |
| SDK/runtime | tokio + reqwest + rustls |
async transport, pagination, retries, 401 refresh, 429 handling |
| CLI | clap + custom JSON/Toon envelope adapters |
default stdout is one compact JSON envelope; --toon emits the same structured envelope |
| TUI | ratatui + crossterm |
direct SDK consumer with background fetch worker and persisted cache |
| Auth/secrets | OAuth code flow + secrecy |
tokens stored in tokens.json, login callback defaults to 127.0.0.1:53682 |
| JS tooling | Bun + Husky + commitlint + Biome | hooks, lockfile, and util:* quality orchestration only |
bun installinstalls JS tooling and Husky hookscargo run -p cho-cli -- toolsandcargo run -p cho-cli -- tools <name>are the authoritative machine-readable command catalogcargo run -p cho-cli -- healthchecks home/config/credentials/audit/token readiness before trying real workcargo run -p cho-cli -- --help,cargo run -p cho-cli -- start, andcargo run -p cho-tuiare the fastest local iteration pathscargo test --workspaceruns all Rust tests; use the crate-specific contract suites when narrowing failuresbun run util:checkis the required full gate before completionbun run buildbuilds release binaries and installschopluscho-tuiinto${CHO_HOME:-${TOOLS_HOME:-$HOME/.tools}/cho}/
crates/cho-cli/src/main.rsbootstrapsconfig -> audit -> auth -> FreeAgentClient; early commandstools,health,config, andstartintentionally bypass full API bootstrapcrates/cho-cli/src/audit.rsis safety-critical: it recordscommand.start/input/output/endplus HTTP request/response events, redacts secrets, and hard-fails bootstrap when the audit log is unavailablecrates/cho-sdk/src/client.rsenforces same-origin absolute URLs, clamps pagination, followsLinkpagination, retries rate limits/transient failures, refreshes on 401, and blocks mutating requests unlessallow_writesis enabledcrates/cho-sdk/src/liabilities.rsis the non-trivial finance layer behindtax-calendar,taxes reconcile, andsummary; it merges company, payroll, bank, and optional self-assessment data and adds derivedstatus_trustfieldscrates/cho-cli/src/registry.rsandcrates/cho-sdk/src/api/specs.rsare hand-maintained, not generated; command/resource additions usually also require test updates and TUI route decisionscrates/cho-tui/src/api.rstalks tocho-sdkdirectly rather than shelling out tocho;crates/cho-cli/src/commands/start.rsonly launches a sibling orPATHcho-tuibinary
- Home resolution order is
CHO_HOME->TOOLS_HOME/cho->$HOME/.tools/choviacrates/cho-sdk/src/home.rs - Runtime files live outside the repo:
config.toml,history.log,tokens.json, andtui-cache.jsonunder the resolvedchohome - CLI credential precedence is
--client-id/--client-secret->CHO_CLIENT_ID/CHO_CLIENT_SECRET->config.tomlauth.*; SDK base URL precedence isCHO_BASE_URL->config.tomlsdk.base_url-> FreeAgent default auth status,health, CLI bootstrap, and TUI startup all call trusted session checks that can refresh tokens and rewritetokens.json; these are not read-only inspections- TUI route data uses stale-while-revalidate caching in
crates/cho-tui/src/cache.rs; preview and full payloads persist totui-cache.json, oversized cache files are rejected, and stale cached data may be shown while a refresh is in flight - Structured mode writes only the selected envelope to stdout; default output is compact JSON,
--toonswitches the envelope to Toon, and--verboseenables tracing to stderr
cho toolsis the authoritative contract surface;crates/cho-cli/tests/cli_contract.rsandcrates/cho-cli/tests/cli_drift.rsreject duplicate names, stale help/output metadata, and any reintroduction of the removed--jsonflag- Generic resource writes consume JSON files up to 50 MB, auto-wrap unwrapped payloads under the singular resource key, and support repeated
--query key=valuepairs for FreeAgent edge cases - Bank transaction explanation updates can attach local files; attachments are base64-encoded client-side, MIME-sniffed by extension, and capped at FreeAgent's 5 MB limit
- Several surfaces are client-composed rather than direct endpoint pass-through: cross-account bank transaction listing, invoice
--unpaid-onlyfiltering, grouped category flattening, tax-calendar assembly, HMRC reconciliation, and TUI bank annotations --precisepreserves decimal-like JSON values as strings; JSON output also compact-redacts signed company logo URLs instead of dumping volatile query tokens
- Never commit or hand-edit runtime state under
CHO_HOME, includingconfig.toml,tokens.json,history.log,tui-cache.json, or binaries installed bybun run build - Never bypass
[safety] allow_writes = true; write blocking is enforced in bothcrates/cho-cli/src/context.rsandcrates/cho-sdk/src/client.rs - Never trust arbitrary absolute resource URLs; the SDK only accepts
http(s)URLs on the configured FreeAgent origin and base path - Treat
crates/cho-cli/src/registry.rs,crates/cho-sdk/src/api/specs.rs,crates/cho-tui/src/routes.rs,crates/cho-cli/tests/cli_contract.rs, andcrates/cho-cli/tests/cli_drift.rsas a coordinated change set for command-surface work - Keep stdout clean in JSON mode; ad-hoc diagnostics break the machine contract and belong on stderr or in the audit log
- Required gate:
bun run util:check - If you change CLI command surface, registry metadata, help text, output envelopes, or write gating, run
cargo test -p cho-cli --test cli_contract --test cli_driftand smokecargo run -p cho-cli -- tools - If you change SDK auth, transport, pagination, absolute URL handling, or resource behavior, run
cargo test -p cho-sdk --test http_contract - If you change TUI routes, fetch context, cache logic, or palette/navigation behavior, run
cargo run -p cho-tuiand verify startup warnings, palette prompts, stale-cache revalidation, and route refresh with a seededCHO_HOME - For mutating workflows, validate both the default blocked path and an explicit
[safety] allow_writes = truepath - There is no checked-in CI workflow; the local commands above are the completion bar