This file provides guidance to AI coding agents when working with code in this repository.
- When users ask questions, answer them instead of doing the work.
- When making changes to user-visible behavior (commands, output, storage, configuration),
update
website/docs/(andwebsite/i18n/ja/) andREADME.mdaccordingly.
- Always use
rm -f(never barerm) - Before running a series of
gitcommands, confirm you are in the project root; if not,cdthere first. Then run all subsequentgitcommands from that directory without the-Coption.
Backlog CLI tool written in Rust. The main command is bl.
bl auth login— Save space key and API key (stored in system keyring)bl auth status— Show auth info and verify credentials via APIbl auth logout— Remove credentialsbl space— Show space information
src/
main.rs - CLI entry point (clap subcommands)
config.rs - ~/.config/bl/config.toml (non-sensitive metadata)
secret.rs - Credential storage: keyring (primary) with file fallback (~/.config/bl/credentials.toml)
api/
mod.rs - BacklogClient + BacklogApi trait
space.rs - GET /api/v2/space → Space struct
user.rs - GET /api/v2/users/myself → User struct
cmd/
auth.rs - auth login / status / logout
space/
mod.rs - pub use re-exports
show.rs - space show
activities.rs
disk_usage.rs
notification.rs
project/
mod.rs - pub use re-exports
list.rs - project list
show.rs - project show
main.rs (clap) → cmd/* → BacklogClient::from_config() → BacklogClient::get() → Backlog API
from_config() loads config.toml for the space key, then retrieves the API key from the credential store.
- Add a new file
src/api/<resource>.rswith the response struct and animpl BacklogClientblock. - Add the method to the
BacklogApitrait insrc/api/mod.rs. - Add
pub mod <resource>insrc/api/mod.rs.
Commands are organized as directories (src/cmd/<resource>/) with one file per subcommand.
- Create
src/cmd/<resource>/<subcommand>.rswith:- A public
<subcommand>(args…) -> Result<()>that callsBacklogClient::from_config()and delegates. - A public
<subcommand>_with(args…, api: &dyn BacklogApi) -> Result<()>for the real logic (testable).
- A public
- Add
mod <subcommand>;andpub use <subcommand>::<subcommand>;tosrc/cmd/<resource>/mod.rs. - Register the subcommand in
src/main.rs.
See docs/TESTING.md for the full testing guide.
Summary:
api/layer: Usehttpmockto spin up a local HTTP server; constructBacklogClient::new_with(base_url, api_key).cmd/layer: ImplementBacklogApion aMockApistruct; call*_with(&args, &mock)directly.- Never call
BacklogClient::from_config()in tests — it requires real credentials on disk.
- Use
anyhowfor error handling throughout. - API key is stored via
CredentialStoretrait: keyring first, falling back to~/.config/bl/credentials.toml(0600). space_keyis stored in~/.config/bl/config.toml(non-sensitive).- HTTP client uses
reqwest(blocking) withrustls-tls(no OpenSSL dependency). BacklogClient::from_config()loads both config and credentials automatically.
See docs/VALIDATION.md for the full validation guide.
Summary:
main.rs(clap) — Syntactic/type-level checks only (e.g. "cannot parse as u64").Args::try_new— Domain invariants that must hold before any logic runs.cmd/*_with— API call logic and output formatting. API-spec constraints that depend on runtime data may also live here.api/— HTTP-level error translation only.
All Rust commands must be run via mise tasks — never call cargo directly.
mise run rs-build # build
mise run rs-check # clippy + fmt check + tests (Rust only)
mise run rs-fix # auto-fix clippy and fmt
mise run check # full check: run before committing (markdown + actions + spelling + rust)
mise run fix # auto-fix all: run before committingmise run release -- patch # Bump version (patch / minor / major) -> create tag and push to trigger CI release