Skip to content

Post-sync-overhaul cohesion cleanup + Docker-mode README clarifications#38

Merged
mswdev merged 4 commits intodevelopfrom
feature/cohesion-and-doc-cleanup
May 4, 2026
Merged

Post-sync-overhaul cohesion cleanup + Docker-mode README clarifications#38
mswdev merged 4 commits intodevelopfrom
feature/cohesion-and-doc-cleanup

Conversation

@mswdev
Copy link
Copy Markdown
Owner

@mswdev mswdev commented May 4, 2026

Summary

Closes the punch list from the post-sync-overhaul cohesion audit (research kicked off after PR #37 merged). Four logical commits, each independently revertable:

  • fix(account) — stderr + keychain picker. Account validation/usage messages printed to stdout, breaking 2>/dev/null pipelines. Also replaced the hand-rolled nl + read -r keychain picker in --adopt with _core_prompt_choose so gum/no-gum routing matches every other interactive picker.

  • refactor — prompt helpers + constant prefixes. Three sites (sync interactive fallbacks, setup pick-keys fallback) bypassed _core_prompt_*; standardized them. Eight _SYNC_* module globals + two unprefixed readonlys (MIN_HOOK_FILES, ALIASES_FILE_PERMS) renamed to the _CKIPPER_* convention from shell-conventions.md.

  • feat — doctor + completion + wizard. ckipper doctor now checks gum on PATH, completion-file freshness, and aliases.zsh parses cleanly via zsh -n. Tab completion now offers schema keys after ck config get/set/unset (bumped completion version 7→8). Setup-wizard final message now lists all three Claude-launching paths (ck run, claude-<account>, bare <account>) and the ck interactive menu, plus a ckipper doctor hint.

  • docs(readme) — slogan + table + Docker-mode clarifications. Slogan replaced. Core-commands table now lists the previously-omitted sync and redeploy-hooks subcommands. Renamed Known limitationsKnown limitations (Docker mode only) and Multi-account caveatsMulti-account caveats (host and Docker) so each issue's scope is unambiguous. Added two Docker-mode limitations the audit identified: Claude in Chrome MCP (browser extension can't bridge the container boundary, anthropics/claude-code#25506) and custom system-sound hooks (afplay/say/osascript don't exist in the Linux container).

Test plan

  • make lint-shell lint-zsh lint-fmt lint-merge-guards — clean
  • bats --recursive . — 467 / 467 passing
  • python3 -m pytest — 6 / 6 passing
  • Manual smoke: ckipper account remove nonexistent 2>/dev/null — should be silent (was leaking errors to stdout pre-fix)
  • Manual smoke: ck config get <TAB> — should now offer the 10 schema keys
  • Manual smoke: ckipper doctor — should now report on gum, completion file, and aliases.zsh parse
  • Manual smoke: re-run ckipper setup, complete flow, verify final message lists all three Claude-launching paths

Scope notes

  • The sync interactive fallbacks (no-gum branch) used read -r "var?label" which writes the prompt to stderr correctly. The behavioral change after switching to _core_prompt_input is that the prompt now displays the bracketed empty default (e.g. Enter comma-separated targets []:). Centralizing on the helper trades a minor visual change for consistency and future-proofing.
  • One audit finding deliberately deferred: the find -maxdepth 3 scan inside the completion function (slow on large ~/Developer trees). Caching with mtime checks adds complexity for marginal benefit on typical setups; skipping per KISS.

mswdev added 4 commits May 3, 2026 21:30
…cker

Two fixes in lib/account/account-management.zsh:

1. Account validation/usage messages ("Account 'foo' is already
   registered.", "Usage: ckipper account remove <name>", etc.) printed
   to stdout. Other modules (lib/config, lib/worktree, doctor.zsh)
   already use stderr, so `ckipper account remove foo 2>/dev/null`
   silenced success but leaked the failure path. Routed every error
   path through `>&2`.

2. The Keychain entry picker used by `ckipper account add --adopt`
   hand-rolled `nl + read -r` instead of using _core_prompt_choose.
   Switched to _core_prompt_choose with an explicit "(skip)" sentinel
   so gum/no-gum routing matches every other interactive picker.
Two consistency cleanups left over from the sync overhaul:

1. Three sites bypassed _core_prompt_*: lib/account/sync/interactive.zsh
   used raw `read -r "var?label"` for two free-form prompts, and
   lib/setup/prompts.zsh:98 used raw `read -r` for a y/N. All three now
   route through _core_prompt_input / _core_prompt_confirm. Same
   behavior in no-gum mode; future helper-layer changes propagate
   automatically.

2. Module-level globals in lib/account/sync/{dispatcher,engine,preview}
   used the bare _SYNC_* prefix. Every other module uses _CKIPPER_*
   per .claude/rules/shell-conventions.md. Renamed the eight
   dispatcher state vars (_SYNC_FROM, _SYNC_TARGETS, _SYNC_INCLUDE,
   _SYNC_EXCLUDE, _SYNC_DRY_RUN, _SYNC_YES, _SYNC_FORCE, _SYNC_CTX)
   plus the unprefixed ALIASES_FILE_PERMS readonly in aliases.zsh.
   Tests updated. Verified zero leftover _SYNC_* references via grep.
Three small additions that close gaps the README implies are covered:

- ckipper doctor now checks (a) gum on PATH (FAIL — required for the
  setup/sync wizards), (b) ~/.zsh/completions/_ckipper exists and
  matches CKIPPER_COMPLETION_VERSION (WARN — stale completions only
  produce outdated tab suggestions), and (c) aliases.zsh parses with
  `zsh -n` (FAIL — a broken aliases file disables every per-account
  launcher in the user's shell). Also renamed MIN_HOOK_FILES to
  _CKIPPER_DOCTOR_MIN_HOOK_FILES while in doctor.zsh.

- Tab completion now offers schema keys after `ck config get/set/unset`,
  sourced live from _CKIPPER_SCHEMA_TYPE. Bumped
  CKIPPER_COMPLETION_VERSION 7 → 8 so existing installs regenerate the
  cached completion file on next shell start.

- The setup-wizard final message now lists all three Claude-launching
  paths (`ckipper run`, `claude-<account>`, bare `<account>`) and the
  `ck` interactive menu, plus a hint to run `ckipper doctor`.
  Previously it only mentioned `ckipper run`.
- Renamed slogan from "Multi-account Claude Code manager with Docker
  isolation, per-account preferences, and worktree-aware launchers." to
  "A lightweight Claude Code account, worktree, and Docker manager."
  Shorter, scans cleaner.

- Core commands table now lists `sync` and `redeploy-hooks` under
  account-namespace subcommands. Both are fully implemented and
  documented later in the README, but the at-a-glance command index
  was missing them.

- Renamed "Known limitations" → "Known limitations (Docker mode only)"
  and "Multi-account caveats" → "Multi-account caveats (host and
  Docker)" with intro lines that explicitly tag scope. The previous
  headings left it ambiguous whether each limitation applied only to
  the dockerized launch path or to ckipper in general.

- Added two Docker-mode limitations confirmed via research:
  - Claude in Chrome MCP — the browser extension can't bridge the
    host/container boundary (anthropics/claude-code#25506).
  - Custom system-sound hooks — afplay/say/osascript don't exist in
    the Linux container; built-in notify-bell.sh sidesteps via the
    terminal bell (\a) character.
@mswdev mswdev force-pushed the feature/cohesion-and-doc-cleanup branch from 0a8e2b6 to 0199490 Compare May 4, 2026 03:43
@mswdev mswdev marked this pull request as ready for review May 4, 2026 03:46
@mswdev mswdev merged commit dc6d8e6 into develop May 4, 2026
1 check passed
@mswdev mswdev deleted the feature/cohesion-and-doc-cleanup branch May 4, 2026 03:46
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.

1 participant