typefully 0.1.0

A full-featured CLI client for the Typefully API v2
Documentation
# AGENTS.md

Instructions for AI coding agents working on the typefully-cli project.

## Project Overview

A full-featured CLI client for the [Typefully API v2](https://typefully.com), written in Rust. Lets users create, schedule, manage, and publish social media drafts from the terminal.

## Project Structure

```
typefully-cli/
  src/
    main.rs          # Entry point, command dispatch, tokio runtime
    lib.rs           # Public module re-exports
    api/
      mod.rs         # TypefullyApi trait definition + re-exports
      client.rs      # TypefullyClient (concrete HTTP implementation)
      types.rs       # Shared types: Platform, DraftStatus, DraftListParams
    cli/
      mod.rs         # Clap derive structs (Cli, Commands, DraftCmd, etc.)
    config/
      mod.rs         # Config file loading/saving, API key + set ID resolution
    output/
      mod.rs         # Table rows, JSON output, formatting helpers
    error.rs         # Error hierarchy: AppError, ApiError, ConfigError
  .github/
    workflows/
      ci.yml         # PR checks: test, clippy, fmt
      release.yml    # Version bump, cross-compile, GitHub Release, crates.io, Homebrew
  Cargo.toml
  rustfmt.toml
  LICENSE            # GPL-3.0-only
  README.md
```

## Conventions

### Rust Edition and Toolchain
- **Edition:** 2024
- **MSRV:** 1.91
- **Lints:** `unsafe_code = "forbid"`, `clippy::all = "deny"`, `clippy::pedantic = "warn"`

### Async Runtime
- Use `tokio` with the `full` feature set
- All API calls are async. The `#[tokio::main]` macro is in `main.rs`
- Never use blocking reqwest

### Error Handling
- `thiserror` for all error type derivations
- Three error enums: `AppError` (top level), `ApiError` (HTTP/API layer), `ConfigError` (file/parse)
- All errors implement `Display` via thiserror
- Exit codes: 0 = success, 1 = API/runtime error, 2 = invalid usage

### Logging
- Use `tracing` macros (`debug!`, `info!`, `warn!`) instead of `eprintln!` for diagnostics
- `tracing-subscriber` with env-filter, writing to stderr
- `--verbose` sets the filter to `debug`; default is `warn`

### Secrets
- API keys are wrapped in `secrecy::SecretString`
- Never log or display API keys. Use `ExposeSecret` only at the point of HTTP auth

### API Client Pattern
- `TypefullyApi` trait in `src/api/mod.rs` defines all API operations
- `TypefullyClient` in `src/api/client.rs` is the concrete implementation
- Command handlers accept `&impl TypefullyApi` so they are testable with mocks
- `mockall` is available in dev-dependencies

### CLI Arguments
- `clap` with derive macros
- Global flags: `--json`, `--no-color`, `-q`/`--quiet`, `-v`/`--verbose`, `--api-key`
- Social set ID: `--set` flag, falls back to config default

### Output
- Human-friendly tables via `tabled` crate (default)
- `--json` flag outputs raw JSON to stdout
- Success/error messages go to stderr
- Respect `NO_COLOR` env var

### Config
- Config file at `~/.config/typefully/config.toml` (via `dirs` crate for XDG)
- Fields: `api_key`, `default_social_set_id`
- Key resolution order: `--api-key` flag > `TYPEFULLY_API_KEY` env > config file

### Branch
- Default branch: `main` (not master)
- All workflows and references use `main`

## Building and Testing

```bash
# Check compilation
cargo check

# Run clippy (must pass with zero warnings)
cargo clippy -- -D warnings

# Build release
cargo build --release

# Run
cargo run -- --help
```

## Writing Style

- Never use em dashes in any text (README, help text, comments, doc comments)
- Use colons, commas, periods, or parentheses instead
- Keep help text concise

## Adding a New Subcommand

1. Add the clap struct/variant in `src/cli/mod.rs`
2. Add the API trait method in `src/api/mod.rs`
3. Implement it in `src/api/client.rs`
4. Add a command handler function in `src/main.rs`
5. Wire it into the `run()` match in `src/main.rs`
6. Run `cargo clippy -- -D warnings` before committing

## Adding a New API Type

1. Define it in `src/api/types.rs`
2. Re-export it via `pub use types::*` in `src/api/mod.rs`
3. Add `#[non_exhaustive]` on public enums
4. Derive `Debug`, `Clone`, and implement `Display` where appropriate