|
| 1 | +--- |
| 2 | +name: cli-design-proposal |
| 3 | +description: > |
| 4 | + Prepares and iterates on a gh CLI design proposal (RFC-style) for submission |
| 5 | + to cli/cli. Handles gist-based iteration, scenario-driven formatting, and |
| 6 | + alignment with cli/cli's UX review process. |
| 7 | +--- |
| 8 | + |
| 9 | +# CLI Design Proposal Skill |
| 10 | + |
| 11 | +## When to Use |
| 12 | + |
| 13 | +- User asks to "write a design proposal", "prepare for CLI review", "update the proposal", "push to gist" |
| 14 | +- User is preparing a `gh` extension for UX review by the cli/cli team |
| 15 | +- User wants to iterate on RFC-style scenario documentation |
| 16 | + |
| 17 | +## Context: cli/cli's Process |
| 18 | + |
| 19 | +From [cli/cli docs/working-with-us.md](https://github.com/cli/cli/blob/trunk/docs/working-with-us.md): |
| 20 | + |
| 21 | +1. **Step 0**: Build as a `gh` extension first (we're here — `gh-actions-pin`) |
| 22 | +2. **Step 1**: UX review — open an issue in cli/cli or github/cli describing command usage with mock-ups and `--help` output |
| 23 | +3. **Step 2**: Public preview quality |
| 24 | +4. **Step 3**: Merge decision (complexity, cadence, audience) |
| 25 | + |
| 26 | +The design proposal is **Step 1** — it's a UX review, not a security review or architecture document. |
| 27 | + |
| 28 | +## Proposal Format: RFC-Style (Scenario-Driven) |
| 29 | + |
| 30 | +Follow the pattern from [cli/cli#13120](https://github.com/cli/cli/issues/13120) (Issues 2.0 RFC): |
| 31 | + |
| 32 | +### Structure |
| 33 | + |
| 34 | +``` |
| 35 | +# Title — one-line description |
| 36 | +
|
| 37 | +Covering: [comma-separated list of what this covers] |
| 38 | +
|
| 39 | +### Link to issue |
| 40 | +[issue URL] |
| 41 | +
|
| 42 | +Related: |
| 43 | +- [contextual links — roadmap, community discussions, prior art] |
| 44 | +
|
| 45 | +## Problem |
| 46 | +[numbered list of DX pain points — lead with developer experience, not security] |
| 47 | +
|
| 48 | +## Proposed design |
| 49 | +[brief description + command table + help text in <details> blocks] |
| 50 | +
|
| 51 | +### How the lockfile works |
| 52 | +[format explanation with example YAML] |
| 53 | +
|
| 54 | +## Try it yourself |
| 55 | +[how to reproduce every scenario locally — try-it.sh, demo fixtures] |
| 56 | +
|
| 57 | +## Table of Contents |
| 58 | +### `command-name` |
| 59 | +| Category | Scenario | |
| 60 | +|---|---| |
| 61 | +| Category | [Scenario name](#anchor) | |
| 62 | +
|
| 63 | +### `try-it.sh` scenarios |
| 64 | +| Scenario | Section | Interactive? | |
| 65 | +|---|---|---| |
| 66 | +
|
| 67 | +## `command-name` |
| 68 | +[Per-scenario sections below] |
| 69 | +
|
| 70 | +### Scenario name |
| 71 | +
|
| 72 | +[Brief description of what this demonstrates] |
| 73 | +
|
| 74 | +*Input:* |
| 75 | +\`\`\`bash |
| 76 | +$ command here |
| 77 | +\`\`\` |
| 78 | +
|
| 79 | +*Output:* |
| 80 | +<img src="..." alt="..." width="800"> |
| 81 | +
|
| 82 | +<details> |
| 83 | +<summary>Full terminal session</summary> |
| 84 | +[complete terminal output] |
| 85 | +</details> |
| 86 | +
|
| 87 | +*Expected effects:* |
| 88 | +- What happens as a result |
| 89 | +- Exit codes, file changes, user-visible state changes |
| 90 | +- `try-it.sh scenario-name` reproduces this scenario |
| 91 | +``` |
| 92 | + |
| 93 | +### Key Principles |
| 94 | + |
| 95 | +1. **Scenario-driven, not feature-driven** — each scenario is Input → Output → Expected effects |
| 96 | +2. **Reproducible** — every scenario links to a `try-it.sh` scenario and checked-in demo fixtures |
| 97 | +3. **UX focus** — lead with what the developer sees and experiences, not implementation details |
| 98 | +4. **GIF + text** — animated GIF for quick visual, expandable `<details>` block with full terminal text for copy-paste |
| 99 | +5. **Self-contained** — the proposal + demo dir + try-it.sh should let a reviewer validate everything without building from source |
| 100 | +6. **Help text included** — full `--help` output in collapsible blocks so reviewers see exact CLI surface |
| 101 | + |
| 102 | +### What to Include |
| 103 | + |
| 104 | +- Command table with all commands |
| 105 | +- Full `--help` output for each command (in `<details>`) |
| 106 | +- Lockfile format explanation with real YAML example |
| 107 | +- `try-it.sh` scenario table linking scenarios to proposal sections |
| 108 | +- Each scenario: Input → GIF → Full terminal text → Expected effects |
| 109 | +- Brief contextual links (roadmap blog, community discussion, ADR) |
| 110 | + |
| 111 | +### What to Exclude |
| 112 | + |
| 113 | +- Security analysis (defer to ADR, link once) |
| 114 | +- Implementation notes (it's a UX review) |
| 115 | +- Phased rollout plans (unless directly relevant to UX) |
| 116 | +- Comparison tables with other tools (let the UX speak for itself) |
| 117 | +- Open questions (resolve before submitting) |
| 118 | + |
| 119 | +## Gist-Based Iteration Workflow |
| 120 | + |
| 121 | +The proposal lives in a GitHub Gist for rapid iteration with the user: |
| 122 | + |
| 123 | +### Setup (first time) |
| 124 | + |
| 125 | +```bash |
| 126 | +# Create the gist |
| 127 | +gh gist create --public -f proposal.md /tmp/new-proposal.md |
| 128 | +# Returns: https://gist.github.com/<user>/<id> |
| 129 | +``` |
| 130 | + |
| 131 | +### Iteration loop |
| 132 | + |
| 133 | +1. **Edit locally**: All changes go to `/tmp/new-proposal.md` (working copy) |
| 134 | +2. **Upload to gist**: After each change batch: |
| 135 | + ```bash |
| 136 | + gh api "gists/<GIST_ID>" --method PATCH \ |
| 137 | + --field "files[proposal.md][content]=@/tmp/new-proposal.md" \ |
| 138 | + --jq '.html_url' |
| 139 | + ``` |
| 140 | +3. **User reviews on GitHub**: Gist renders markdown with GIFs, anchors, details blocks |
| 141 | +4. **User gives feedback**: Targeted corrections, section adds/drops, reframing |
| 142 | +5. **Repeat** — changes are surgical (python string replacements or regex), not full rewrites |
| 143 | + |
| 144 | +### Tips |
| 145 | + |
| 146 | +- Use `python3` for complex multi-site edits — safer than sed for large markdown |
| 147 | +- Always verify structure after edits: `grep -n "^## \|^### " /tmp/new-proposal.md` |
| 148 | +- The gist URL is stable — share it once, iterate in place |
| 149 | +- GIF URLs from VHS (vhs.charm.sh) are immutable — no need to re-record unless CLI output changes |
| 150 | + |
| 151 | +## GIF Recording (VHS) |
| 152 | + |
| 153 | +Terminal recordings use [VHS](https://github.com/charmbracelet/vhs) with `.tape` files in the repo: |
| 154 | + |
| 155 | +```bash |
| 156 | +# Record a tape |
| 157 | +vhs demo/tapes/check-autofix.tape |
| 158 | + |
| 159 | +# VHS uploads to vhs.charm.sh and returns a URL |
| 160 | +# Use that URL in the proposal: <img src="https://vhs.charm.sh/vhs-XXXX.gif" ...> |
| 161 | +``` |
| 162 | + |
| 163 | +When CLI output changes (e.g., category renames), tapes need re-recording. |
| 164 | + |
| 165 | +## Demo Fixtures and try-it.sh |
| 166 | + |
| 167 | +The `demo/` directory contains: |
| 168 | +- `demo/workflows-check/` — clean unpinned workflows for onboarding scenarios |
| 169 | +- `demo/workflows-upgrade/` — pre-pinned workflows for upgrade scenarios |
| 170 | +- `demo/workflows-interactive/` — edge cases requiring interactive prompts |
| 171 | +- `demo/workflows-pwned/` — tampered/moved ref scenarios for change detection |
| 172 | +- `demo/try-it.sh` — runs any scenario against fixtures, resets state between runs |
| 173 | + |
| 174 | +Each proposal scenario should map to a `try-it.sh` scenario so reviewers can validate. |
| 175 | + |
| 176 | +## Current Proposal State |
| 177 | + |
| 178 | +- **Gist**: https://gist.github.com/nodeselector/4ca66e60f1a1760f41bbab3fb84d3d7c |
| 179 | +- **Issue**: https://github.com/cli/cli/issues/10553 |
| 180 | +- **Working copy**: `/tmp/new-proposal.md` |
| 181 | +- **Format**: RFC-style, scenario-driven (modeled after cli/cli#13120) |
| 182 | + |
| 183 | +## Finding Category Reference |
| 184 | + |
| 185 | +These are the user-facing finding categories shown in CLI output and JSON: |
| 186 | + |
| 187 | +| Category | Meaning | |
| 188 | +|---|---| |
| 189 | +| `REF_MOVED` | Locked SHA no longer matches upstream (expected for mutable tags like v4) | |
| 190 | +| `MISSING` | Action in workflow has no lock entry | |
| 191 | +| `STALE` | Lock entry references an action no longer in the workflow | |
| 192 | +| `REF_CHANGED` | Workflow ref was edited; lock needs updating | |
| 193 | +| `MISLEADING_SHA` | Ref looks like a SHA but resolves to a different commit | |
| 194 | +| `IMPOSTER_COMMIT` | Locked SHA is not in the ref's history | |
0 commit comments