feat(cli): cached shell completion (bash/zsh/fish)#78
Merged
Conversation
`ccas completion <bash|zsh|fish>` emits a self-contained, pure-shell completion script. The JVM boots once at install; at <TAB> the script runs entirely in the shell (no JVM, no network), meeting the <50ms bar for all three shells — and retiring the ~1.5s-per-<TAB> zio-cli dynamic script used for zsh/fish. This replaces issue #49's hidden `ccas __complete` design: that would boot the JVM on every <TAB> (~1.5s on a JavaAppPackaging binary), breaking its own <50ms / cache-only acceptance. Instead the scripts are generated from a single `CompletionSpec` (mirrors the CliCommand tree) via `CompletionEmitter`; the committed `completions/ccas.bash` is the emitter's output, and TestCcasCompletion guards file==emitter, per-shell `-n` validity, spec⊇tree coverage, and value-vs-boolean flag classification. Dynamic candidates — club slugs at slug positions, recent job ids for `logs` — come from `${XDG_CACHE_HOME:-~/.cache}/ccas/{clubs.txt, recent-jobs.txt}`, written best-effort by normal commands (staleness-gated `GET /api/clubs` refresh after a successful command; each submitted job id appended on submit). The empty-cache `default_clubs` fallback is deferred to #43 (no CLI config yet). Drive-by: `Main`'s `serve` branch now logs the server crash cause via `foldCauseZIO` instead of the error-swallowing `fold(_ => ExitCode.failure, …)` (the body of the deprecated `ZIO#exitCode`). Closes #49. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 12, 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.
What
ccas completion <bash|zsh|fish>emits a self-contained, pure-shell completion script. The JVM boots once at install; at<TAB>the script runs entirely in the shell (no JVM, no network) → instant, all three shells. Completes subcommands, flags, club slugs (at slug positions) and recent job ids (ccas logs).Why this shape (deviates from the issue's literal design)
#49 specified a hidden
ccas __complete <argv>subcommand the shell calls per<TAB>. On aJavaAppPackagingbinary that boots a JVM (~1.5s) every<TAB>— breaking the issue's own <50ms / cache-only acceptance. So instead:CompletionSpecmirrors theCliCommandtree (single source of truth);CompletionEmittergenerates all three shells from it.completions/ccas.bashis the emitter's bash output (regenerate:ccas completion bash > completions/ccas.bash).<TAB>zio-cli dynamic script previously used for zsh/fish.Dynamic sources
${XDG_CACHE_HOME:-~/.cache}/ccas/{clubs.txt,recent-jobs.txt}, written best-effort by normal commands (never alter exit code): staleness-gatedGET /api/clubsrefresh after a successful command; each submitted job id appended on submit.Tests / guards (
TestCcasCompletion)completions/ccas.bash== bash emitter output<shell> -n(skips absent shells;@@ flakyto absorb fork-pressure flakes without masking real syntax errors)CompletionSpec⊇ tree commands + flags, and value-vs-boolean flag classification matches the treeVerification
completionparser case).blacklist/schedule, empty-cache no-op).ccas-server(isolated schema) →ccas jobsrefreshedclubs.txt→ccas stats … team-alphasubmit wrote the real ULID torecent-jobs.txt(job Completed) → sourced completion served slugs + the ULID with prefix filtering.Scoped out / notes
default_clubsfallback → CLI config file resolution #43 (no CLI config yet).__completeJVM subcommand intentionally not built.CompletionEmitter. bash/zsh gate correctly.Main'sservebranch now logs the crash cause (foldCauseZIO) instead of the error-swallowingfold(body of the deprecatedZIO#exitCode).Closes #49. Part of epic #40.
🤖 Generated with Claude Code