feat(cli): club targeting via --club/--all + current_club (#86)#123
Merged
Conversation
Replace positional club slugs across the CLI with a uniform --club option and a current-club context pointer, the cleaner way to deliver #86's intent. Why the redesign over the issue's "optional positional slug": an optional positional is ambiguous for `blacklist add/remove` (slug precedes the username positionals). Moving the club to an option dissolves that and gives one git/kubectl-style targeting model everywhere. - Targeting: `--club <slug>` (comma-separated on membership/history) and `--all` (every managed club, expanded client-side via /api/managed-clubs so the server API is unchanged). Neither given -> falls back to current_club. `--all` together with `--club` is rejected: conflicting intent, almost always a mistake. - `ccas use-club <slug>`: a local config write (no server) that sets current_club. Top-level, not under `club`, because it's a client-local focus pointer while the `club` group is server-side managed-set ops. Server-validation was rejected on purpose: a fresh user / not-yet-fetched club has nothing to validate against, so it warns (offline, vs the completion cache) but never blocks. - ConfigWriter: surgical single-key HOCON edit (zio-config has no writer), written atomically via temp-file + same-dir rename so a crash/concurrent writer can't leave a half-written config. - Trim CLI club input at the resolver/use-club boundary, since ClubSlug.normalize only lowercases. - Rename the managed-clubs group `clubs` -> `club` (singular, idiomatic per gh/docker/git-remote). - Completion: club-slug completion moves from positionals to the `--club` value flag (plus the `use-club` positional); drift guard now sees hyphenated commands. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ETHm6wCYdzFuB3kNEBayjF
This was referenced Jun 25, 2026
Sootopolis
added a commit
that referenced
this pull request
Jun 25, 2026
Regression from #123. `club add`/`remove` manage the membership set itself, so the club is the direct operand (like `git remote add <name>`), not the `--club` context option the operation commands use. With `--club`, the natural `ccas club add <slug>` silently dropped the slug as an unparsed operand and failed with "no club specified". Revert these two to a required positional slug (no `--club`, no current_club fallback). Also fix a latent completion bug from the same PR: the `clubs` -> `club` group rename missed the CompletionSpec *leaves* (still `List("clubs", …)`), so `leavesOf("club")` was empty — the `club` group's subcommands lost argument completion and rendered blank summaries. Rename the leaves and add a drift guard asserting every group's children have a matching leaf, which fails on exactly this mismatch. Claude-Session: https://claude.ai/code/session_01ETHm6wCYdzFuB3kNEBayjF Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
What
Reshapes the
ccasCLI's club targeting (issue #86, epic #40). Drops positional club slugs everywhere in favour of a uniform--cluboption plus a current-club context pointer.--club <slug>(comma-separated onmembership/history) and--all(every managed club, expanded client-side viaGET /api/managed-clubs— server API unchanged). Neither given → falls back tocurrent_club.--all+--clubtogether is rejected (conflicting intent).ccas use-club <slug>: local config write (no server) that setscurrent_club. Top-level — it's a client-local focus pointer, whereas theclubgroup is server-side managed-set ops. Server-validation was rejected on purpose (a fresh / not-yet-fetched club has nothing to validate against): it warns offline against the completion cache but never blocks.ConfigWriter: surgical single-key HOCON edit (zio-config has no writer), written atomically (temp-file + same-dir rename) so a crash/concurrent writer can't leave a half-written config.use-clubboundary (ClubSlug.normalizeonly lowercases).clubs→club(singular, idiomatic per gh/docker/git-remote).--clubvalue flag (+ theuse-clubpositional); drift guard now covers hyphenated commands.Fixes
Fixes #86.
Testing
sbt test— 923 passed, 0 failed (pre-push hook green; +newTestClubResolver,TestUseClub,TestConfigWriter, updated parser/config/completion suites).use-clubwrite + offline warn + trim;--all/--clubconflict and no-club → clean exit 2;clubgroup rename; oldclubs/userejected; regeneratedcompletions/ccas.bashbyte-matches the emitter.Note: the standalone
ZIOAppDefaultapps still hand-roll argv parsing — out of scope here (#70). Future intent to gate job submission to managed clubs only is captured for #66/#60.🤖 Generated with Claude Code
https://claude.ai/code/session_01ETHm6wCYdzFuB3kNEBayjF