Skip to content

feat(cli): build the ccas subcommand tree (#46)#71

Merged
Sootopolis merged 1 commit into
mainfrom
wip
Jun 3, 2026
Merged

feat(cli): build the ccas subcommand tree (#46)#71
Sootopolis merged 1 commit into
mainfrom
wip

Conversation

@Sootopolis

Copy link
Copy Markdown
Owner

Closes #46.

Turns the ccas binary from a serve-only stub into a real CLI — a zio-cli command tree dispatched as a thin HTTP client to the local CcasServer.

Commands

serve, membership, history, recruit, stats, jobs, logs, blacklist {add,list,remove}, schedule {list,add,remove}, with a global --server (default http://127.0.0.1:8080). Job commands submit to the existing /api routes and poll GET /api/jobs/{id} to completion. Exit codes: 0 Completed, 1 Failed / submission error / unreachable server, 2 usage error.

Notable decisions

  • zio-cli, not decline — ZIO-native (no cats), plus built-in shell-completion generation (towards Shell completions for ccas #49). Aligns deps: zio 2.1.24→2.1.26, zio-json 0.9.0→0.9.2 for zio-cli 0.8.1.
  • Wire DTOs as the single source of truth — request/response case classes in JobRoutes/ScheduleRoutes/BlacklistRoutes widened private[server]private[ccas] so the CLI imports them directly (compile-time drift safety, no duplicated codecs).
  • Bounded poll loop — 60-min cap, unknown status treated as terminal, friendly "start a server with 'ccas serve' first." on connection refusal.

Deferred (forced — need server routes / other issues)

admin ref/clubdata (no routes / would duplicate matchref), __complete dynamic completions (#49), config.toml resolution (#43), live log tail (#47logs polls status for now).

Verification

  • sbt test green (772/772), incl. all route suites (the DTO visibility widening doesn't break them).
  • New CLI suites: TestCliParser, TestJobPoller, TestCcasApiClient (19 tests).
  • Staged binary: --help (exit 0), bad command (exit 2), unreachable server (exit 1, friendly message); bounded e2e against a local ccas_test server — real round-trips, correct exit codes.

Known caveat

zio-cli is POSIX-style (options before positional args); options after a positional are silently dropped/swallowed. Documented in CliCommand's scaladoc and each --help. Follow-up tracked in #70 (unify app + CLI parsing), and an upstream zio-cli issue is drafted.

🤖 Generated with Claude Code

Turn the `ccas` binary from a serve-only stub into a real CLI: a zio-cli
command tree dispatched as a thin HTTP client to the local CcasServer.

Commands: serve, membership, history, recruit, stats, jobs, logs,
blacklist {add,list,remove}, schedule {list,add,remove}, with a global
--server (default http://127.0.0.1:8080). Each job command submits to the
existing /api routes and polls GET /api/jobs/{id} to completion; exit 0 on
Completed, 1 on Failed/submit-error/unreachable, 2 on usage.

- zio-cli (not decline): ZIO-native, no cats, and built-in shell-completion
  generation (towards #49). Bumps zio 2.1.24->2.1.26 and zio-json 0.9.0->0.9.2
  to align with zio-cli 0.8.1.
- Wire DTOs reused as the single source of truth: widen the request/response
  case classes in JobRoutes/ScheduleRoutes/BlacklistRoutes from private[server]
  to private[ccas] so the CLI imports them directly (compile-time drift safety,
  no duplication).
- Poll loop is bounded (60-min cap) and treats unknown status as terminal;
  unreachable server prints a friendly "start a server with 'ccas serve' first."

Note: zio-cli is POSIX-style (options before positional args); options placed
after a positional are silently dropped/swallowed. Documented in CliCommand's
scaladoc and each --help; follow-up tracked in #70.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Sootopolis Sootopolis merged commit bc85fcf into main Jun 3, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CLI subcommand tree via decline

1 participant