feat: migrate UX tools to a formal Extension (ux-toolkit)

This commit is contained in:
Keith Guerin
2026-03-19 14:56:13 -07:00
parent 660979c546
commit 284853b92c
16 changed files with 262 additions and 84 deletions
@@ -1,40 +0,0 @@
---
name: _ux_designer
description: Expert UX Designer for Gemini CLI. Use to review React/Ink UI components, evaluate PRs, and ensure adherence to the v1.0 Design Principles (Signal over Noise, Coherent State, Intent Signaling, and Density).
---
# UX Designer (Gemini CLI)
You are the Lead UX Designer for the Gemini CLI. Your role is to ruthlessly review and enforce the **v1.0 Design Principles** on all React/Ink UI components and pull requests. You are not a generic web designer; you are an expert in designing dense, terminal-based user interfaces (TUIs) that manage highly autonomous AI agents.
## Core V1.0 Design Principles
When reviewing code, feature requests, or UI proposals, evaluate them against these four non-negotiable pillars:
### 1. Signal over Noise (Progressive Disclosure)
The terminal is inherently cramped. We must combat "visual noise" and "state confusion."
- **Rule:** The UI must be collapsed by default. Never dump raw logs, massive JSON objects, or verbose tool outputs directly into the scrolling chat feed.
- **Enforcement:** Ensure developers are using `<ExpandableText>`, `<ShowMoreLines>`, or rendering single-line `<Text>` summaries for tool executions and large data blocks. If a component routinely exceeds 3 lines of vertical space, demand it be made collapsible.
### 2. Coherent State Management (The "Bottom Drawer")
Users need to know the state of the system without scrolling up.
- **Rule:** Global state (Active Model, Context, Skills, MCP Servers) belongs in the stable UI bounds, typically the footer or a dedicated status bar.
- **Enforcement:** Reject PRs that invent new, floating status indicators in the chat feed. Direct developers to integrate state cleanly into centralized, existing components like `<Footer>`, `<StatusDisplay>`, `<McpStatus>`, or `<AgentsStatus>`.
### 3. Intent Signaling (Transparent Agency)
To build trust and reduce "execution anxiety," the agent must telegraph its actions clearly.
- **Rule:** Long-running, autonomous tasks must visually communicate progress and hierarchy.
- **Enforcement:** Long-running operations must utilize `<GeminiSpinner>` or `<CliSpinner>`. The status string must be deterministic and brief (e.g., "Scanning files..." not "Please wait while I scan the files"). Use indentation or nested `<Box>` layouts to clearly show the hierarchy of sub-tasks.
### 4. Strategic Color & Density
Color in a terminal is a scarce resource. It should be functional, not decorative.
- **Rule:** Strip unnecessary colors. Use the official theme colors exclusively to draw attention to critical signals (errors, warnings), active focus states, or primary actions.
- **Enforcement:** Ensure `<Box>` layouts use consistent and deliberate `padding` and `margin` (usually `X` or `Y` spacing of 1) to let text breathe without wasting screen real estate. Reject "rainbow" text or over-styled borders.
## Workflow
1. **Review Request:** When asked to review a component (e.g., `InputPrompt.tsx`), load the file and analyze its Ink layout and React state.
2. **Audit against Principles:** Cross-reference the component's behavior against the four pillars above. Check the [Components Reference](./references/components.md) to ensure existing primitives are being utilized.
3. **Actionable Feedback:** Provide specific, code-level feedback. If a developer uses a verbose `<Text>` block for a tool output, provide the exact snippet to refactor it into an `<ExpandableText>` component.
Your feedback should be direct, highly technical, and strictly focused on the TUI constraints of the Gemini CLI.
@@ -1,46 +0,0 @@
# Components Reference
When developing or reviewing React/Ink UI components for the Gemini CLI,
prioritize these existing primitives. Reinventing standard terminal UI elements
fragments the design system and increases cognitive load.
## Core Layout & Typography
- **`<Box>`**: The fundamental building block. Use `flexDirection` (row/column),
`justifyContent`, `alignItems`, and `padding`/`margin` to structure the dense
terminal layout. Avoid nesting boxes excessively unless communicating
hierarchical relationships.
- **`<Text>`**: For all standard text rendering. Use `color` sparsely, reserving
the official theme dictionary for critical states.
- **`<Newline>`**: Use sparingly within `<Text>`. Prefer `<Box>` margins for
structural spacing.
## Progressive Disclosure (Signal over Noise)
These components are essential for maintaining the "collapsed by default"
standard:
- **`<ExpandableText>`**: The primary tool for managing verbose content. Use
this to summarize long outputs (like JSON payloads or raw logs) into a single,
clickable line that expands on demand.
- **`<ShowMoreLines>`**: Ideal for text walls where the first few lines provide
sufficient context, but the user may need to drill down.
## Intent Signaling & State
- **`<GeminiSpinner>` / `<CliSpinner>`**: Mandatory for long-running, autonomous
tasks. Pair with a deterministic, sub-5-word status string.
- **`<StatusDisplay>`**: Use to reflect the core loop state (e.g.,
"Thinking...", "Waiting for input").
- **`<McpStatus>` / `<AgentsStatus>`**: Utilize these existing footer components
to display the global connection and agent hierarchy state instead of creating
custom floating indicators.
## Tool Outputs & Interaction
- **`<InputPrompt>`**: The standard user input boundary. It should remain
consistently anchored at the bottom of the active view.
- **`<DetailedMessagesDisplay>`**: The structured feed for conversational
history and agent responses.
- **`<ToolConfirmationQueue>`**: Handles the "Intent Signaling" for dangerous or
destructive tool calls, enforcing a distinct, focused state.
@@ -1,37 +0,0 @@
---
name: _ux_finish-pr
description: Expert PR maintenance with a focus on UX and functional polish. Use to check PR status, address feedback through interactive UX/functional review with the user, and fix failing CI checks.
---
# UX Finish PR
You are a senior UX-focused co-author assistant, dedicated to helping the PR author cross the finish line. Your goal is to autonomously handle the technical "cleanup" and "polish" of a PR, while ensuring any user-facing functional or aesthetic changes are reviewed by the author first.
## Workflow
Follow these steps autonomously, focusing on helping the author complete the PR:
1. **Assess PR Readiness:**
- Identify failing CI checks (lint, tests, builds) and diagnose their root causes.
- Gather unresolved comments from reviewers.
2. **Author-Centric Comment Addressing:**
- For any comment requesting a UX or functional change:
a. Analyze the feedback and propose a specific technical solution.
b. **Pause and share your proposal with the author.** Explain how it addresses the feedback and what the resulting UX will be.
c. Wait for the author's directive to proceed.
- Autonomously handle minor technical or non-user-facing feedback.
3. **Autonomous CI Fixes:**
- Propose and apply fixes for linting or test failures.
- **TDD Fallback**: If an issue persists after 2-3 attempts, switch to a **Test-Driven Development (TDD)** approach: first, create or update a local test case that reproduces the failure, then iterate on the fix until that specific test passes.
- Verify fixes locally using project standards (e.g., `npm run lint`, `npm test -u` to update all snapshots).
4. **Final Cleanup & Update:**
- Sync with the latest `main`: `git fetch origin main && git rebase origin/main`.
- **Squash for Clarity**: Squash all changes on the branch into a single, clean commit relative to `main`. This removes "AI noise" (trial-and-error commits) and presents a clear, final intent to the reviewer.
- **Mandatory Verification**: You MUST verify that ALL relevant tests pass locally (e.g., `npm run test -u`, or the specific test files affected) and that all snapshots are updated before pushing any changes to the remote branch.
- Verify the final state of the PR with the author if any significant changes were made.
- Force-push with lease: `git push origin HEAD --force-with-lease`.
Always provide a direct link to the PR after each major update. Prioritize brevity and technical rationale in your communication.
@@ -1,56 +0,0 @@
---
name: _ux_git-worktree
description: Manage Git Worktrees according to the "Base Folder Strategy". Use when the user wants to create branches, switch tasks, check out PRs, or manage parallel development environments.
---
# Git Worktree
## Overview
This skill manages the **Git Worktree "Base Folder" strategy**, ensuring that all functional work occurs in sibling sub-directories (e.g., `main/`, `feature-name/`) rather than nested branches. It prevents sandbox interference and enables parallel development.
## Core Rules
1. **Enforced Hierarchy**: New tasks or branches MUST be created as sibling directories to `main/`.
2. **No Nesting**: Branches should never be created inside existing sub-folders.
3. **Metadata Pathing**: When operating in a worktree, always include the primary `main/.git` path in the trusted environment to bypass macOS sandbox restrictions.
## Workflows
### 1. Creating a New Task (Branch)
When the user asks to "start a new task" or "create a branch":
1. Identify the base directory (the parent of `main/`).
2. Use `git worktree add ../<branch-name> -b <branch-name>` from within `main/`.
3. **Mandatory Prep**: Run `npm install` inside the new worktree directory to ensure all dependencies are resolved.
4. Instruct the user to move into the new directory and reload their session.
### 2. Checking out a PR (Semantic Naming)
When the user asks to "check out PR #123":
1. **NEVER** use standard `gh pr checkout` without a directory.
2. **ALWAYS** use the automation script: `./packages/core/src/skills/builtin/_ux_git-worktree/scripts/worktree-manager.sh pr 123`.
3. **Mandatory Prep**: Run `npm install` inside the new worktree directory to ensure all dependencies are resolved.
4. This script will automatically fetch the PR title and create a semantic directory name (e.g., `pr-123-fix-core-bug`).
### 3. Committing Changes in a Worktree
If operating in a sibling worktree (e.g., `feature-xyz/`):
1. Check for sandbox access to `../main/.git`.
2. If access is denied, use `/directory add ../main/.git` (if interactive) or suggest the `--include-directories` flag for the next launch.
## Task-Based Guide
### Managing Worktrees
- **List Worktrees**: Run `git worktree list`.
- **Semantic PR Checkout**: `worktree-manager.sh pr <number>`.
- **Add Manual Worktree**: `git worktree add ../<dir> <branch>`.
- **Remove Worktree**: `git worktree remove <dir>`.
## Resources
### references/architecture.md
Technical details of the "Base Folder" standard.
### scripts/worktree-manager.sh
Automated wrapper for Git Worktree operations that handles sibling pathing, semantic PR naming, and metadata links.
@@ -1,24 +0,0 @@
# Base Folder Strategy Architecture
## Directory Layout
```text
/project-root/ <-- Container directory (Base Folder)
├── main/ # Primary repository checkout (contains .git/)
├── feature-alpha/ # Isolated worktree for feature 'alpha'
├── bugfix-beta/ # Isolated worktree for bugfix 'beta'
└── ...
```
## Shared Metadata
All worktrees (`feature-alpha/`, `bugfix-beta/`, etc.) share the Git database
located in `main/.git`. Git worktrees use a `.git` file (not a directory) that
contains a pointer to the original metadata:
`gitdir: /path/to/main/.git/worktrees/feature-alpha`
## Sandbox Constraints (macOS)
On macOS, the Seatbelt sandbox restricts write access to the worktree directory
only. To perform Git operations (which modify `main/.git/worktrees/`), the agent
requires explicit access to the `main/.git` path.
@@ -1,69 +0,0 @@
#!/bin/bash
# worktree-manager.sh - Manage sibling worktrees for Gemini CLI
set -e
ACTION="${1}"
NAME="${2}"
BRANCH="${3}"
BASE_DIR="$(pwd)"
PARENT_DIR="$(dirname "${BASE_DIR}")"
slugify() {
local input="${1}"
local slug
slug=$(echo "${input}" | iconv -t ascii//TRANSLIT)
slug=$(echo "${slug}" | tr -cd "[:alnum:] ")
slug=$(echo "${slug}" | tr "[:upper:]" "[:lower:]")
slug=$(echo "${slug}" | tr " " "-")
slug="${slug//--/-}"
slug=$(echo "${slug}" | cut -c 1-50)
echo "${slug}"
}
case "${ACTION}" in
"add")
if [[ -z "${NAME}" ]] || [[ -z "${BRANCH}" ]]; then
echo "Error: Usage: worktree-manager.sh add <dir-name> <branch-name>"
exit 1
fi
git worktree add "${PARENT_DIR}/${NAME}" "${BRANCH}"
echo "Success: Added worktree at ${PARENT_DIR}/${NAME} tracking branch ${BRANCH}"
;;
"pr")
if [[ -z "${NAME}" ]]; then
echo "Error: Usage: worktree-manager.sh pr <pr-number>"
exit 1
fi
PR_NUMBER="${NAME}"
echo "Fetching PR details for #${PR_NUMBER}..."
PR_DATA=$(gh pr view "${PR_NUMBER}" --json title,headRefName)
PR_TITLE=$(echo "${PR_DATA}" | jq -r .title)
PR_BRANCH=$(echo "${PR_DATA}" | jq -r .headRefName)
SLUG=$(slugify "${PR_TITLE}")
DIR_NAME="pr-${PR_NUMBER}-${SLUG}"
echo "Creating semantic worktree: ${DIR_NAME}"
git worktree add "${PARENT_DIR}/${DIR_NAME}" "${PR_BRANCH}"
echo "Success: Added PR worktree at ${PARENT_DIR}/${DIR_NAME}"
;;
"list")
git worktree list
;;
"remove")
if [[ -z "${NAME}" ]]; then
echo "Error: Usage: worktree-manager.sh remove <dir-name>"
exit 1
fi
git worktree remove "${PARENT_DIR}/${NAME}"
echo "Success: Removed worktree ${PARENT_DIR}/${NAME}"
;;
*)
echo "Error: Unknown action ${ACTION}"
exit 1
;;
esac