Skip to content

refactor: finish the CLI split, dedupe normalizers, rename CMUXCLI#113

Merged
arzafran merged 4 commits into
mainfrom
nr/cli
Jul 9, 2026
Merged

refactor: finish the CLI split, dedupe normalizers, rename CMUXCLI#113
arzafran merged 4 commits into
mainfrom
nr/cli

Conversation

@arzafran

@arzafran arzafran commented Jul 9, 2026

Copy link
Copy Markdown
Member

What this does

The CLI's per-domain split from #78 is now real: descriptors and help text live with their domains, and the last cmux-named type is gone.

Summary

Fixes #93. Fixes #101.

Test Plan

  • build + build-for-testing green locally
  • CI green

arzafran added 4 commits July 9, 2026 14:11
normalizeWindowHandle/normalizeWorkspaceHandle/normalizePaneHandle/
normalizeSurfaceHandle shared one algorithm (trim -> UUID/ref passthrough
-> index lookup via <kind>.list) copy-pasted 4x with only the RPC method
name, list key, filter param key, and current/focused fallback varying.
Collapsed into a single private normalizeHandle(kind:filterParam:fallback:)
with the four public wrappers now thin call sites.

parseOption/parseRepeatedOption were the same terminator-aware scan loop
duplicated twice, differing only in whether the last or all matched values
were kept. Collapsed into a shared scanOption(_:name:) returning all
matches; parseOption now takes .last, parseRepeatedOption returns the
full list.

Behavior-identical: same RPC methods, same list/filter keys, same error
message text, same terminator (--) handling.

Refs #93.
…omain files

programa.swift's subcommandUsage() switch (~1300 lines) documented help
text for every CLI domain in one place, even though the tmux-compat,
SSH, tree, hooks, browser, markdown, themes, and agent-wrapper domains
already have their own CLI+*.swift files housing the implementation.
Split the domain-specific case blocks out into a <domain>SubcommandUsage
helper per file (mirroring the existing tmuxCompatDescriptors pattern),
and turned the central subcommandUsage() into a delegation chain that
falls through to the remaining core (window/workspace/pane/surface/
notify/status/log) cases.

Also moved the ssh/ssh-session-end/remote-daemon-status, tree, and
claude-hook/codex-hook CommandDescriptor entries out of the central
commandDescriptors() array into sshDescriptors()/treeDescriptors()/
hooksDescriptors() in their respective domain files, next to the
implementations they call. The execute:nil pre-connection specials
(themes, claude-teams, omo/omx/omc, codex) stay centralized per the
existing comment ('documented here only so usage() has one source for
help text').

commandDescriptors() itself had to be restructured from one large array
concatenation expression into imperative descriptors += statements: the
Swift type-checker timed out trying to infer the combined expression
once a fourth concatenation was added.

Behavior-identical: same command names, same help text, same dispatch.

Refs #101.
ClaudeHookParsedInput, ClaudeHookSessionRecord, ClaudeHookSessionStoreFile,
ClaudeHookSessionStore, and codexHookWrapperProcessNames were declared at
the top of programa.swift (210 lines) but only ever used from
CLI+Hooks.swift. Moved the whole block verbatim, ahead of the existing
`extension CMUXCLI` in that file. No access-level or behavior changes.

Refs #101.
Mechanical rename across all CLI/*.swift files (the struct declaration in
programa.swift, its instantiation in main(), and every `extension CMUXCLI`
in the CLI+*.swift domain files). No behavior change.

Refs #101.
@arzafran arzafran merged commit dedff42 into main Jul 9, 2026
8 checks passed
@arzafran arzafran deleted the nr/cli branch July 9, 2026 22:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant