schemaui 将 JSON Schema
文档转换为由ratatui、crossterm和jsonschema驱动的完全交互式的终端用户界面。
该库解析丰富的模式(嵌套部分、$ref、数组、键值映射、模式属性等),将其转换为可导航的表单树,将其呈现为键盘优先的编辑器,并在每次编辑后验证结果,以便用户在保存之前始终可以看到完整的错误列表。
CLI 可用:
schemaui-cli会安装schemaui可执行文件。想直接使用 CLI?跳转到 CLI 安装与用法。
draft-07,包括$ref、definitions、、patternProperties、枚举、数值范围以及嵌套的对象/数组。jsonschema::Validator,所有错误(字段作用域 +
全局)都被收集并一起显示。io::input可以处理
JSON/YAML/TOML(通过功能标志),而io::output可以输出到标准输出和/或任何启用格式的多个文件。schemaui-cli提供了与库相同的流程,包括多目标输出、stdin/内联规范和聚合诊断。当你只传 --config 而不显式传 --schema 时,schemaui-cli
现在会按以下优先级解析 schema:
--schemaschema_from_data_value 自动推断支持的声明形式:
$schema#:schema ./schema.json# yaml-language-server: $schema=...# @schema ...本地与远程 schema 都支持。相对本地路径会按配置文件所在目录解析;如果配置来自
stdin/内联文本,则回退到当前工作目录。对于 JSON 配置,根级 $schema
只作为元数据使用,会在内存中的 defaults
里剥离,避免编辑器提示字段污染最终校验与输出。
远程 http(s) schema 加载只存在于 schemaui-cli,并且 CLI 默认开启
remote-schema feature;如果你希望二进制只保留本地能力,可以关闭它。 schemaui
这个库默认不会开启任何远程 schema 加载能力。
两者的默认 feature 按使用场景刻意分开:
schemaui-cli 默认走“开箱即用”路径:TUI + Web + 远程 schema 加载都开启。schemaui 作为库默认开 tui + json,这样保留最基础的 JSON
能力,同时不默认引入 Web 与联网相关能力。json、yaml、toml 都是真正落在代码路径上的 feature
gate;三者不能全关,否则会直接给出清晰的编译期错误。参考:
$schema:https://json-schema.org/understanding-json-schema/reference/schema#:schema
指令:https://taplo.tamasfe.dev/configuration/directives.html[dependencies]
schemaui = "0.12.2"
serde_json = "1"
use anyhow::Result;
use schemaui::prelude::*;
use serde_json::json;
fn main() -> Result<()> {
let schema = json!({
"$schema": "http://json-schema.org/draft-07/schema# ",
"title": "服务运行时",
"type": "object",
"properties": {
"metadata": {
"type": "object",
"properties": {
"serviceName": {"type": "string"},
"environment": {
"type": "string",
"enum": ["dev", "staging", "prod"]
}
},
"required": ["serviceName"]
},
"runtime": {
"type": "object",
"properties": {
"http": {
"type": "object",
"properties": {
"host": {"type": "string", "default": "0.0.0.0"},
"port": {"type": "integer", "minimum": 1024, "maximum": 65535}
}
}
}
}
},
"required": ["metadata", "runtime"]
});
let config = serde_json::json!({
"metadata": { "name": "demo-service" },
"runtime": { "http": { "host": "127.0.0.1", "port": 8080 } }
});
let value = SchemaUI::new(config)
.with_schema(schema)
.with_title("SchemaUI 演示")
.with_description("基于现有配置和校验 schema 进行编辑")
.run(FrontendOptions::Tui(UiOptions::default()))?;
println!("{}", serde_json::to_string_pretty(&value)?);
Ok(())
}
在作为库集成 schemaui 时,主要的入口包括:
SchemaUI、DocumentInput、FrontendOptions、
ServeOptions、UiOptionscrate::tui::session::TuiFrontend(适合通过
SchemaUI::run_with_frontend 注入自定义前端)crate::tui::state::*(例如
FormState、FormCommand、FormEngine、SectionState 等)crate::ui_ast::build_ui_ast 配合
crate::tui::model::form_schema_from_ui_ast(先生成规范 UI AST,再派生
FormSchema)┌─────────────┐ 解析/合并 ┌──────────────┐ 布局+类型 ┌───────────────┐
│ io::input ├────────────────▶│ schema ├────────────────────▶│ tui::state │
└─────────────┘ │ (loader/ │ │ (FormState, │
│ resolver/ │ │ sections, │
┌─────────────┐ 输出值 │ build_form_ │ FormSchema │ reducers) │
│ io::output ◀─────────────────┴────pipeline──┘ └────────┬──────┘
└─────────────┘ 焦点/编辑 │
│
┌──────▼──────────┐
│ tui::app::runtime │
│ (输入路由器, │
│ 覆盖层, 状态) │
└──────┬──────────┘
│ 绘制
┌──────▼──────────┐
│ tui::view::* │
│ (ratatui 视图) │
└─────────────────┘
此布局反映了src/下的实际模块,便于将任何代码更改映射到其架构责任。
io::input::parse_document_str将
JSON/YAML/TOML(通过serde_json、serde_yaml、toml)转换为serde_json::Value。功能标志(json、yaml、toml)不仅控制依赖项,也会真实控制DocumentFormat的解析与探测路径。schema_from_data_value/str从活动配置中推断模式,注入草稿 -07
元数据和默认值,以便 UI 加载现有值。schema_with_defaults将规范模式与用户数据合并,通过properties、patternProperties、additionalProperties、dependencies、dependentSchemas、数组和$ref目标传播默认值,而不修改原始树。io::output::OutputOptions封装了序列化格式、美观/紧凑切换以及OutputDestination::{Stdout, File}的向量。支持多个目标;冲突在输出前被捕获。OutputOptions::render 负责把最终的 serde_json::Value 渲染成 JSON/YAML/TOML
文本,OutputOptions::write 则在 SchemaUI::run* 返回后显式输出到 stdout /
文件。build_ui_ast 先把解析后的模式规范化为 UI AST,再由 form_schema_from_ui_ast
将每个子树映射为 FormSection/FieldSchema:
| 模式功能 | 结果控件 |
|---|---|
type: string, integer, number |
带有数值保护的内联文本编辑器 |
type: boolean |
切换/复选框 |
enum |
弹出选择器(单选或多选用于数组枚举) |
| 数组 | 内联列表摘要 + 每个项目的覆盖层编辑器 |
patternProperties, propertyNames, additionalProperties |
带有模式支持验证的键值编辑器 |
$ref, definitions |
在布局前解析;被视为内联模式 |
oneOf / anyOf |
变体选择器 + 覆盖层表单,将非活动变体排除在最终负载之外 |
根对象生成标签;嵌套对象成为带有面包屑标题的部分。每个字段记录其 JSON
指针(例如/runtime/http/port),以便焦点管理和验证可以精确映射错误。
jsonschema::validator_for在SchemaUI::run开始时编译完整模式一次。FormCommand::FieldEdited。FormEngine通过FormState::try_build_value重建当前文档,运行验证器,并将错误反馈到FieldState或全局状态行。┌─────────────┐ 解析模式 ┌───────────────────────────────┐ 膨胀状态 ┌────────────┐
│ SchemaUI::run├──────────▶│ form_schema_from_ui_ast ├───────────────▶│ FormState │
└─────┬───────┘ │ (tui::model::FormSchema) │ └──────┬─────┘
│ validator_for() └───────────────────────────────┘ 编辑 │
│ ┌──────▼─────────┐
└────────────────────────────────────────────────────── ▶│ app::runtime │
│ (状态, 输入) │
└──────┬─────────┘
│ FormCommand
┌──────▼──────────┐
│ FormEngine │
│ + jsonschema │
└─────────────────┘
App是FormState的唯一所有者;即使是覆盖层编辑也会通过FormEngine流动,以保持验证规则集中。
keymap/default.keymap.json列出了每个快捷键(上下文、组合键、动作)。app::keymap::keymap_source!()宏将此文件拉入二进制文件中,InputRouter使用它对KeyEvent进行分类,运行时页脚从相同的数据中呈现帮助文本——保持文档和行为
DRY。Ctrl+J / Ctrl+L(根)和Ctrl+Tab / Ctrl+Shift+Tab(部分)循环。普通Tab/Shift+Tab在各个字段之间移动。Enter键打开枚举/oneOf
选择器的弹出窗口;Ctrl+E打开复合编辑器的全屏覆盖层。覆盖层暴露集合快捷键(Ctrl+N、Ctrl+D、Ctrl+←/→、Ctrl+↑/↓)以及Ctrl+S提交。| 快捷键 | 动作 | 类型 |
|---|---|---|
Tab / Down |
下一个字段 | 命令 |
BackTab / Up |
上一个字段 | 命令 |
Ctrl+Tab |
下一个分区 | 命令 |
Ctrl+Shift+Tab |
上一个分区 | 命令 |
Ctrl+L |
下一个根标签 | 命令 |
Ctrl+J |
上一个根标签 | 命令 |
Enter |
打开弹窗 / 应用选择 | 命令 |
Ctrl+E |
打开复合编辑器 | 命令 |
Ctrl+S |
保存并验证(覆盖层保持打开) | 命令 |
Ctrl+Q / Ctrl+C |
退出(脏状态需确认) | 命令 |
Esc |
取消 / 清除状态(覆盖层:弹出当前层) | 命令 |
Ctrl+? / Ctrl+H |
显示帮助与错误摘要 | 命令 |
| 快捷键 | 动作 | 类型 |
|---|---|---|
Ctrl+E |
打开复合编辑器 | 命令 |
Ctrl+N |
添加条目 | 命令 |
Ctrl+D |
删除条目 | 命令 |
Ctrl+Left |
选择上一个条目 | 命令 |
Ctrl+Right |
选择下一个条目 | 命令 |
Ctrl+Up |
条目上移 | 命令 |
Ctrl+Down |
条目下移 | 命令 |
Ctrl+? / Ctrl+H |
显示帮助与错误摘要 | 命令 |
| 快捷键 | 动作 | 类型 |
|---|---|---|
Tab / Down |
下一个字段 | 命令 |
BackTab / Up |
上一个字段 | 命令 |
Ctrl+N |
添加条目 | 命令 |
Ctrl+D |
删除条目 | 命令 |
Ctrl+Left |
选择上一个条目 | 命令 |
Ctrl+Right |
选择下一个条目 | 命令 |
Ctrl+Up |
条目上移 | 命令 |
Ctrl+Down |
条目下移 | 命令 |
Ctrl+S |
保存并验证(覆盖层保持打开) | 命令 |
Esc |
取消 / 清除状态(覆盖层:弹出当前层) | 命令 |
Ctrl+? / Ctrl+H |
显示帮助与错误摘要 | 命令 |
| 快捷键 | 动作 | 类型 |
|---|---|---|
Esc |
关闭弹窗 | 命令 |
Up |
选择上一个弹窗选项 | 命令 |
Down |
选择下一个弹窗选项 | 命令 |
Space |
切换弹窗选项 | 命令 |
Enter |
应用弹窗选择 | 命令 |
| 快捷键 | 动作 | 类型 |
|---|---|---|
Esc / Ctrl+H / Ctrl+? |
关闭帮助 | 命令 |
Tab |
下一页错误 | 命令 |
BackTab |
上一页错误 | 命令 |
$ claude mcp add schemaui \
-- python -m otcore.mcp_server <graph>