LangGenius Internal

CLI 交互设计系统

Mesh CLI 的交互设计远不止"能用"——它追求让每一次终端交互都有温度、有智慧、有效率。本文档完整记录了这套设计系统的理念、模式与实现。

目录

  1. 设计原则
  2. 登录欢迎体验
  3. 命令架构
  4. 帮助与纠错
  5. 交互式引导
  6. 勋章与庆祝
  7. 输出系统
  8. 信号与优雅退出
  9. Shell 补全
  10. AI Agent 适配

01 — 设计原则

Mesh CLI 的交互设计基于四个核心原则。每个功能在实现前都会先问:它是否符合这些原则?

🤝

友好有温度

CLI 不应该冰冷。每天不同的问候语、登录时的 ASCII 艺术、勋章通知——让终端也有人情味。

🧠

智能不打扰

拼错命令会自动建议,缺少参数会交互引导,token 过期会静默刷新——帮你纠正而不是报错。

无障碍兼容

尊重 NO_COLOR 标准,非 TTY 自动降级,--no-fun 关闭装饰输出——在任何环境都可用。

🤖

Agent 原生

所有命令支持 --format json,结构化输出让 AI Agent 能直接解析——人和机器共用一套接口。

02 — 登录欢迎体验

登录是用户与 CLI 的第一次深度接触。我们把它设计成一个有仪式感的时刻。

ASCII 艺术横幅

登录成功后展示双色渐变的 ASCII 横幅。上半部分 "CYBER" 使用蓝紫色渐变(6 行 6 色),下半部分 "POPS" 使用橙金色渐变(6 行 6 色),每行独立着色,形成视觉纵深。

mesh login
██████╗██╗ ██╗██████╗ ███████╗██████╗ ██╔════╝╚██╗ ██╔╝██╔══██╗██╔════╝██╔══██╗ ██║ ╚████╔╝ ██████╔╝█████╗ ██████╔╝ ██║ ╚██╔╝ ██╔══██╗██╔══╝ ██╔══██╗ ╚██████╗ ██║ ██████╔╝███████╗██║ ██║ ╚═════╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ██████╗ ██████╗ ██████╗ ███████╗ ██╔══██╗██╔═══██╗██╔══██╗██╔════╝ ██████╔╝██║ ██║██████╔╝███████╗ ██╔═══╝ ██║ ██║██╔═══╝ ╚════██║ ██║ ╚██████╔╝██║ ███████║ ╚═╝ ╚═════╝ ╚═╝ ╚══════╝ Welcome back, Luyu Zhang! 👋 Role: ADMIN | LangGenius, Inc. Employee Number: LG-0001 Badges: 5 🏅 You received a new badge: Founding Member ⚠️ 2 sync warnings pending (mesh sync warnings) Credentials saved to: ~/.mesh/credentials.json

每日问候语

问候语不是随机的——基于日期 + 用户名的确定性哈希,同一个人同一天永远看到相同的问候,但不同人看到不同的问候。这避免了"每次刷新都变"的廉价感。

function pickDailyGreeting(displayName: string): string {
  const greetings = [
    "Good morning", "Hello", "Welcome back",
    "Hope you're having a smooth day", "Ready when you are",
  ];
  const seed = `${new Date().toISOString().slice(0, 10)}:${displayName}`;
  const hash = [...seed].reduce((t, c) => t + c.charCodeAt(0), 0);
  return `${greetings[hash % greetings.length]}, ${displayName}.`;
}

角色感知提醒

登录后根据用户角色显示不同的提醒信息。VIEWER 看到个人资料完善提示,EDITOR/ADMIN 看到系统级待办。

Viewer 看到的
📝 Your profile is incomplete: ○ Missing phone number ○ No IM account set
Admin 看到的
⚠️ 2 sync warnings pending (mesh sync warnings) ⚠️ 5 employees have incomplete data ⚠️ 3 org consistency issues (mesh audit consistency)

--no-fun 模式

传入 --no-fun 标志后,所有 ASCII 艺术和颜色装饰被关闭,输出纯文本格式。适用于脚本环境、日志采集和无障碍场景。

mesh login --no-fun
Logged in as luyu@langgenius.ai Role: ADMIN Employee Number: LG-0001 Badges: 5 🏅 You received a new badge: Founding Member Credentials: ~/.mesh/credentials.json

03 — 命令架构

Mesh CLI 采用 verb-first(动词优先)命令结构,灵感来自 kubectl 和 docker,让操作意图先于资源类型。

命令语法

mesh <verb> <resource> [ref] [flags]
$ mesh get employee luyu@langgenius.ai $ mesh list employees --dept backend --format json $ mesh update employee luyu@langgenius.ai --display-name "Luyu" $ mesh create badge --name "Ship It" --design 27

兼容入口

对外主推 verb-first 写法;resource-first 仅作为兼容入口保留,内部通过 normalizeVerbFirstArgs() 统一转换。

Preferred
mesh get employee luyu
Compatibility alias
mesh employee get luyu

命令分类

类别动词说明
查询get list org-chart team只读操作,任何角色可用
自助服务update add set remove修改自己的资料、电话、IM
管理写入create update closeEDITOR+ 管理组织数据
系统管理sync audit import adminADMIN 专属操作
认证login logout whoami status身份与会话管理

04 — 帮助与纠错

好的 CLI 不会让用户在犯错后无所适从。Mesh 通过 Levenshtein 距离算法、上下文感知帮助和可操作的错误信息,构建了一套完整的纠错系统。

拼写纠错

输入错误的命令时,CLI 使用 Levenshtein 编辑距离算法在所有已注册命令中搜索最接近的匹配。阈值自适应:max(2, floor(input.length / 3))

拼写纠错演示
$ mesh empolyee get luyu Unknown command: empolyee Did you mean: employee? $ mesh get employe luyu Unknown resource: employe Did you mean: employee?
function suggestCommand(token: string, candidates: string[]) {
  let best = null;
  for (const c of candidates) {
    const d = levenshtein(token, c);
    if (!best || d < best.distance) best = { value: c, distance: d };
  }
  const threshold = Math.max(2, Math.floor(token.length / 3));
  return best?.distance <= threshold ? best.value : null;
}

上下文帮助

mesh help 显示分类概览,mesh help <command> 显示具体命令的用法、参数和示例。裸运行 mesh 则显示当前状态和下一步建议。

mesh(无参数运行)
Luyu Zhang (admin) · luyu@langgenius.ai · 🏅 5 badges ⚠️ 2 sync warnings pending (mesh sync warnings) ⬆️ Update available: mesh 0.1.0 → 0.2.0 Available next steps: mesh whoami Show your profile mesh badges View your badges mesh help Full command reference

错误信息设计

每个错误都包含三要素:错误码、人类可读描述、可操作的建议。API 错误还附带 Request ID 用于追查。

$ mesh get employee nonexistent@foo.com NOT_FOUND: Employee not found (request req_a1b2c3) $ mesh list employees Not logged in. Run `mesh login` first. $ mesh admin set-role john@langgenius.ai --role editor FORBIDDEN: Requires ADMIN role (request req_d4e5f6)

05 — 交互式引导

当命令缺少必要参数时,CLI 不会直接报错退出,而是进入交互式引导模式,逐步询问缺失信息。

智能参数补全

只在交互式终端(TTY)中触发提示;管道输入和 --format json 模式下直接跳过,避免阻塞自动化流程。

交互式创建部门
$ mesh create dept Department name: Backend Infrastructure Parent department (optional): Engineering Description (optional): Created department: Backend Infrastructure (dept_abc123)

声明式提示注册

写命令的交互提示通过声明式注册定义,将提示文案、是否可选、默认值等元数据集中管理:

// write-command-registry.ts
{
  name: "create",
  summary: "Create employment record",
  prompts: {
    reference: { message: "Employee (email / employee number)" },
    entity:    { message: "Legal entity" },
    type:      { message: "Employment type" },
    start:     { message: "Start date (YYYY-MM-DD)" },
    office:    { message: "Office (optional)", optional: true },
    title:     { message: "Job title (optional)", optional: true },
  },
}

危险操作确认

Offboard、reinstate 等不可逆操作使用 typed-reference 确认策略——用户必须手动输入目标员工的邮箱才能执行,杜绝误操作。

危险操作确认
$ mesh offboard john@langgenius.ai Offboard preview: Employee: John Doe (john@langgenius.ai) Direct reports: 0 Active employments: 1 Badges: 3 (will be preserved) ⚠️ Type "john@langgenius.ai" to confirm: > john@langgenius.ai Employee offboarded successfully.
设计决策:为什么不用 y/n 确认?因为 y 太容易按下。typed-reference 强制用户阅读操作对象并手动确认,将误操作概率从"手滑按回车"降低到"主动输入错误目标"。在非 TTY 环境中,直接抛出错误要求重新以交互方式运行。

06 — 勋章与庆祝

勋章系统为 CLI 注入了游戏化元素。每枚勋章都有独特的 ASCII 艺术和配色方案,登录时自动通知新获得的勋章。

勋章 ASCII 艺术

每枚勋章包含 5 行 ASCII 艺术和 5 个对应的颜色值,每行独立着色。80 枚内置设计覆盖了工龄纪念、技术成就、文化认可等多个类别。

勋章通知机制

credentials 文件中记录 last_badge_seen_at 时间戳。每次登录时,CLI 比对最新勋章的颁发时间,若有新勋章则在欢迎横幅中高亮展示。

🏅 You received a new badge: Founding Member Badges: 5

生日与周年庆祝

mesh celebrations 显示本周和即将到来的团队庆祝日,包括生日和入职周年。让远程团队不再错过同事的重要时刻。

mesh celebrations
🎂 Birthdays this week: 04/07 Alice Wang <alice@langgenius.ai> 04/09 Bob Chen <bob@langgenius.ai> 🎉 Work anniversaries this week: 04/08 Carol Li — 2 years <carol@langgenius.ai> Upcoming: 04/14 🎂 David Zhou 04/15 🎉 Eve Zhang — 1 year 04/20 🎂 Frank Wu

07 — 输出系统

CLI 的输出系统在视觉美观和机器可读之间取得平衡,支持多种输出格式和颜色模式。

表格格式化

默认输出使用自动计算列宽的 ASCII 表格。列间距 2 空格,空数据显示 "(none)" 占位。简洁清晰,无多余的边框线。

mesh list employees --dept backend
NAME EMP# EMAIL DEPARTMENT TYPE Luyu Zhang LG-0001 luyu@langgenius.ai Backend Full Time Alice Wang LG-0012 alice@langgenius.ai Backend Full Time Bob Chen LG-0023 bob@langgenius.ai Backend Intern

True Color 颜色系统

使用 24-bit True Color ANSI 转义码(\x1B[38;2;R;G;Bm),不依赖终端的 256 色调色板限制。支持从 hex 值直接转换:

function trueColor(r: number, g: number, b: number): string {
  return `\x1B[38;2;${r};${g};${b}m`;
}

function colorize(...codes: string[]) {
  if (!colorOutputEnabled) return (v) => v;  // graceful degradation
  const prefix = codes.join("");
  return (v) => `${prefix}${v}\x1B[0m`;
}

颜色降级策略

条件行为场景
process.stdout.isTTYTrue Color 全彩输出正常终端使用
NO_COLOR=1关闭所有颜色遵循 no-color.org 标准
非 TTY(管道)自动关闭颜色mesh list | grep
--no-fun关闭 ASCII 艺术和装饰脚本环境

08 — 信号与优雅退出

CLI 需要正确处理中断信号。Mesh 实现了两级退出策略,确保数据完整性。

两级 Ctrl-C 策略

第一次 Ctrl-C

设置中断标志,运行注册的清理函数(逆序执行),然后优雅退出。

第二次 Ctrl-C

跳过所有清理,立即强制退出,返回退出码 130。

信号处理演示
$ mesh sync google Syncing with Google Workspace... ^C Interrupted. Cleaning up... (running cleanup handlers) ^C Force exiting immediately.
// signal-handling.ts
const onSigint = () => {
  interruptCount += 1;

  if (interruptCount === 1) {
    interrupted = true;
    io.stderr("\nInterrupted. Cleaning up...\n");
    cleanupPromise ??= runCleanup();  // run handlers in reverse order
    return;
  }

  io.stderr("Force exiting immediately.\n");
  process.exit(130);
};

09 — Shell 补全

通过 mesh completion --shell zsh 生成 Shell 自动补全脚本,实现 Tab 键补全命令名、子命令和标志。

安装 Shell 补全
# Zsh $ mesh completion --shell zsh >> ~/.zshrc $ source ~/.zshrc # Bash $ mesh completion --shell bash >> ~/.bashrc $ source ~/.bashrc
补全效果
$ mesh [TAB] get list create update add remove set close login logout whoami status org-chart team badges celebrations audit sync import admin accesskey help completion $ mesh get [TAB] employee dept project entity office $ mesh list employees [TAB] --dept --role --format --include --active

10 — AI Agent 适配

Mesh CLI 是 Agent-native 的——所有命令都支持 JSON 输出,让 AI Agent 能直接调用 CLI 作为工具。

JSON 输出模式

任何命令加上 --format json 即可获得结构化 JSON 输出,适合程序解析。JSON 模式下自动跳过交互提示和颜色输出。

Agent 模式
$ mesh whoami --format json { "email": "luyu@langgenius.ai", "role": "ADMIN", "displayName": "Luyu Zhang", "employeeNumber": "LG-0001", "department": "Engineering" } $ mesh list employees --format json | jq '.[].email' "luyu@langgenius.ai" "alice@langgenius.ai" "bob@langgenius.ai"

SKILL.md — AI Agent 能力声明

CLI 附带 SKILL.md 文件,以 LLM 可理解的格式描述自身能力。AI Agent 可以通过阅读此文件了解可用命令、参数和使用模式,无需人工配置。

设计理念:人用 mesh help,AI 读 SKILL.md。同一套 CLI 同时服务人类和 Agent,而不是为两者分别构建接口。这是 "Agent-native" 的核心思想。

总结

Mesh CLI 的交互设计证明了一件事:终端工具也可以是温暖的。

通过 ASCII 艺术与渐变色彩创造仪式感,通过 Levenshtein 纠错和交互引导降低门槛,通过 typed-reference 确认和两级退出保障安全,通过 JSON 输出和 SKILL.md 打通人机协作——这些设计模式共同构成了一套可复用的 CLI 交互设计系统。

它不是某个框架的产物,而是对"CLI 应该如何对待使用者"这个问题的回答。