-
Notifications
You must be signed in to change notification settings - Fork 1
Pipeline Design 1
Now I have all the context needed. Let me write the ADR.
Shipwright already has shell completions for bash, zsh, and fish in the completions/ directory, and a standalone installer script at scripts/install-completions.sh. However, the shipwright init command — the primary onboarding path — does not install completions. Users must know to separately run scripts/install-completions.sh or shipwright completions install (which doesn't exist yet in the CLI router). The install.sh summary mentions "Tab completions: shipwright completions install" (line 691) but this command is not routed.
Current state:
-
completions/shipwright.bash,completions/_shipwright(zsh),completions/shipwright.fishexist with full subcommand coverage -
scripts/install-completions.sh(64 lines) handles all three shells: detects$SHELL, copies completion files to standard per-user directories, warns aboutfpathfor zsh -
scripts/cct(CLI router) has nocompletionscase in itsmain()dispatch -
scripts/cct-init.sh(439 lines) installs tmux config, overlay, templates, Claude Code settings, hooks, CLAUDE.md, and deploy setup — but not completions -
install.sh(697 lines) also does not install completions, though its summary references the command
Constraints:
- Bash 3.2 compatibility (no associative arrays, no
readarray, no${var,,}) -
set -euo pipefailin all scripts - Output must use
info(),success(),warn(),error()helpers - Atomic operations — no partial writes
- The
completions/directory is relative to$REPO_DIR, resolved from$SCRIPT_DIR/..
Add shell completion installation as a new section in scripts/cct-init.sh and wire up a completions subcommand in the CLI router (scripts/cct). The implementation delegates to the existing scripts/install-completions.sh to avoid duplicating shell-detection logic.
Data flow:
-
shipwright init→cct-init.sh→ calls$SCRIPT_DIR/install-completions.shafter hooks/CLAUDE.md and before the tmux reload + doctor run -
shipwright completions install→cctrouter →exec $SCRIPT_DIR/install-completions.sh "$@"
Error handling:
- If
completions/directory doesn't exist (e.g., npm global install without completions packaged), skip gracefully withwarn— don't fail the entire init - If
install-completions.shexits non-zero (e.g., unsupported shell), catch with|| trueso init continues - The standalone
completionscommand surfaces errors directly (no|| true)
Non-interactive by default in init: The completions section in cct-init.sh runs without prompting since init is designed to be non-interactive (the "no prompts" design — see header comment line 5). This matches how other sections like templates and hooks work in init.
-
Inline the completion logic into cct-init.sh — Pros: self-contained, no exec dependency / Cons: duplicates the 64-line shell-detection logic in
install-completions.sh, creates two copies to maintain, violates DRY -
Only add
completionsCLI subcommand, don't integrate into init — Pros: minimal change / Cons: new users still won't get completions during onboarding, they must know to run a separate command -
Add to
install.shinstead ofcct-init.sh— Pros: the interactive installer is already the "full setup" / Cons:install.shis the initial install path and users may not re-run it;initis the repeatable onboarding command that users run in each repo
-
Files to modify:
-
scripts/cct-init.sh— Add a "Shell Completions" section (~10 lines) between the CLAUDE.md per-repo section (line 275) and the tmux reload (line 277). Guard with[[ -x "$SCRIPT_DIR/install-completions.sh" ]]. Call the script with|| trueto avoid breaking init if completions fail. -
scripts/cct— Add acompletionscase in themain()router (around line 227, afterinit). Route toexec "$SCRIPT_DIR/install-completions.sh" "$@". Also addcompletionsto theshow_help()output. -
install.sh— Addinstall-completions.shto the list of subcommand scripts installed to$BIN_DIR(line 384).
-
-
Files to create: None — all completion files and the installer script already exist.
-
Dependencies: None new. The completion files (
completions/shipwright.bash,completions/_shipwright,completions/shipwright.fish) are already in the repo. -
Risk areas:
-
$COMPLETIONS_DIRresolution in install-completions.sh (line 8): Usescd "$SCRIPT_DIR/../completions" && pwdwhich will fail withset -eif thecompletions/directory doesn't exist. This is fine for the standalone command (should error visibly) but must be caught with|| truewhen called from init. -
npm global install path: When installed via npm, symlinks resolve through
$SCRIPT_DIRback tonode_modules/. Thecompletions/directory needs to be in the npm package (check.npmignore— it's already listed under included files). -
$BIN_DIRinstall path: When scripts are copied to~/.local/bin/byinstall.sh,install-completions.shresolves$COMPLETIONS_DIRrelative to its own location. After copying to~/.local/bin/, the../completions/path won't resolve. Theinstall.shshould also copy the completions directory, orinstall-completions.shneeds a fallback to$HOME/.shipwright/completions/or the repo path from the manifest.
-
-
shipwright initinstalls completions for the user's shell without prompting -
shipwright initsucceeds even ifcompletions/directory is missing (graceful skip with warning) -
shipwright completions installworks as a standalone command and shows success/error output -
shipwright helplistscompletionsin the command list -
install.shinstallsinstall-completions.shto$BIN_DIRalongside other subcommands - After init, tab-completing
shipwright <TAB>shows subcommands in bash/zsh/fish - All scripts remain Bash 3.2 compatible (no associative arrays, no
readarray) - Existing
npm testsuite passes (no regressions in pipeline/daemon/prep/fleet/fix/memory tests) - The
completions/directory is included in the npm package (verify.npmignoredoesn't exclude it)