Skip to content

Implement rich CLI UI with Ink components and gradients#9

Merged
tikazyq merged 4 commits into
mainfrom
copilot/fix-217570708-1087021690-3a73d161-57b7-4e72-9523-605101e29d70
Nov 3, 2025
Merged

Implement rich CLI UI with Ink components and gradients#9
tikazyq merged 4 commits into
mainfrom
copilot/fix-217570708-1087021690-3a73d161-57b7-4e72-9523-605101e29d70

Conversation

Copilot AI commented Nov 3, 2025

Copy link
Copy Markdown
Contributor

Implements spec 013-cli-ui-ux-optimization to bring Python rich-style UI to the CLI. All commands now use Ink/React for consistent, beautiful rendering.

Component Library

Created reusable UI primitives in src/components/ui/:

  • Panel: Rounded borders (╭─╮╰─╯) with titles
  • Table: Auto-sized columns with alignment
  • KeyValueList: Aligned metadata display
  • StatusBadge: Emoji + color indicators
  • Card: Metadata cards with borders

Command Enhancements

Stats: Multi-panel dashboard with bar charts

// Before: Plain text lists
// After: Panels with visual bars
╭─ 📊 Status Distribution ──────╮
 📅 Planned  ━━━━━━━━━ 6      
 🔨 Progress ━━━ 2             
╰────────────────────────────────╯

Board: Enhanced kanban with hashtag tags, emoji priorities

// Before: [ux, polish] priority: medium
// After:  #ux #polish · 🟠 medium

List: Converted from console.log to Ink with tree structure

// Before: Simple indented text
// After:  Tree with metadata
📂 20251103/
  ├─ 001-feature/
      🟡 high · [#core #ux]

Visual Design

  • Rainbow gradient titles via ink-gradient
  • Bar charts with Unicode (━━━) for distributions
  • Rounded corners for softer appearance
  • Semantic color coding (cyan/yellow/green/magenta)
  • Tree characters (├─) for hierarchy

Dependencies

Added Ink ecosystem libraries:

  • ink-gradient ^3.0.0 (gradients)
  • ink-table, ink-spinner, ink-select-input, ink-text-input, ink-progress-bar (future interactive features)

All 106 tests pass. Zero security vulnerabilities.

Original prompt

let's implement this spec

[Chronological Review: The conversation began with the user expressing dissatisfaction with the CLI UI/UX render and requesting the creation of a specification to optimize it. The user then clarified their desire for a prettier UI, emphasizing that it should not be overly simplified and should utilize the Ink library, likening it to the 'rich' library in Python for Node.js. Finally, the user requested to implement the spec.]

[Intent Mapping:

  1. "i still don't like the cli ui/ux render. let's create a spec to optimize it" - User wants to create a specification for optimizing the CLI UI/UX.
  2. "i want a prettier ui, not an over-simplified one. let's keep with ink. can you think of it like a rich (python) for node.js?" - User specifies the desired aesthetic and functionality of the UI, indicating a preference for the Ink library.
  3. "let's implement this spec" - User requests to proceed with the implementation of the spec.]

[Technical Inventory:

  • Core Technology: Ink (for rendering CLI UIs in Node.js).
  • Comparison Reference: 'rich' library in Python, indicating a desire for rich formatting and aesthetics in the CLI interface.]

[Code Archaeology: No specific files or code changes were discussed in detail yet, but the user is focused on the README.md file related to the CLI UI/UX optimization.]

[Progress Assessment:

  • Completed Tasks: User has articulated their dissatisfaction and provided a clear direction for the UI/UX optimization.
  • Partially Complete Work: The specification for the optimization is in the process of being created and implemented.]

[Context Validation: All critical information for continuation is captured, including user preferences for the UI and the technology to be used.]

[Recent Commands Analysis:

  • Last Agent Commands: The user requested to implement the spec.
  • Tool Results Summary: No specific tool results were generated as the conversation focused on user requests and intentions.
  • Pre-Summary State: The agent was actively working on understanding and implementing the user's specifications for the CLI UI/UX optimization when the token budget was exceeded.
  • Operation Context: The commands executed were directly related to the user's goal of improving the CLI UI/UX, emphasizing the need for a visually appealing and functional interface.]
1. Conversation Overview: - Primary Objectives: - "i still don't like the cli ui/ux render. let's create a spec to optimize it" - User wants to create a specification for optimizing the CLI UI/UX. - "i want a prettier ui, not an over-simplified one. let's keep with ink. can you think of it like a `rich` (python) for node.js?" - User specifies the desired aesthetic and functionality of the UI. - "let's implement this spec" - User requests to proceed with the implementation of the spec. - Session Context: The conversation has focused on the user's dissatisfaction with the current CLI UI/UX and their desire to create a more visually appealing interface using the Ink library. - User Intent Evolution: The user has moved from expressing dissatisfaction to specifying their requirements and requesting implementation.
  1. Technical Foundation:
  • Core Technology: Ink - A library for building CLI UIs in Node.js, preferred for its aesthetic capabilities.
  • Comparison Reference: 'rich' library in Python, indicating a desire for rich formatting and aesthetics in the CLI interface.
  1. Codebase Status:
  • File Name: README.md
  • Purpose: Documenting the specifications for the CLI UI/UX optimization.
  • Current State: The file is currently being edited to reflect the new specifications.
  • Key Code Segments: Not specified yet, as the focus has been on user requests.
  • Dependencies: Relates to the overall project for CLI UI/UX.
  1. Problem Resolution:
  • Issues Encountered: User dissatisfaction with the current UI/UX render.
  • Solutions Implemented: User has provided clear specifications for improvement.
  • Debugging Context: No ongoing troubleshooting efforts have been discussed yet.
  • Lessons Learned: User prefers a visually appealing interface that is not overly simplified.
  1. Progress Tracking:
  • Completed Tasks: User has articulated their dissatisfaction and provided a clear direction for the UI/UX optimization.
  • Partially Complete Work: The specification for the optimization is in the process of being created and implemented.
  1. Active Work State:
  • Current Focus: Implementing the spec for CLI UI/UX optimization.
  • Recent Context: The user has expressed their desire for a prettier UI and requested to implement the spec.
  • Working Code: No specific code snippets have been discussed yet.
  • Immediate Context: The user is focused on creating and implementing a specification for the CLI UI/UX optimization.
  1. Recent Operations:
  • Last Agent Commands: User requested to implement the spec.
  • Tool Results Summary: No specific tool results were generated as the conversation focused on use...

Created from VS Code via the GitHub Pull Request extension.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@vercel

vercel Bot commented Nov 3, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
lean-spec Ready Ready Preview Comment Nov 3, 2025 8:05am

Co-authored-by: tikazyq <3393101+tikazyq@users.noreply.github.com>
Co-authored-by: tikazyq <3393101+tikazyq@users.noreply.github.com>
Co-authored-by: tikazyq <3393101+tikazyq@users.noreply.github.com>
Copilot AI changed the title [WIP] Implementing a rich CLI UI spec with Ink Implement rich CLI UI with Ink components and gradients Nov 3, 2025
Copilot AI requested a review from tikazyq November 3, 2025 08:06
@tikazyq tikazyq marked this pull request as ready for review November 3, 2025 08:17
Copilot AI review requested due to automatic review settings November 3, 2025 08:17
@tikazyq tikazyq merged commit 0e1fe76 into main Nov 3, 2025
2 checks passed
@tikazyq tikazyq deleted the copilot/fix-217570708-1087021690-3a73d161-57b7-4e72-9523-605101e29d70 branch November 3, 2025 08:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements UI/UX enhancements for the CLI by introducing reusable Ink-based UI components and refactoring existing displays to use a modern, consistent design system. The changes improve visual appeal with gradient titles, bordered panels, and bar chart visualizations while maintaining functionality.

  • Introduces reusable UI component library (Panel, Table, Card, KeyValueList, StatusBadge)
  • Refactors StatsDisplay, Board, and list command to use new component architecture
  • Adds new dependencies for enhanced terminal UI capabilities (ink-gradient, ink-box, etc.)

Reviewed Changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
src/components/ui/index.ts Exports new UI component library
src/components/ui/Table.tsx New reusable table component with border styles and alignment
src/components/ui/StatusBadge.tsx New badge components for status and priority display
src/components/ui/Panel.tsx New panel component with optional borders and titles
src/components/ui/KeyValueList.tsx New component for displaying key-value pairs
src/components/ui/Card.tsx New card component with metadata support
src/components/StatsDisplay.tsx Refactored to use new Panel component with gradient titles and bar charts
src/components/SpecListView.tsx New component for rendering spec lists (extracted from list command)
src/components/Board.tsx Enhanced with gradient title and improved border styling
src/commands/list.ts Refactored to use React/Ink rendering with SpecListView component
specs/20251103/013-cli-ui-ux-optimization/README.md Marks the UI optimization spec as complete
pnpm-lock.yaml Adds new ink-related dependencies
package.json Declares new ink-related dependencies
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

const headerLength = col.header.length;
const maxContentLength = Math.max(
...rows.map(row => {
const value = Object.values(row)[idx];

Copilot AI Nov 3, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accessing row values by index using Object.values(row)[idx] is fragile and assumes column order matches property order. Consider using a key property in TableColumn to explicitly map columns to row properties by key name. This would make the component more maintainable and less error-prone.

Copilot uses AI. Check for mistakes.
{rows.map((row, rowIdx) => (
<Box key={rowIdx}>
{columns.map((col, colIdx) => {
const value = Object.values(row)[colIdx];

Copilot AI Nov 3, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as Comment 1: accessing row values by index is fragile. The component relies on the order of properties in the row object matching the column order, which is not guaranteed in JavaScript objects.

Copilot uses AI. Check for mistakes.
<Text key={rowIdx}>
<Text color={borderColor}>{vertical}</Text>
{columns.map((col, colIdx) => {
const value = Object.values(row)[colIdx];

Copilot AI Nov 3, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as Comments 1 and 2: accessing row values by index is fragile and should use explicit key mapping instead.

Suggested change
const value = Object.values(row)[colIdx];
const value = row[col.header];

Copilot uses AI. Check for mistakes.
const maxCount = Math.max(...Object.values(statusCounts));
const barWidth = 40;
const createBar = (count: number, color: string) => {
const width = Math.round((count / maxCount) * barWidth);

Copilot AI Nov 3, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Division by zero will occur when maxCount is 0 (e.g., when there are no specs). This will result in NaN which could cause rendering issues. Add a guard condition to handle the case when maxCount === 0.

Suggested change
const width = Math.round((count / maxCount) * barWidth);
const width = maxCount === 0 ? 0 : Math.round((count / maxCount) * barWidth);

Copilot uses AI. Check for mistakes.
Comment thread src/components/Board.tsx

const STATUS_CONFIG: Record<SpecStatus, { emoji: string; label: string; color: string }> = {
planned: { emoji: '📅', label: 'Planned', color: 'gray' },
planned: { emoji: '📅', label: 'Planned', color: 'cyan' },

Copilot AI Nov 3, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The STATUS_CONFIG object is duplicated between Board.tsx and StatusBadge.tsx with slightly different color values (here 'cyan', in StatusBadge.tsx also 'cyan', but previously was 'gray' in the old line). Consider importing and reusing the configuration from StatusBadge.tsx to maintain a single source of truth for status styling.

Copilot uses AI. Check for mistakes.
};

export const getPriorityEmoji = (priority: SpecPriority): string => {
return PRIORITY_CONFIG[priority]?.emoji || '';

Copilot AI Nov 3, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent fallback values: getStatusEmoji returns '❓' when status is not found, but getPriorityEmoji returns an empty string. Consider using a consistent fallback approach (e.g., both return '❓' or both return empty string) for better user experience.

Suggested change
return PRIORITY_CONFIG[priority]?.emoji || '';
return PRIORITY_CONFIG[priority]?.emoji || '';

Copilot uses AI. Check for mistakes.
Comment thread src/commands/list.ts
console.log(chalk.green('=== Specs ==='));
console.log('');
// Build filter info for component
const filterInfo: any = {};

Copilot AI Nov 3, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using any type defeats the purpose of TypeScript's type safety. Define a proper interface for filterInfo or use a more specific type that matches the expected structure for the SpecListView filter prop.

Suggested change
const filterInfo: any = {};
interface SpecListViewFilterInfo {
status?: string;
tags?: string[];
priority?: string;
assignee?: string;
}
const filterInfo: SpecListViewFilterInfo = {};

Copilot uses AI. Check for mistakes.
Comment thread src/components/Board.tsx
import Gradient from 'ink-gradient';
import type { SpecInfo } from '../spec-loader.js';
import type { SpecStatus } from '../frontmatter.js';
import { Card } from './ui/Card.js';

Copilot AI Nov 3, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import Card.

Suggested change
import { Card } from './ui/Card.js';

Copilot uses AI. Check for mistakes.
Comment thread src/components/Board.tsx
const header = `${emoji} ${title} (${count})`;
const padding = Math.max(0, width - header.length - 4);

const isRounded = true;

Copilot AI Nov 3, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable isRounded.

Suggested change
const isRounded = true;

Copilot uses AI. Check for mistakes.
const bottomLeft = isRounded ? '╰' : '└';
const bottomRight = isRounded ? '╯' : '┘';
const horizontal = '─';
const vertical = '│';

Copilot AI Nov 3, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable vertical.

Suggested change
const vertical = '│';

Copilot uses AI. Check for mistakes.
tikazyq added a commit that referenced this pull request Dec 17, 2025
…0-3a73d161-57b7-4e72-9523-605101e29d70

Implement rich CLI UI with Ink components and gradients
tikazyq added a commit that referenced this pull request May 18, 2026
…293)

Pulls the latest plan-dag (upstream commits #9#13): renderer
collapsed to PNG-only, status fills + available-next highlight,
duplicate-id labels rejected, and the obsolete ascii/tb/svg/html
fixture artifacts dropped.

Moves the skill from .claude/skills/plan-dag/ (real directory) to
.agents/skills/plan-dag/ with a .claude/skills/plan-dag symlink,
matching the multi-agent layout the skills CLI now emits.

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants