Skip to content

Add TUIKit cross-language component spec system#1

Merged
basiclines merged 18 commits into
mainfrom
basiclines/first-spec-pr
Apr 17, 2026
Merged

Add TUIKit cross-language component spec system#1
basiclines merged 18 commits into
mainfrom
basiclines/first-spec-pr

Conversation

@basiclines
Copy link
Copy Markdown
Collaborator

@basiclines basiclines commented Apr 16, 2026

Summary

Spec-driven UI component system where markdown specs are the source of truth and LLM agents compile them into target language implementations. This PR establishes the full spec system, tooling, and initial compilation across four targets.

What is TUIKit?

TUIKit defines terminal UI components in a language-agnostic markdown format. Each component has a spec (.md), test spec (.test.md), and preview spec (.preview.md). An LLM-powered compiler reads these specs and generates idiomatic implementations for each target framework.

Specs

  • 17 components: Dialog, HintBar, Icons, Input, Link, Metric, QrCode, Screen, ScrollBox, Select, SelectAutocomplete, TabBar, Table, TextHeading, TextSpinner, TextTitle, TimelineItem
  • 3 token systems: colors (semantic palette with 4 color modes), icons (30+ glyphs with semantic aliases), breakpoints (responsive width thresholds)
  • 4 targets: Node (Ink + React), Bun (OpenTUI + React), Go (Bubbletea + Lipgloss), Rust (Ratatui + Crossterm)
  • Schema v2 format: RFC 2119 conformance keywords, frontmatter validation with zod, required sections for visual rules / rendering / dependencies / behavior

Tooling

bun run lint

Validates all specs against the schema. Rules extracted to scripts/lint-rules.ts — zod schemas, rule registry, required sections, RFC 2119 patterns. Auto-generates --help from rules.

bun run compile <command>

  • status — Shows dirty/clean state per target via SHA-256 content hashing
  • prompt --target <name> / --all-targets — Generates index-style compilation prompts (~16KB each, 94% smaller than full-embed approach). Tokens, components, schema, and foundations are referenced by file path with summaries — agents read full specs from disk as needed
  • lock --target <name> / --all-targets — Snapshots spec hashes after successful compilation
  • clean --target <name> / --all-targets — Removes lock files and generated prompts

CI (.github/workflows/specs-ci.yml)

5 checks: lint, compiler health per target, prompt smoke test per target, dist guard, changed-spec completeness.

Key design decisions

  • Token providers: Tokens are exposed at runtime through idiomatic providers (React hooks, Go model methods, Rust trait impls) — not static constants. Providers recompute when environment changes (terminal resize, theme switch).
  • Index-style prompts: Compilation prompts are lean indexes (~16KB) that reference specs by path instead of embedding full content (~257KB). Agents read files from disk, keeping prompts focused.
  • Interactive previews: The demo app is a full-screen TUI with sidebar browser + main preview panel. Every preview variant is a live, interactive component instance — not a static snapshot.
  • Foundations doc: docs/foundations.md captures CLI design principles (color, typography, icons, layout, accessibility, keybinds, buffer management) — referenced but not embedded in prompts.
  • Multi-pass compilation: A single pass is usually not enough for the full suite. 2–3 passes produce notably better results — each pass builds on prior output with diminishing returns after the third.

Repo structure

components/           17 component specs (spec + test + preview each)
tokens/               3 token specs (colors, icons, breakpoints)
targets/              4 target definitions (node, bun, go, rust)
docs/
  schema.md           Meta-spec defining all spec formats
  foundations.md       CLI design principles and best practices
scripts/
  compile.ts          Compiler CLI
  lint.ts             Linter CLI
  lint-rules.ts       Extracted rule definitions and zod schemas
dist/                 Generated code per target (gitignored)

Compilation results

Target Framework Components Tests Demo
Node (Ink + React) ink 5 + React 17 154 ✅ npx tsx demo.tsx
Bun (OpenTUI + React) @opentui/react 17 117 ✅ bun run demo.tsx
Go (Bubbletea) bubbletea + lipgloss 17 187 ✅ go run ./cmd/demo
Rust (Ratatui) ratatui + crossterm 17 164 ✅ cargo run --example demo

Origin

Ported from github/copilot-agent-runtime#5477 into this dedicated repository. Restructured, extended with missing components (Screen, ScrollBox), added CI, refactored tooling, and compiled all four targets.

basiclines and others added 13 commits April 16, 2026 11:27
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add Screen and ScrollBox component specs (md, test, preview)
- Add CI workflow with lint, compiler health, prompt smoke test, dist guard, and changed-spec completeness checks
- Move scripts to scripts/ folder (lint.ts, compile.ts)
- Move _schema.md to docs/schema.md
- Move demo.md to components/previews.md
- Remove csharp target
- Add chalk coloring and TUI-style unicode symbols to script output
- Consolidate frontmatter validation into lint.ts (broken link check)
- Add package.json with scripts, chalk, gray-matter, zod
- Add node_modules to .gitignore
- Update README with getting started section

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Extract lint schemas and rule registry to scripts/lint-rules.ts
- Refactor lint.ts to use gray-matter, zod, fast-glob (768 → 400 lines)
- Add chalk coloring to lint and compile output
- Add missing semantic_aliases to icons token spec (fixes 11 warnings)
- Add bun run scripts to package.json (lint, compile)
- Update all script references to use bun run
- Add compile status hint showing next command per target
- Ignore targets/*.lock.json in .gitignore

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Reflect actual file structure (scripts/, docs/, components/previews.md)
- Use bun run lint / bun run compile throughout all examples
- Add install dependencies section (bun install)
- Document CI checks section
- Document lint-rules.ts as the rule config file
- Note lock files are gitignored; fresh clone starts dirty

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Refactor compile prompt to index style (257KB → 16KB, 94% reduction)
  Schema, tokens, components, and demo are now referenced by file path
  with a brief summary — agents read full specs from disk as needed
- Add --all-targets flag to prompt, lock, and clean commands
- Add padEnd alignment for component names in status/prompt output
- Add token provider concept: runtime layer between static token
  definitions and live component rendering (docs/schema.md + prompt)
- Rewrite previews.md: full-screen TUI with sidebar + main panel layout,
  two-state focus model (sidebar vs preview), fuzzy search, escape to
  return focus
- Add docs/foundations.md from copilot-agent-runtime (design principles
  for CLI: color, typography, icons, layout, accessibility, keybinds)
- Show help before status when no subcommand given

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Enable automated testing of individual component previews without
interactive TUI access. Agents can:
- --list to discover available components
- --component <Name> to open a single preview directly
- --component <Name> --snapshot to capture one rendered frame to stdout
- --variant <name> to target a specific variant

Same render code path as the full TUI, just accessible headlessly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Implement --list, --component, --variant, --snapshot CLI flags
- Create demo.test.tsx with parameterized smoke tests for all 20 components
- Rewrite demo with variant registry matching all .preview.md specs
- All 158 tests pass (134 component + 24 demo/smoke)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add --list, --component, --variant, --snapshot CLI flags to demo app
- Implement full component/variant registry with snapshot rendering
- Add table-driven smoke tests (TestSnapshotAllComponents,
  TestSnapshotEachVariant) that verify every component renders via
  --snapshot with exit 0 and non-empty output
- Fix Select component nil-pointer panic on TextOnBackgroundSecondary
  (was *lipgloss.Color nil, now guarded before dereference)
- Fix Select/SelectAutocomplete terminal state bug in demo: reset
  State back to StateFocused after Enter/number-key selection so the
  preview stays interactive
- Add q-to-quit from preview focus (except text-input components)
- Re-init interactive sub-models on each component open for clean state
- Render all preview variants with TextHeading labels per spec

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- previews.md: Add file structure guidance — demo MUST be split into
  modules (registry, sidebar, preview_panel, app, cli, variants), not
  a single monolithic file
- compile.ts: Verification section now requires running --list and
  --snapshot for every component before reporting done
- Agents must self-test via --snapshot to catch demo wiring bugs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… tests

- Add --list, --component, --variant, --snapshot CLI flags to demo
- Add SelectAutocomplete to demo preview browser (19 total entries)
- Add VariantRenderer helper for per-variant filtering and headings
- Fix Escape key routing: always returns to sidebar from preview
- Reset component state on entering preview
- Add snapshot mode using TestBackend for non-interactive rendering
- Add integration smoke tests (tests/demo_smoke.rs):
  - list_returns_all_components
  - snapshot_all_components_exit_0_with_output
  - unknown_component_exits_with_error
  - unknown_variant_exits_with_error

All 164 tests pass (160 unit + 4 integration).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The bun target becomes the node target using standard Node.js toolchain:
- Runtime: Node.js 20+ (was Bun 1.1+)
- Testing: vitest (was bun:test)
- Execution: npx tsx (was bun run)
- Package manager: npm (was bun install)

The bun target name is reserved for a future OpenTUI-based target.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Switch from imperative factory-function API to React+JSX with OpenTUI's
native Zig renderer. Same mental model as the node/Ink target (hooks,
functional components) but backed by OpenTUI's high-performance core.

Key changes:
- Use @opentui/react createRoot + JSX intrinsic elements (<text>, <box>, etc.)
- Hooks: useKeyboard, useTerminalDimensions, useOnResize, useTimeline
- Token access via React hooks (useColors, useBreakpoint) instead of functions
- Dependencies: @opentui/core + @opentui/react + react 19
- TSX files, jsxImportSource: @opentui/react in tsconfig
- State via useState/useReducer, same as node target

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add guidance that 2-3 compilation passes produce notably better results
than a single pass for the full component suite. Include a table showing
what each pass focuses on and a workflow example for follow-up passes.

Also update target table to reflect the node/bun split (4 targets).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@basiclines basiclines marked this pull request as ready for review April 17, 2026 14:21
Copilot AI review requested due to automatic review settings April 17, 2026 14:22
basiclines and others added 4 commits April 17, 2026 16:24
dist/ is gitignored and should never be committed. These files were
accidentally staged by earlier force-adds. Removes them from the index
only — local copies are unaffected.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Workflow section already covers the same compile/verify/lock flow.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Introduces a spec-driven, cross-language TUI component system where markdown specs (components/tokens/targets) are linted and used to drive compilation prompts and generated implementations across targets.

Changes:

  • Added token specs + previews for colors/icons/breakpoints.
  • Added target definition specs (Bun/Node/Go/Rust) and centralized lint rule definitions (zod + rule registry).
  • Added/updated multiple component specs with corresponding test + preview specs, plus generated target-side smoke tests in dist/.
Show a summary per file
File Description
tokens/icons.preview.md Adds icon token preview variants grouped by icon type.
tokens/icons.md Defines icon glyph tokens and semantic aliases.
tokens/colors.preview.md Adds color token preview sets (groups + specific tokens).
tokens/colors.md Defines semantic color tokens and design/implementation guidance.
tokens/breakpoints.preview.md Adds breakpoint token preview fields.
tokens/breakpoints.md Defines responsive breakpoint thresholds and guidance.
targets/rust.md Documents Rust/Ratatui target conventions and architecture.
targets/node.md Documents Node/Ink target conventions and architecture.
targets/go.md Documents Go/Bubbletea target conventions and architecture.
targets/bun.md Documents Bun/OpenTUI target conventions and architecture.
scripts/lint-rules.ts Centralizes lint rule registry + zod frontmatter schemas + section requirements.
package.json Adds Bun scripts and dependencies for lint/compile tooling.
dist/rust/tests/demo_smoke.rs Adds Rust demo snapshot smoke tests for components/tokens.
dist/go/pkg/tuikit/components/selectcomp/select.go Adds generated Go Select component implementation.
dist/go/cmd/demo/main_test.go Adds Go demo snapshot smoke tests over registry/variants.
components/previews.md Defines the interactive preview app spec and required CLI/snapshot behaviors.
components/TimelineItem/TimelineItem.preview.md Adds TimelineItem preview variants.
components/TextTitle/TextTitle.test.md Adds TextTitle behavioral/style tests.
components/TextTitle/TextTitle.preview.md Adds TextTitle preview variants.
components/TextTitle/TextTitle.md Defines TextTitle component spec (props/tokens/a11y/rules).
components/TextSpinner/TextSpinner.test.md Adds extensive TextSpinner rendering/animation/a11y tests.
components/TextSpinner/TextSpinner.preview.md Adds TextSpinner preview variants.
components/TextSpinner/TextSpinner.md Defines TextSpinner component spec (props/animation/a11y/rules).
components/TextHeading/TextHeading.test.md Adds TextHeading behavioral/style tests.
components/TextHeading/TextHeading.preview.md Adds TextHeading preview variants.
components/TextHeading/TextHeading.md Defines TextHeading component spec (props/tokens/a11y/rules).
components/Table/Table.test.md Adds Table rendering/style/a11y tests.
components/Table/Table.preview.md Adds Table preview variants.
components/Table/Table.md Defines Table component spec (layout/wrapping/a11y/rules).
components/TabBar/TabBar.test.md Adds TabBar rendering/navigation/carousel/a11y tests.
components/TabBar/TabBar.preview.md Adds TabBar preview variants.
components/TabBar/TabBar.md Defines TabBar component spec (keyboard/a11y/carousel rules).
components/SelectAutocomplete/SelectAutocomplete.preview.md Adds SelectAutocomplete preview variants.
components/SelectAutocomplete/SelectAutocomplete.md Defines SelectAutocomplete component spec (search/filtering/a11y/rules).
components/Select/Select.preview.md Adds Select preview variants (incl scrolling/text-input variant).
components/Select/Select.md Defines Select component spec (keyboard/a11y/rules + variant section).
components/ScrollBox/ScrollBox.test.md Adds ScrollBox behavior tests (scrolling/focus/selection).
components/ScrollBox/ScrollBox.preview.md Adds ScrollBox preview variants.
components/ScrollBox/ScrollBox.md Defines ScrollBox component spec (scroll/focus/selection/a11y).
components/Screen/Screen.test.md Adds Screen composition/escape/selection lifecycle tests.
components/Screen/Screen.preview.md Adds Screen preview variants.
components/Screen/Screen.md Defines Screen component spec (layout/scroll wrapper/a11y).
components/QrCode/QrCode.test.md Adds QrCode rendering + cell mapping + placeholder tests.
components/QrCode/QrCode.preview.md Adds QrCode preview variants.
components/QrCode/QrCode.md Defines QrCode component spec (rendering rules/a11y).
components/Metric/Metric.test.md Adds Metric rendering/style tests.
components/Metric/Metric.preview.md Adds Metric preview variants.
components/Metric/Metric.md Defines Metric component spec (grid layout/rules/a11y).
components/Link/Link.test.md Adds Link OSC-8 rendering + sanitization + a11y tests.
components/Link/Link.preview.md Adds Link preview variants.
components/Link/Link.md Defines Link component spec (OSC-8 + sanitization + a11y).
components/Input/Input.preview.md Adds Input preview variants.
components/Input/Input.md Defines Input component spec (keybindings/multiline/masking/a11y).
components/Icons/Icons.preview.md Adds component-level “all icons” preview list.
components/HintBar/HintBar.test.md Adds HintBar rendering/style + formatKey tests.
components/HintBar/HintBar.preview.md Adds HintBar preview variants.
components/HintBar/HintBar.md Defines HintBar component spec (key mapping/rules/a11y).
components/Dialog/Dialog.test.md Adds Dialog rendering/placement/a11y/edge-case tests.
components/Dialog/Dialog.preview.md Adds Dialog preview variants.
components/Dialog/Dialog.md Defines Dialog component spec (placement/rules/a11y).
.gitignore Ignores dist output, node_modules, and target lock snapshots.
.github/workflows/specs-ci.yml Adds CI for spec linting, prompt generation, and dist guard checks.

Copilot's findings

Tip

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

  • Files reviewed: 70/72 changed files
  • Comments generated: 7

Comment thread components/TextTitle/TextTitle.preview.md
Comment thread components/TextHeading/TextHeading.preview.md
Comment thread components/SelectAutocomplete/SelectAutocomplete.md
Comment thread targets/rust.md
Comment thread .github/workflows/specs-ci.yml
Comment thread targets/bun.md
Comment thread tokens/colors.preview.md
Copy link
Copy Markdown

Copilot AI commented Apr 17, 2026

Warning

This is an internal experiment to assess Copilot's ability to auto-approve PRs. Please 👍 this comment if the assessment below is correct and 👎 if not. Feedback in #f-ccr-auto-approve is appreciated!

Copilot thinks this PR is not ready to approve — see review comments for details.

1. TextTitle/TextHeading previews: text → children (matches component API)
2. SelectAutocomplete: add iconPrompt to tokens and dependencies table
3. Rust target: rustc 1.75 → 1.85 (2024 edition requires 1.85+)
4. colors.preview: remove nonexistent tokens (textMuted, textDisabled, textOnBackground)
5. PR description: updated to reflect 4 targets and OpenTUI + React for bun

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@basiclines basiclines merged commit 85b52da into main Apr 17, 2026
2 checks passed
@basiclines basiclines deleted the basiclines/first-spec-pr branch April 17, 2026 15:12
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.

2 participants