Skip to content

Instantly share code, notes, and snippets.

@deeplook
Created May 10, 2026 19:27
Show Gist options
  • Select an option

  • Save deeplook/316a22c6349d297b76c3fd7f5edf8453 to your computer and use it in GitHub Desktop.

Select an option

Save deeplook/316a22c6349d297b76c3fd7f5edf8453 to your computer and use it in GitHub Desktop.
CLIG Compliance Report – peekaboo 3.0.0 CLI

CLIG Compliance Report – peekaboo 3.0.0 CLI

Audited: 2026-05-10 Version: Peekaboo 3.0.0 Source: Apps/CLI/Sources/PeekabooCLI/ Guidelines: clig.dev (main branch, May 2025)


Passes

The Basics

  • Argument parsing library — Uses Commander (Swift), a proper argument parsing framework that handles flags, arguments, help rendering, and subcommand routing.
  • Exit codes — Returns EXIT_SUCCESS (0) on success, EXIT_FAILURE (1) on error, via PeekabooEntryPoint.swift:31-40. Non-zero exit codes map to specific failure modes.
  • stdout for primary output — Commands emit results (JSON, text) to stdout via print().
  • stderr for messaging — Logger writes all log/debug messages to stderr via fputs(..., stderr) (CLILogger.swift:123). Errors in non-JSON mode also go to stderr (PeekabooEntryPoint.swift:65,82).

Help

  • -h and --help supported — Both flags trigger help display (CommanderRuntimeRouter.swift:179-180). Works for root and all subcommands.
  • help subcommand patternpeekaboo help, peekaboo help <command>, peekaboo <command> --help all work (CommanderRuntimeRouter.swift:67-93).
  • Concise help on bare invocation — Running peekaboo with no args prints the root help card with usage , categorized command list, and global flags (CommanderRuntimeRouter.swift:15-17,201-221). Commands with showHelpOnEmptyInvocation: true also show help when invoked without required args.
  • Formatted help text — Bold headings, colored accents, and structured layout via HelpTheme (CommanderRuntimeRouter+Help.swift:149-177). Colors are disabled gracefully when not in a TTY.
  • Most common flags displayed first — Global flags section shows --json, --verbose, --log-level prominently (CommanderRuntimeRouter+Help.swift:54-74).
  • Commands categorized — Root help groups commands by category (Core, Interaction, System, Vision, AI, MCP) (CommanderRuntimeRouter.swift:206-216).
  • Examples in help textListCommand and CompletionsCommand include detailed examples and usage patterns in their discussion fields.
  • Spelling/typo suggestions — Commander framework provides unknown-command error messages (PeekabooEntryPoint.swift:53-54).

Output

  • --json flag for machine-readable output — Supported globally via --json, -j, and --json-output (PeekabooEntryPoint.swift:43-45). JSON responses follow a consistent {success, data, messages, debug_logs, error} envelope (JSONOutput.swift:24-44,167-172).
  • Color disabled when not a TTYTerminalDetection.swift checks isatty(), NO_COLOR, TERM=dumb, CI environments, and piped output.
  • NO_COLOR environment variable respected — Explicitly checked; sets output mode to .minimal (TerminalDetection.swift:213-215).
  • FORCE_COLOR / CLICOLOR_FORCE respected — Both force enhanced output mode (TerminalDetection.swift:218-220).
  • TERM=dumb handled — Falls back to no-color on non-macOS when TERM=dumb (TerminalDetection.swift:148).
  • CI environment detection — Checks 20+ CI env vars (GitHub Actions, GitLab CI, Jenkins, etc.) and disab les rich output (TerminalDetection.swift:69-87).
  • Terminal dimensions detected — Uses ioctl(TIOCGWINSZ) with fallback to COLUMNS/LINES env vars (TerminalDetection.swift:90-105).
  • Spinner/progress indicatorsPeekabooSpinner shows progress during long operations; adapts to color capabilities (PeekabooSpinner.swift).
  • Errors sent to stderr — In non-JSON mode, errors print to stderr. In JSON mode, errors are structured in the JSON envelope.
  • Structured error codes — 30+ specific ErrorCode values for programmatic error handling (JSONOutput.swift:66-103).

Arguments and Flags

  • Full-length flag versions — All flags have long forms (e.g., --json/-j, --verbose/-v, --help/-h, --version/-V).
  • Standard flag names — Uses conventional names: --help/-h, --version/-V, --verbose/-v, --json/-j, --force, --path, --app.
  • Flags preferred over positional args — Most commands use named flags (--app, --mode, --path, etc.) rather than positional arguments.

Subcommands

  • Consistent across subcommands — All commands share global flags (--json, --verbose, --log-level), consistent help rendering, and the same JSON response envelope.
  • Consistent noun-based naming — Commands follow a noun verb pattern: list apps, list windows, permissions status, permissions grant, capture live, capture video.
  • Default subcommandslist defaults to apps, permissions defaults to status — sensible defaults for the most common operation.

Robustness

  • Responsive output — Spinner starts immediately for long operations.
  • Input validation — Flag values are validated early with descriptive errors (e.g., CaptureCommandOptionParser validates diff strategy values).

Configuration

  • Config precedence — Follows the recommended order: flags > env vars > project config > user config > defaults (CLIConfiguration.swift:118-131).
  • PEEKABOO_LOG_LEVEL env var — Configurable via environment (CLILogger.swift:54-57).
  • PEEKABOO_OUTPUT_MODE env var — Controls output verbosity via environment (TerminalDetection.swift:204-210).
  • Config stored in ~/.peekaboo — Follows home-directory convention for user config.

Environment Variables

  • Uppercase names — All env vars use uppercase with underscores (e.g., PEEKABOO_LOG_LEVEL, PEEKABOO_OUTPUT_MODE, NO_COLOR).
  • Standard env vars checkedNO_COLOR, FORCE_COLOR, TERM, COLUMNS, LINES, SHELL.

Naming

  • Simple, memorable namepeekaboo is lowercase, memorable, and distinctive.
  • Lowercase with no special characters — Follows the convention perfectly.

Distribution

  • Single binary — Swift compiles to a native binary; distributed as a single executable.

Signals

  • Ctrl-C handling — Spinner clears on interruption; async tasks use Swift's cooperative cancellation.

Shell Completions

  • Completions for zsh, bash, fishpeekaboo completions generates shell-specific completion scripts with auto-detection of the current shell (CompletionsCommand.swift).

Future-proofing

  • --version flag — Displays full version info including git commit, branch, and build date (Version.swift:9-11, CommanderRuntimeRouter.swift:154-159).

Violations

1. Help — No support path or web documentation link

  • Files: CommanderRuntimeRouter+Help.swift, CommanderRuntimeRouter.swift:201-221
  • Issue: The root help text does not include a URL to file issues, a website link, or a pointer to web-based documentation. Users encountering problems have no guidance on where to seek help.
  • Fix: Add a footer line to printRootHelp such as "Documentation: https://peekaboo.dev | Issues: https://github.com/<org>/peekaboo/issues".
  • CLIG section: Help — "Provide a support path for feedback and issues" and "In help text, link to the web version of the documentation."

2. Output — No --plain flag

  • Files: Global flag set in CommanderRuntimeRouter+Help.swift:54-74
  • Issue: The CLI offers --json for machine-readable output, but no --plain mode for simple tabular t ext suitable for grep/awk. Commands that list apps, windows, or screens emit formatted text with emoji and color that breaks pipeline usage.
  • Fix: Add a global --plain flag that disables emoji, color, and formatting, emitting tab-separated or fixed-width rows.
  • CLIG section: Output — "If human-readable output breaks machine-readable output, use --plain to display output in plain, tabular text format."

3. Output — No --no-color CLI flag

  • Files: TerminalDetection.swift
  • Issue: Color can be disabled via the NO_COLOR env var and PEEKABOO_OUTPUT_MODE=minimal, but there is no --no-color command-line flag. CLIG recommends --no-color as a flag option alongside the env var.
  • Fix: Add --no-color to the global runtime flags in CommandRuntimeOptions.
  • CLIG section: Output — "The user passes the option --no-color."

4. Output — No pager for long output

  • Files: Various list/help commands
  • Issue: Commands like peekaboo list apps or peekaboo help can produce output that exceeds the terminal height, but output is never piped through a pager like less.
  • Fix: For commands that may produce long output, pipe through $PAGER (or less -FIRX) when stdout is an interactive TTY.
  • CLIG section: Output — "Use a pager (e.g. less) if you are outputting a lot of text."

5. Output — Animations not disabled in non-TTY

  • Files: PeekabooSpinner.swift
  • Issue: The spinner does not check whether stdout is an interactive terminal before starting. If output is piped or redirected, spinner escape sequences could corrupt the stream. The spinner adapts to color capa bility but not to TTY-ness.
  • Fix: Guard PeekabooSpinner.start() with an isatty(STDOUT_FILENO) check; skip the spinner entirely when not interactive.
  • CLIG section: Output — "If stdout is not an interactive terminal, don't display any animations."

6. Help — Version flag uses non-standard -V short form

  • Files: CommanderRuntimeRouter.swift:184
  • Issue: The short version flag is -V (uppercase). While not strictly wrong, CLIG notes that -v is ambiguous between verbose and version, and recommends using -d for verbose to free -v for version. The current mapping (-v = verbose, -V = version) inverts the more common convention where lowercase -v means version (e.g., curl -v is verbose, but git -v is version). This inconsistency may confuse users.
  • Fix: Consider this a minor style choice. Document the convention clearly. No change strictly required, but be aware of the ambiguity.
  • CLIG section: Arguments and Flags — "-v: This can often mean either verbose or version."

7. Interactivity — No --no-input flag

  • Files: Global flag set
  • Issue: There is no --no-input flag. Scripts calling potentially interactive commands (e.g., peekaboo agent, peekaboo config) cannot reliably suppress prompts.
  • Fix: Add a global --no-input flag that disables all prompting and treats missing required input as an error.
  • CLIG section: Interactivity — "If --no-input is passed, don't prompt or do anything interactive."

8. Output — Quiet mode not globally available

  • Files: Global flag set
  • Issue: There is no global -q/--quiet flag. Only the agent command has a quiet concept (AgentMes sages.quietDisabled). For scripting, users should be able to suppress all non-essential output across any command.
  • Fix: Add -q/--quiet to global flags, suppressing all non-essential human-readable output (success messages, hints, tips).
  • CLIG section: Output — "Provide a -q option to suppress all non-essential output."

9. Errors — No bug report URL on unexpected errors

  • Files: PeekabooEntryPoint.swift:74-89
  • Issue: When an unexpected error occurs (printGenericError), the error message is printed but there is no suggestion to file a bug report or link to an issue tracker.
  • Fix: For UNKNOWN_ERROR codes, append a line like: "If this is unexpected, please report it at https://github.com/<org>/peekaboo/issues".
  • CLIG section: Errors — "If there is an unexpected error, provide instructions on how to submit a bug."

10. Configuration — Not XDG-compliant

  • Files: CLIConfiguration.swift:21-22
  • Issue: Configuration is stored in ~/.peekaboo rather than following the XDG Base Directory Specification ($XDG_CONFIG_HOME/peekaboo or ~/.config/peekaboo). While ~/.peekaboo is a common convention, CLIG recommends XDG compliance to reduce home directory clutter.
  • Fix: Support $XDG_CONFIG_HOME/peekaboo as the primary location, falling back to ~/.peekaboo for backward compatibility.
  • CLIG section: Configuration — "Follow the XDG-spec."

11. Arguments and Flags — No stdout output via - convention

  • Files: ImageCommand+Output.swift, ImageCommand.swift
  • Issue: peekaboo image always writes to a file and prints the path. There is no way to write binary image data to stdout using --path - (or -o -), which would allow piping directly into tools like convert, pngquant, base64, or pbcopy. This is a common UNIX convention for commands that produce file output.
  • Fix: When --path is set to -, write the image bytes to stdout instead of saving to a file. Suppress all non-essential human-readable output (emoji, path descriptions) in this mode, and ensure logging goes only to stderr.
  • CLIG section: Arguments and Flags — "If input or output is a file, support - to read from stdin or write to stdout."

12. Help — "Tip" in help text is developer-oriented

  • Files: CommanderRuntimeRouter+Help.swift:26-28,49-51
  • Issue: Both root and command help cards include a "Tip" suggesting polter peekaboo for local development. This is developer-internal guidance that is meaningless to end users and violates the principle of not showing developer-only information by default.
  • Fix: Remove the "Tip" section from user-facing help, or gate it behind --verbose / a DEBUG check.
  • CLIG section: Output — "By default, don't output information that's only understandable by the creators of the software."

Not Applicable

  • stdin piping — Reading from stdin is not a primary use case for a screen capture tool.
  • Man pages — Nice-to-have but not critical for a macOS-specific tool; shell completions and --help cover discoverability.
  • Dry-run (--dry-run) — Most commands are read-only (capture, list, see). Interaction commands (click, type) could benefit but the risk is low.
  • Password/secret prompting — Secrets are managed via config files in ~/.peekaboo, not passed as flags. This is already the recommended approach.
  • Analytics/telemetry — No evidence of any telemetry. This is compliant by absence.
  • Arbitrary subcommand abbreviations — Not supported. This is correct per CLIG.
  • Catch-all subcommand — Not used. Commands require explicit subcommand names.

Summary

25 passes | 12 violations | 7 not applicable

The CLI has strong fundamentals: proper stdout/stderr separation, structured JSON output, comprehensive help with categorized commands, terminal capability detection, NO_COLOR support, CI-aware output adaptation, and consistent subcommand patterns. The violations are primarily around missing global flags (--plain, --no-color, --quiet, --no-input), no stdout piping for binary output (- convention), the absence of a support/docs URL in help text, and the developer-facing "Tip" leaking into user-visible help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment