← 返回 Skills 市场
openlark

Ink — React for interactive command-line apps.

作者 OpenLark · GitHub ↗ · v1.0.0 · MIT-0
cross-platform ✓ 安全检测通过
61
总下载
0
收藏
0
当前安装
1
版本数
在 OpenClaw 中安装
/install ink-tui
功能描述
Ink — React for interactive command-line apps. Build rich terminal UIs with React components.
使用说明 (SKILL.md)

Ink Skill Guide

Overview

Ink renders React components directly to the terminal using Yoga layout (Flexbox for CLI). It handles diffing, re-rendering, and terminal I/O. Components receive real React state, effects, and hooks — the same mental model as web React.Requires Node.js 22+ and React 19.2+ as peer dependencies.

Triggers

when the user wants to create CLI/TUI apps, terminal dashboards, interactive prompts, colored terminal output, spinners, progress bars, or tables using JSX/React syntax.

  • building CLI apps with React
  • creating interactive terminal UIs
  • rendering styled terminal output
  • handling keyboard input in the terminal
  • terminal layout with Flexbox/Yoga

Quick Start

mkdir my-cli && cd my-cli
pnpm init
pnpm add ink react @types/react
pnpm add -D tsx typescript @types/node
// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "jsx": "react-jsx",
    "strict": true,
    "outDir": "build"
  }
}
// index.tsx
import { render, Box, Text } from 'ink';

const App = () => (
  \x3CBox flexDirection="column">
    \x3CText color="green" bold>Hello, CLI!\x3C/Text>
  \x3C/Box>
);

render(\x3CApp />);

Run: node --import=tsx index.tsx

Architecture

Ink uses react-reconciler as its rendering core and yoga-layout as its layout engine. It mounts components into a virtual terminal, diffs against current output, and writes changes to stdout. This means:

  • Full React state/lifecycle (useState, useEffect, etc.)
  • Flexbox layout via Yoga (not CSS — uses integer-based positioning)
  • Terminal output is treated as an append-only buffer that gets replaced on re-render

Components

\x3CBox> — Layout Container

import { Box, Text } from 'ink';

// Row layout (default flexDirection)
\x3CBox gap={2}>
  \x3CText>Left\x3C/Text>
  \x3CText>Right\x3C/Text>
\x3C/Box>

// Column layout with border
\x3CBox flexDirection="column" borderStyle="round" padding={1} width={40}>
  \x3CText bold>Title\x3C/Text>
  \x3CText dim>subtitle\x3C/Text>
\x3C/Box>

Key Box props: width, height, padding/paddingX/paddingY, borderStyle (single/double/round/classic/bold), borderDimColor, gap, flexGrow, flexShrink, flexDirection (row/column), justifyContent, alignItems.

\x3CText> — Styled Text

// Direct styling
\x3CText color="green" bold underline>Success\x3C/Text>

// Nested spans
\x3CText>
  Regular \x3CText bold>bold\x3C/Text> and \x3CText color="red" inverse>inverse red\x3C/Text>
\x3C/Text>

// Wrap via width
\x3CText width={40} wrap="truncate">Truncated long text...\x3C/Text>

Colors: black/red/green/yellow/blue/magenta/cyan/white/gray + Bright variants (redBright, etc.), hex (#ff0000), rgb(255,0,0).
Background: prefix with bg (bgGreen, bgCyanBright).
Styles: bold, dim, italic, underline, strikethrough, inverse.

\x3CNewline>, \x3CSpacer>

\x3CNewline count={2} />       // n blank lines
\x3CSpacer />                   // flex spacer
\x3CSpacer height={3} />        // fixed height spacer

Hooks

useInput — Keyboard Input

import { useInput } from 'ink';

useInput((input, key) => {
  if (key.escape || input === 'q') exit();           // exit on Escape or 'q'
  if (key.upArrow) navigateUp();
  if (key.downArrow) navigateDown();
  if (key.return) selectItem();
});

key object: upArrow, downArrow, leftArrow, rightArrow, return, escape, tab, backspace, delete, ctrl, shift, meta, space, pageUp, pageDown, home, end, f1–f12.

useApp — App-Level Control

import { useApp } from 'ink';
const { exit } = useApp();
exit();  // or exit(error)

useFocus — Focus Management

import { useFocus } from 'ink';
const { isFocused } = useFocus({ autoFocus: true });
// Style differently when focused
\x3CText color={isFocused ? 'blue' : 'dim'}>{label}\x3C/Text>

useStdin / useStdout — Stream Access

const { stdin, isRawModeSupported } = useStdin();
const { stdout } = useStdout();

render() Options

render(\x3CApp />, {
  exitOnCtrlC: true,         // default true
  debug: false,              // show Yoga layout debug
  patchConsole: true,        // suppress console output
});

Common Patterns

Select/Menu

const Menu = ({ items, onSelect }) => {
  const [idx, setIdx] = useState(0);
  useInput((_, key) => {
    if (key.upArrow) setIdx(i => Math.max(0, i - 1));
    if (key.downArrow) setIdx(i => Math.min(items.length - 1, i + 1));
    if (key.return) onSelect(items[idx]);
  });
  return (
    \x3CBox flexDirection="column">
      {items.map((item, i) => (
        \x3CText key={i} color={i === idx ? 'green' : undefined}>
          {i === idx ? '❯ ' : '  '}{item}
        \x3C/Text>
      ))}
    \x3C/Box>
  );
};

Spinner (useEffect + setInterval)

const Spinner = () => {
  const [frame, setFrame] = useState(0);
  const chars = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
  useEffect(() => {
    const id = setInterval(() => setFrame(f => (f + 1) % chars.length), 80);
    return () => clearInterval(id);
  }, []);
  return \x3CText>{chars[frame]} Loading...\x3C/Text>;
};

Progress Bar

const ProgressBar = ({ percent }) => {
  const filled = '█'.repeat(Math.round(percent / 5));
  const empty = '░'.repeat(20 - filled.length);
  return \x3CText>{filled}{empty} {percent}%\x3C/Text>;
};

Input Field (useInput + useState)

const Input = ({ onSubmit }) => {
  const [value, setValue] = useState('');
  useInput((input, key) => {
    if (key.return) { onSubmit(value); setValue(''); }
    else if (key.backspace) setValue(v => v.slice(0, -1));
    else if (input.length === 1 && !key.ctrl) setValue(v => v + input);
  });
  return \x3CText>❯ {value}\x3CText dim>█\x3C/Text>\x3C/Text>;
};

Resources

This skill includes:

  • components.md — Full component and prop reference
  • hooks.md — Hook API details and custom hook patterns
  • examples.md — Complete runnable examples (counter, table, loading, CLI arguments)

Key Constraints

  • Node.js >= 22 required (ESM only)
  • React >= 19.2 is a peer dependency
  • Only works in real terminal (no browser)
  • Layout via Yoga Flexbox — units are characters/rows, not pixels
  • No scrolling — the terminal viewport is the canvas
  • Colors depend on terminal support (most modern terminals support 256-color)
  • Interactive mode requires raw stdin (Ink enables it automatically)
安全使用建议
This result is low confidence because the requested files could not be inspected. Re-run the scan in an environment where metadata.json and the artifact directory are readable before relying on this review.
功能分析
Type: OpenClaw Skill Name: ink-tui Version: 1.0.0 The ink-tui skill bundle is a legitimate documentation and reference guide for the Ink library, which allows building terminal UIs using React. It contains standard API references for components (SKILL.md, components.md), hooks (hooks.md), and several practical code examples (examples.md) for common CLI patterns like menus, progress bars, and tables. There are no indicators of malicious intent, data exfiltration, or prompt injection.
能力评估
Purpose & Capability
metadata.json and artifact files were requested for review, but local command execution failed before any files could be listed or read.
Instruction Scope
No SKILL.md or artifact instructions were accessible, so instruction scope could not be assessed from evidence.
Install Mechanism
No install specs or manifest contents were accessible; no install risk is supported by artifact evidence.
Credentials
No runtime, environment, or capability declarations were accessible for proportionality review.
Persistence & Privilege
No artifact-backed evidence of persistence, privilege use, credentials, or sensitive data handling was available.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install ink-tui
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /ink-tui 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v1.0.0
Initial release of ink-tui: React-based toolkit for terminal UIs. - Provides React components (`Box`, `Text`, `Newline`, `Spacer`) for building interactive terminal apps with Flexbox/Yoga layout. - Supports keyboard input, focus, and app control via hooks (`useInput`, `useApp`, `useFocus`, `useStdin`, `useStdout`). - Includes examples for menus, spinners, progress bars, and input fields. - Requires Node.js 22+ (ESM-only) and React 19.2+ as peer dependencies. - Documents key constraints: terminal-only, Yoga-based layout, color/style support per terminal. - Bundles detailed references for components, hooks, and runnable examples.
元数据
Slug ink-tui
版本 1.0.0
许可证 MIT-0
累计安装 0
当前安装数 0
历史版本数 1
常见问题

Ink — React for interactive command-line apps. 是什么?

Ink — React for interactive command-line apps. Build rich terminal UIs with React components. 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 61 次。

如何安装 Ink — React for interactive command-line apps.?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install ink-tui」即可一键安装,无需额外配置。

Ink — React for interactive command-line apps. 是免费的吗?

是的,Ink — React for interactive command-line apps. 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。

Ink — React for interactive command-line apps. 支持哪些平台?

Ink — React for interactive command-line apps. 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 Ink — React for interactive command-line apps.?

由 OpenLark(@openlark)开发并维护,当前版本 v1.0.0。

💬 留言讨论