Communitygithub.com

Lev-it/lev-skills

適用於 json-render 的 Ink 終端機渲染器,能將 JSON 規格轉換成交互式終端機 UI。適用於搭配 @json-render/ink 使用、從 JSON 建立終端機 UI、建立終端機元件目錄,或在終端機中渲染 AI 生成的規格。

lev-skills 是什麼?

這是一個專門為 @json-render/ink 打造的 Ink 終端機渲染器技能,其核心功能是將結構化的 JSON 規格(JSON Spec)直接轉換成可互動的終端機使用者介面(TUI)。開發者不需撰寫大量渲染邏輯,只需定義一個包含元件類型、屬性與狀態綁定的 JSON 規格,就能在終端機中渲染出包含 Box、Text、輸入框、圖表、表格等豐富元件的複雜 UI。此技能支援 Claude Code、Cursor 與 Codex 等 AI 編碼代理,當 AI 需要生成、預覽或調整終端機 UI 時,使用此技能可確保輸出的 JSON 規格符合 @json-render/ink 的結構,進而達到所見即所得的開發體驗。詳細做法是在對話中提供目標 UI 的描述,AI 即根據此技能的 SKILL.md 文件產生對應的 JSON 規格,再由 @json-render/ink 渲染成實際的終端機畫面。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Lev-it/lev-skills/tree/HEAD/.claude/skills/ink

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

@json-render/ink

Ink 終端機渲染器,將 JSON 規格轉換成交互式終端機元件樹,支援標準元件、資料綁定、可見性判斷、動作處理與動態屬性。

快速開始

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";

// 建立目錄(包含標準元件及自訂元件)
const catalog = defineCatalog(schema, {
  components: {
    ...standardComponentDefinitions,
    CustomWidget: {
      props: z.object({ title: z.string() }),
      slots: [],
      description: "自訂小工具",
    },
  },
  actions: standardActionDefinitions,
});

// 僅註冊自訂元件(標準元件已內建)
const { registry } = defineRegistry(catalog, {
  components: {
    CustomWidget: ({ props }) => <Text>{props.title}</Text>,
  } as Components<typeof catalog>,
});

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

規格結構(扁平元素對應表)

Ink 的規格使用扁平的元素對應表,並以一個根鍵值作為開頭:

{
  "root": "main",
  "elements": {
    "main": {
      "type": "Box",
      "props": { "flexDirection": "column", "padding": 1 },
      "children": ["heading", "content"]
    },
    "heading": {
      "type": "Heading",
      "props": { "text": "儀表板", "level": "h1" },
      "children": []
    },
    "content": {
      "type": "Text",
      "props": { "text": "來自終端機的問候!" },
      "children": []
    }
  }
}

標準元件

佈局

  • Box - Flexbox 佈局容器(類似終端機的 <div>)。用於分組、間距、邊框、對齊。預設 flexDirection 為 row。
  • Text - 文字輸出,可選樣式(顏色、粗體、斜體等)
  • Newline - 插入空白行。必須放在 flexDirection 為 column 的 Box 內。
  • Spacer - 可沿主軸擴展的彈性空白空間。

內容

  • Heading - 區段標題(h1:粗體+底線,h2:粗體,h3:粗體+暗淡,h4:暗淡)
  • Divider - 水平分隔線,可選置中標題
  • Badge - 彩色行內標籤(變體:default、info、success、warning、error)
  • Spinner - 帶有可選標籤的動畫載入旋轉器
  • ProgressBar - 水平進度條(0-1)
  • Sparkline - 使用 Unicode 區塊字元的行內圖表
  • BarChart - 帶標籤與數值的水平長條圖
  • Table - 含標題行與資料行的表格
  • List - 項目符號或數字清單
  • ListItem - 結構化清單行,包含標題、副標題、前導/結尾文字
  • Card - 帶邊框的容器,可選標題
  • KeyValue - 鍵值對顯示
  • Link - 可點擊的 URL,可選標籤
  • StatusLine - 帶有彩色圖示的狀態訊息(info、success、warning、error)
  • Markdown - 以終端機樣式渲染 Markdown 文字

互動式

  • TextInput - 文字輸入欄位(事件:submit、change)
  • Select - 使用方向鍵導航的選單(事件:change)
  • MultiSelect - 按空格切換的多選(事件:change、submit)
  • ConfirmInput - 是/否確認提示(事件:confirm、deny)
  • Tabs - 使用左右方向鍵導航的分頁列(事件:change)

可見性條件

使用元素的 visible 屬性,根據狀態控制顯示/隱藏。語法:{ "$state": "/path" }、{ "$state": "/path", "eq": value }、{ "$state": "/path", "not": true }、{ "$and": [cond1, cond2] } 表示 AND、{ "$or": [cond1, cond2] } 表示 OR。

動態屬性表達式

任何屬性值都可以是資料驅動的表達式,在渲染時解析:

  • { "$state": "/state/key" } - 從狀態模型中讀取(單向讀取)
  • { "$bindState": "/path" } - 雙向綁定:用於表單元件的自然值屬性
  • { "$bindItem": "field" } - 雙向綁定至重複項目的欄位
  • { "$cond": <條件>, "$then": <值>, "$else": <值> } - 條件值
  • { "$template": "Hello, ${/name}!" } - 將狀態值插值到字串中

元件不使用 statePath 屬性進行雙向綁定。請改用 { "$bindState": "/path" } 於自然值屬性上。

事件系統

元件使用 emit 觸發具名事件。元素的 on 欄位將事件對應到動作綁定:

CustomButton: ({ props, emit }) => (
  <Box>
    <Text>{props.label}</Text>
    {/* emit("press") 將觸發規格 on.press 中綁定的動作 */}
  </Box>
),
{
  "type": "CustomButton",
  "props": { "label": "提交" },
  "on": { "press": { "action": "submit" } },
  "children": []
}

內建動作

setState、pushState 和 removeState 為內建動作,會自動處理:

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

重複(動態清單)

在容器元素上使用 repeat 欄位,從狀態陣列渲染項目:

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

在重複的子元素內,使用 { "$item": "field" } 讀取當前項目的欄位,使用 { "$index": true } 取得當前索引。

串流

使用 useUIStream 從 JSONL 修補串流逐步渲染規格:

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

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

伺服器端提示生成

使用 ./server 匯出,從您的目錄生成 AI 系統提示詞:

import { catalog } from "./catalog";

const systemPrompt = catalog.prompt({ system: "你是一個終端機助手。" });

提供者

提供者用途
StateProvider跨元件共享狀態(JSON Pointer 路徑)。接受可選的 store 屬性以使用受控模式。
ActionProvider處理透過事件系統分派的動作
VisibilityProvider根據狀態啟用條件式渲染
ValidationProvider表單欄位驗證
FocusProvider管理互動式元件之間的焦點
JSONUIProvider所有上下文提供者的組合

外部儲存(受控模式)

將 StateStore 傳遞給 StateProvider(或 JSONUIProvider)以使用外部狀態管理:

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

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

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

store.set("/count", 1); // React 會自動重新渲染

當提供了 store 時,initialState 和 onStateChange 將被忽略。

createRenderer(高階 API)

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

const InkRenderer = createRenderer(catalog, {
  ...standardComponents,
  // 在此覆寫自訂元件
});

// InkRenderer 包含所有提供者(狀態、可見性、動作、焦點)
render(
  <InkRenderer spec={spec} state={{ activeTab: "overview" }} />
);

主要匯出

匯出名稱用途
defineRegistry從目錄建立型別安全的元件註冊表
Renderer使用註冊表渲染規格
createRenderer高階:建立包含內建提供者的元件
JSONUIProvider所有上下文提供者的組合
schemaInk 扁平元素對應表規格(包含內建狀態動作)
standardComponentDefinitions所有標準元件的目錄定義
standardActionDefinitions標準動作的目錄定義
standardComponents預建立的元件實作
useStateStore存取狀態上下文
useStateValue從狀態中取得單一值
useBoundProp$bindState/$bindItem 表達式的雙向綁定
useActions存取動作上下文
useAction取得單一動作分派函式
useOptionalValidationuseValidation 的非拋出變體
useUIStream從 API 端點串流規格
createStateStore建立與框架無關的記憶體 StateStore
StateStore插入外部狀態管理的介面
Components型別化的元件映射(可感知目錄)
Actions型別化的動作映射(可感知目錄)
ComponentContext型別化的元件上下文(可感知目錄)
flatToTree將扁平元素對應表轉換為樹狀結構

終端機 UI 設計指南

  • 使用 Box 進行佈局(flexDirection、padding、gap)。預設 flexDirection 為 row。
  • 終端機寬度約為 80-120 欄。主要結構建議使用垂直佈局(flexDirection: column)。
  • 在 Box 上使用 borderStyle 進行視覺分組(single、double、round、bold)。
  • 使用標準終端機顏色:red、green、yellow、blue、magenta、cyan、white、gray。
  • 使用 Heading 作為區段標題、Divider 分隔區段、Badge 標示狀態、KeyValue 顯示標籤資料、Card 作為邊框群組。
  • 使用 Tabs 搭配子內容的可見性條件,實現多檢視 UI。
  • 使用 Sparkline 顯示行內趨勢、使用 BarChart 比較數值。

Individual skills in this repo

This repo contains 11 individual skills — each has its own dedicated page.

Lev-it/lev-skills

Ask which skill or flow fits your situation. A router over the user-invoked skills in this repo.

Lev-it/lev-skills

Premium brand-kit image generation skill for creating high-end brand-guidelines boards, logo systems, identity decks, and visual-world presentations. Trained for minimalist, cinematic, editorial, dark-tech, luxury, cultural, security, gaming, developer-tool, and consumer-app brand systems. Optimized for intentional logo concepting, refined composition, sparse typography, strong symbolic meaning, premium mockups, art-directed imagery, and flexible grid layouts.

Lev-it/lev-skills

Compact the current conversation into a handoff document for another agent to pick up.

Lev-it/lev-skills

Interactive QA session where user reports bugs or issues conversationally, and the agent files GitHub issues. Explores the codebase in the background for context and domain language. Use when user wants to report bugs, do QA, file issues conversationally, or mentions "QA session".

Lev-it/lev-skills

Facilitate a structured sprint retrospective — what went well, what didn't, and prioritized action items with owners and deadlines. Use when running a retrospective, reflecting on a sprint, creating action items from team feedback, or learning how to run effective retros.

Lev-it/lev-skills

Review the changes since a fixed point (commit, branch, tag, or merge-base) along two axes — Standards (does the code follow this repo's documented coding standards?) and Spec (does the code match what the originating issue/PRD asked for?). Runs both reviews in parallel sub-agents and reports them side by side. Use when the user wants to review a branch, a PR, work-in-progress changes, or asks to "review since X".

Lev-it/lev-skills

Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.

Lev-it/lev-skills

Teach the user a new skill or concept, within this workspace.

Lev-it/lev-skills

Turn the current conversation into a PRD and publish it to the project issue tracker — no interview, just synthesis of what you've already discussed.

Lev-it/lev-skills

Move issues through a state machine of triage roles — categorise, reproduce, grill if needed, and write agent-ready briefs.

Lev-it/lev-skills

Create product backlog items in Why-What-Acceptance format — independent, valuable, testable items with strategic context. Use when writing structured backlog items, breaking features into work items, or using the WWA format.

相關技能