Repository navigation
feat: shared foundation for API-backed commands, and the api command - #45
Merged
Merged
Conversation
The reusable pieces auth, products and later commands build on: - api.rs: the source.coop API client (/api/v1), its errors and pages - failure.rs and fail(e, json): JSON errors under --json and one table of exit codes for every command (3 rejected input, 4 not signed in or not allowed, 5 not found, 130 interrupted, else 1) - output::json for --json output; style.rs for color (NO_COLOR, gray IDs) - prompt.rs (scriptable prompts, Esc/Ctrl+C, typed confirmation, an Esc-able line editor), picker.rs (the -i list and full screen) and draft.rs (answers kept when a send fails) - AGENTS.md (with CLAUDE.md importing it): the CLI's conventions, including the JSON-output rules And its first user, source-coop api, which sends any /api/v1 request as the signed-in user. Pieces no command uses yet are allowed as dead code until the commands that use them land. Access tokens issued without an API audience are no longer sent to the API. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Claude finished @alukach's task in 21s —— View job ✅ No blocking issues — safe to merge. I read the API client,
Non-blocking notes:
Simplify (ponytail)
💰 Estimated review cost: $0.18 · 0m21s · 9 turns |
This was referenced Oct 14, 2026
Closed
Closed
- An error status from `source-coop api` went through to_string(), skipping what records its code and status, so every failure exited 1. It goes through From now: a 404 exits 5, a 401 or 403 exits 4, and --json errors carry the code and status. - -X GET with --input is refused rather than sending a body on a GET. - Paths with .. that leave /api/v1 are refused, as a full URL elsewhere already was. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- style: color detection is console's colors_enabled / colors_enabled_stderr (NO_COLOR, CLICOLOR), still only on a terminal. - prompt: the *_or_back methods are required; every prompter has them. - picker: one answered() line writer and one keep() for where browse left off, the two go-back arms merged, keypress's doc comment back on it. - failure: keeps the ApiError itself and serializes Failure with serde. - api: error causes via iter::successors; the api command prints JSON through output::json; main's api_token and api arm without the match-on-Result dances; cache_dir private again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
alukach
marked this pull request as ready for review
October 14, 2026 21:29
This was referenced Oct 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The shared base that the
authandproductcommands, and later ones, build on, plus its first user, theapicommand. Together with the Auth and Products PRs stacked on it, this supersedes #24, #40, #41 and #44, which mixed these concerns.What
src/api.rs: the source.coop API client (/api/v1), its errors (ApiError, with field errors and a sign-in hint on 401) and pages (Page,next_cursor).src/failure.rsandfail(e, json): under--json, a failure prints as{"error": {"code", "message", "status"?, "field_errors"?}}on stderr, and every command exits by kind:Commands pass errors around as plain text (
String), which drops the API's code, status and field errors.failure.rsrecovers them; it's a deliberate bridge, marked with aponytail:comment naming the proper fix: a typed error.output::jsonfor--jsonoutput, andsrc/style.rsfor color: only on a terminal, never withNO_COLOR, gray IDs, andago().Prompting and interaction:
src/prompt.rs: a scriptablePrompter; Esc andqcancel (CANCELLED), Ctrl+C interrupts (exit 130); typed confirmation; a line editor Esc can cancel.src/picker.rs: the-ilist and full screen.src/draft.rs: keeps your answers when a send fails.Conventions:
AGENTS.md, imported byCLAUDE.md, covers commands, input, prompts, the picker, output, the JSON-output rules, stored data, testing and git.source-coop api: sends any/api/v1request as the signed-in user (SOURCE_TOKENoverrides). Access tokens issued without an API audience are no longer sent, since they'd turn public reads into 401s.README:
api, and JSON output and exit codes.Modules no command uses yet are marked
#[allow(dead_code)], with a comment. The Products PR removes the markers, since it uses every module.Stack
mainauth login | status | logout | token) → this PRproduct …,-i) → this PRAuth and Products are independent. Whichever merges second needs a small rebase: both add to
main.rs's module list, command enum and tests, and to the README. That union is verified: merging the two reproduces the combined code with all 103 tests passing.Testing
cargo testandcargo test --features staging: 51 passed, includingevery_command_is_in_the_readme.cargo clippy --all-targets -- -D warnings(both builds) andcargo fmt --check: clean.🤖 Generated with Claude Code