본문으로 건너뛰기
cccskills
무료GitHub에 공개

ink

Build interactive terminal interfaces from JSON specifications with @json-render/ink. The skill covers standard and custom components, input handling, state connections, conditional display, and progressively rendering specifications generated by AI.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

원문원문 설명 보기

Ink terminal renderer for json-render that turns JSON specs into interactive terminal UIs. Use when working with @json-render/ink, building terminal UIs from JSON, creating terminal component catalogs, or rendering AI-generated specs in the terminal.

설치 방법 보기

이럴 때 유용합니다

  • Building a terminal dashboard from JSON
  • Creating forms with input fields and selection menus
  • Defining a catalog of custom terminal components
  • Displaying AI-generated interfaces progressively

포함된 파일(1)

  • SKILL.md9.7 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

@json-render/ink

Ink terminal renderer that converts JSON specs into interactive terminal component trees with standard components, data binding, visibility, actions, and dynamic props.

Quick Start

import { defineCatalog } from "@json-render/core";
import { schema } from "@json-render/ink/schema";
import {
  standardComponentDefinitions,
  standardActionDefinitions,
} from "@json-render/ink/catalog";
import { defineRegistry, Renderer, type Components } from "@json-render/ink";
import { z } from "zod";

// Create catalog with standard + custom components
const catalog = defineCatalog(schema, {
  components: {
    ...standardComponentDefinitions,
    CustomWidget: {
      props: z.object({ title: z.string() }),
      slots: [],
      description: "Custom widget",
    },
  },
  actions: standardActionDefinitions,
});

// Register only custom components (standard ones are built-in)
const { registry } = defineRegistry(catalog, {
  components: {
    CustomWidget: ({ props }) => <Text>{props.title}</Text>,
  } as Components<typeof catalog>,
});

// Render
function App({ spec }) {
  return (
    <JSONUIProvider initialState={{}}>
      <Renderer spec={spec} registry={registry} />
    </JSONUIProvider>
  );
}

Spec Structure (Flat Element Map)

The Ink schema uses a flat element map with a root key:

{
  "root": "main",
  "elements": {
    "main": {
      "type": "Box",
      "props": { "flexDirection": "column", "padding": 1 },
      "children": ["heading", "content"]
    },
    "heading": {
      "type": "Heading",
      "props": { "text": "Dashboard", "level": "h1" },
      "children": []
    },
    "content": {
      "type": "Text",
      "props": { "text": "Hello from the terminal!" },
      "children": []
    }
  }
}

Standard Components

Layout

  • Box - Flexbox layout container (like a terminal <div>). Use for grouping, spacing, borders, alignment. Default flexDirection is row.
  • Text - Text output with optional styling (color, bold, italic, etc.)
  • Newline - Inserts blank lines. Must be inside a Box with flexDirection column.
  • Spacer - Flexible empty space that expands along the main axis.

Content

  • Heading - Section heading (h1: bold+underlined, h2: bold, h3: bold+dimmed, h4: dimmed)
  • Divider - Horizontal separator with optional centered title
  • Badge - Colored inline label (variants: default, info, success, warning, error)
  • Spinner - Animated loading spinner with optional label
  • ProgressBar - Horizontal progress bar (0-1)
  • Sparkline - Inline chart using Unicode block characters
  • BarChart - Horizontal bar chart with labels and values
  • Table - Tabular data with headers and rows
  • List - Bulleted or numbered list
  • ListItem - Structured list row with title, subtitle, leading/trailing text
  • Card - Bordered container with optional title
  • KeyValue - Key-value pair display
  • Link - Clickable URL with optional label
  • StatusLine - Status message with colored icon (info, success, warning, error)
  • Markdown - Renders markdown text with terminal styling

Interactive

  • TextInput - Text input field (events: submit, change)
  • Select - Selection menu with arrow key navigation (events: change)
  • MultiSelect - Multi-selection with space to toggle (events: change, submit)
  • ConfirmInput - Yes/No confirmation prompt (events: confirm, deny)
  • Tabs - Tab bar navigation with left/right arrow keys (events: change)

Visibility Conditions

Use visible on elements to show/hide based on state. Syntax: { "$state": "/path" }, { "$state": "/path", "eq": value }, { "$state": "/path", "not": true }, { "$and": [cond1, cond2] } for AND, { "$or": [cond1, cond2] } for OR.

Dynamic Prop Expressions

Any prop value can be a data-driven expression resolved at render time:

  • { "$state": "/state/key" } - reads from state model (one-way read)
  • { "$bindState": "/path" } - two-way binding: use on the natural value prop of form components
  • { "$bindItem": "field" } - two-way binding to a repeat item field
  • { "$cond": <condition>, "$then": <value>, "$else": <value> } - conditional value
  • { "$template": "Hello, ${/name}!" } - interpolates state values into strings

Components do not use a statePath prop for two-way binding. Use { "$bindState": "/path" } on the natural value prop instead.

Event System

Components use emit to fire named events. The element's on field maps events to action bindings:

CustomButton: ({ props, emit }) => (
  <Box>
    <Text>{props.label}</Text>
    {/* emit("press") triggers the action bound in the spec's on.press */}
  </Box>
),
{
  "type": "CustomButton",
  "props": { "label": "Submit" },
  "on": { "press": { "action": "submit" } },
  "children": []
}

Built-in Actions

setState, pushState, and removeState are built-in and handled automatically:

{ "action": "setState", "params": { "statePath": "/activeTab", "value": "home" } }
{ "action": "pushState", "params": { "statePath": "/items", "value": { "text": "New" } } }
{ "action": "removeState", "params": { "statePath": "/items", "index": 0 } }

Repeat (Dynamic Lists)

Use the repeat field on a container element to render items from a state array:

{
  "type": "Box",
  "props": { "flexDirection": "column" },
  "repeat": { "statePath": "/items", "key": "id" },
  "children": ["item-row"]
}

Inside repeated children, use { "$item": "field" } to read from the current item and { "$index": true } for the current index.

For nested lists, an inner repeat can use { "statePath": { "$item": "children" } } to iterate an array on the enclosing item.

Streaming

Use useUIStream to progressively render specs from JSONL patch streams:

import { useUIStream } from "@json-render/ink";

const { spec, send, isStreaming } = useUIStream({ api: "/api/generate" });

Server-Side Prompt Generation

Use the ./server export to generate AI system prompts from your catalog:

import { catalog } from "./catalog";

const systemPrompt = catalog.prompt({ system: "You are a terminal assistant." });

Providers

ProviderPurpose
StateProviderShare state across components (JSON Pointer paths). Accepts optional store prop for controlled mode.
ActionProviderHandle actions dispatched via the event system
VisibilityProviderEnable conditional rendering based on state
ValidationProviderForm field validation
FocusProviderManage focus across interactive components
JSONUIProviderCombined provider for all contexts

External Store (Controlled Mode)

Pass a StateStore to StateProvider (or JSONUIProvider) to use external state management:

import { createStateStore, type StateStore } from "@json-render/ink";

const store = createStateStore({ count: 0 });

<StateProvider store={store}>{children}</StateProvider>

store.set("/count", 1); // React re-renders automatically

When store is provided, initialState and onStateChange are ignored.

createRenderer (Higher-Level API)

import { createRenderer } from "@json-render/ink";
import { standardComponents } from "@json-render/ink";
import { catalog } from "./catalog";

const InkRenderer = createRenderer(catalog, {
  ...standardComponents,
  // custom component overrides here
});

// InkRenderer includes all providers (state, visibility, actions, focus)
render(
  <InkRenderer spec={spec} state={{ activeTab: "overview" }} />
);

Key Exports

ExportPurpose
defineRegistryCreate a type-safe component registry from a catalog
RendererRender a spec using a registry
createRendererHigher-level: creates a component with built-in providers
JSONUIProviderCombined provider for all contexts
schemaInk flat element map schema (includes built-in state actions)
standardComponentDefinitionsCatalog definitions for all standard components
standardActionDefinitionsCatalog definitions for standard actions
standardComponentsPre-built component implementations
useStateStoreAccess state context
useStateValueGet single value from state
useBoundPropTwo-way binding for $bindState/$bindItem expressions
useActionsAccess actions context
useActionGet a single action dispatch function
useOptionalValidationNon-throwing variant of useValidation
useUIStreamStream specs from an API endpoint
createStateStoreCreate a framework-agnostic in-memory StateStore
StateStoreInterface for plugging in external state management
ComponentsTyped component map (catalog-aware)
ActionsTyped action map (catalog-aware)
ComponentContextTyped component context (catalog-aware)
flatToTreeConvert flat element map to tree structure

Terminal UI Design Guidelines

  • Use Box for layout (flexDirection, padding, gap). Default flexDirection is row.
  • Terminal width is ~80-120 columns. Prefer vertical layouts (flexDirection: column) for main structure.
  • Use borderStyle on Box for visual grouping (single, double, round, bold).
  • Use named terminal colors: red, green, yellow, blue, magenta, cyan, white, gray.
  • Use Heading for section titles, Divider to separate sections, Badge for status, KeyValue for labeled data, Card for bordered groups.
  • Use Tabs for multi-view UIs with visible conditions on child content.
  • Use Sparkline for inline trends and BarChart for comparing values.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

codegen

무료

Helps build custom code exporters from json-render UI specifications. Covers walking the UI tree, collecting components, state references, and actions, and formatting property values for JSX, the markup syntax used in React.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Build a custom exporter for Next.js or Remix
  • List components and actions used in a UI specification
  • Convert property values into JSX attributes
vercel-labs/json-render1.9만2026년 10월 14일 업데이트

core

무료

Define the structure and available components for AI-generated JSON screens or videos. Build generation prompts, process incremental updates, connect values to application state, and validate or repair definitions before passing them to a renderer.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Define allowed components for AI-generated screens
  • Build prompts for generating or editing JSON definitions
  • Assemble definitions from streamed AI responses
vercel-labs/json-render1.9만2026년 10월 14일 업데이트

devtools

무료

Debug json-render interfaces with an inspector panel that shows screen specifications, editable runtime state, action history, and streamed updates. Select a rendered page element to locate its definition and investigate display or interaction problems.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Investigate missing or incorrectly displayed elements
  • Inspect and edit application state at runtime
  • Review action results and errors
vercel-labs/json-render1.9만2026년 10월 14일 업데이트

Set up an inspection panel in React json-render apps to examine UI definitions, edit state, and review action and stream timelines. The skill also covers opening or toggling the panel and recording events from React code.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Adding an inspection panel to a React app
  • Inspecting UI definitions, state, and action history
  • Opening or toggling the panel from React code
vercel-labs/json-render1.9만2026년 10월 14일 업데이트

Add and troubleshoot the json-render inspection panel in SolidJS applications. This skill covers panel setup for examining specifications, editing state, reviewing action and stream timelines, browsing component catalogs, and selecting page elements for inspection.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Add an inspection panel to a SolidJS app
  • Inspect JSON specifications and edit application state
  • Review action and stream timelines
vercel-labs/json-render1.9만2026년 10월 14일 업데이트

Add and troubleshoot a developer panel in Svelte 5 json-render apps. Inspect JSON screen definitions, edit application state, review action and streaming timelines, browse component catalogs, and select elements directly from the page.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Add a developer panel to a Svelte app
  • Inspect screen definitions and edit application state
  • Review action and streaming timelines
vercel-labs/json-render1.9만2026년 10월 14일 업데이트

vercel-labs의 스킬 모두 보기

이 스킬의 문제 신고