2026-03-12 19:40:22 +02:00
---
name : clack-cli-patterns
2026-07-14 00:45:44 +03:00
description : Use when creating or modifying OpenChamber CLI commands, prompts, terminal output, non-TTY behavior, `--quiet`, or `--json` behavior.
2026-03-12 19:40:22 +02:00
license : MIT
compatibility : opencode
---
## Overview
OpenChamber terminal CLI uses `@clack/prompts` for interactive UX, but command policy and validation must be mode-agnostic.
**Core principle:** policy-first, UX-second. Clack is presentation, not enforcement.
## Scope
Use this skill for terminal CLI work only (for example `packages/web/bin/*` ).
Do not use this skill for web UI or VS Code webview styling work.
2026-08-13 13:57:00 +03:00
## Mode Contract
Run safety and correctness validation before presentation in every mode. Prompts collect missing input; they never enforce policy alone.
| Mode | Prompt | Output | Failure |
|---|---|---|---|
| Interactive TTY | Allowed when input is missing | Framed human output | Concise human error, non-zero exit |
| Fully specified flags | None required | Human output | Same policy and exit semantics |
| Non-TTY/piped | Never | Deterministic script-safe output | Non-zero without hanging |
| `--quiet` | Never | Essential result only | Concise error, non-zero exit |
| `--json` | Never | JSON only, including warnings/errors | JSON failure payload, non-zero exit |
Handle prompt cancellation with `isCancel` + `cancel(...)` and SIGINT with consistent exit semantics.
2026-03-12 19:40:22 +02:00
## Clack Primitive Standard
- **Flow framing:** `intro` , `outro` , `cancel`
- **Status lines:** `log.info` , `log.success` , `log.warn` , `log.error` , `log.step`
- **Guidance blocks:**
- default: `note`
- high-severity warnings only: `box`
- **Prompts:** `select` , `confirm` , `text` , `password`
- **Long-running feedback:**
- unknown duration: `spinner`
- known duration: `progress`
- multi-stage: `tasks`
## Preferred Pattern
Centralize Clack imports and formatting helpers in one adapter module (for example `cli-output.js` ) so command logic stays focused on behavior and policy.
### Thin framework (recommended)
Use a small shared helper surface rather than command-specific formatting logic.
- `isJsonMode(options)`
- `isQuietMode(options)`
- `shouldRenderHumanOutput(options)`
- `canPrompt(options)`
- `createSpinner(options)`
- `createProgress(options, config)`
- `printJson(payload)`
Keep this layer minimal. Do not hide core validation or command semantics inside output helpers.
## Output Contracts by Mode
### `--quiet` contract
`--quiet` should still return essential result data.
- Read/list commands: emit concise machine-friendly lines (not framed Clack blocks).
- Action commands: emit one minimal success line and concise errors.
- Do not suppress required outcomes entirely.
Quiet output should still be complete enough for scripts and quick human scanning.
- Status-like commands should list all active items, not only `running` /`ok` .
- Prefer compact stable key tokens in quiet lines (for example `port 3000 pass:yes` ).
### `--json` contract (strict)
- Output must be JSON only (no extra text before/after payload).
- Warnings/info should be represented in JSON fields (for example `status` , `messages` ).
- Preserve non-zero exit codes for failures.
## Human UX Consistency
### Framing completeness
- If human flow uses `intro` , close with `outro` (or `outro('')` when you want structure without text).
- Avoid orphan frame/spinner artifacts (prefer `spinner.clear()` when a trailing spinner line is not wanted).
- If a structured summary section immediately follows a spinner, prefer `spinner.clear()` to avoid duplicate success lines.
### Progress feedback for visible operations
- For operations users wait on (start/stop/restart/tunnel lifecycle), show in-progress spinner in interactive mode.
- Resolve each spinner explicitly to done/error so users can see completion state at the same visual location.
- Keep quiet/json modes non-animated.
### Prompt flow design
- Ask required inputs in dependency order (for example hostname before token when token depends on chosen host/mode context).
- When offering save-vs-run flows, ask intent before collecting optional metadata (for example profile name only if user chooses save).
- Prefill editable values with `initialValue` (not only `placeholder` ) so users can accept or edit quickly.
- Reuse latest relevant values when safe (for example last managed-local config path, last managed-remote hostname).
### Readability on narrow terminals
- Prefer short lines.
- Split long guidance into multiple detail lines.
- Use warning/info codes (`[CODE]` ) when the message has follow-up docs or repeat use.
### Guidance tone
- Use `Optional Tips` for non-required next actions.
- Avoid wording that implies mandatory follow-up unless it is truly required.
### Guidance rendering style (preferred)
- Prefer structured status lines for reusable hints:
- `logStatus('info', '[CODE]', '<actionable command or short guidance>')`
- Use short, stable codes (for example `[START_PROFILE]` , `[PORT_MISMATCH]` ) so users can quickly scan and recognize repeated guidance.
- Prefer this style over boxed notes for routine follow-up actions.
- Reserve `note` /boxed callouts for rare, high-context guidance where a long paragraph is truly necessary.
2026-08-13 13:57:00 +03:00
## Completion Criteria
2026-03-12 19:40:22 +02:00
2026-08-13 13:57:00 +03:00
Every command/subcommand must have a tested answer for:
2026-03-12 19:40:22 +02:00
1. default interactive TTY output
2. `--quiet` output (minimal but informative)
3. `--json` output (JSON-only)
4. non-TTY behavior (e.g. piped)
5. error path in both human and json modes
2026-07-14 00:45:44 +03:00
## Reusable Snippets
Load `references/snippets.md` when implementing prompt guards, non-interactive fallback, spinner lifecycle, or JSON/human output branching.
2026-03-12 19:40:22 +02:00
2026-08-13 13:57:00 +03:00
Implementation is complete when validators run before every mode branch, interactive Clack UX is only an enhancement, and all five cases above produce deterministic output and exit behavior.
2026-03-12 19:40:22 +02:00
## References
2026-07-14 00:45:44 +03:00
- This skill is the canonical CLI parity and safety policy.
2026-03-12 19:40:22 +02:00
- Terminal CLI precedent: `packages/web/bin/cli.js`
- Output adapter precedent: `packages/web/bin/cli-output.js`