用 React + Ink 在终端里「优雅搜索」:开源 CLI 设计与非交互模式实践

用 React + Ink 在终端里「优雅搜索」:开源 CLI 设计与非交互模式实践

适合:喜欢命令行、想写 Node CLI、或对「终端 UI + 脚本化输出」感兴趣的前端 / Node 开发者。

仓库:bot-cli · npm 包名:search-bot-cli · 全局命令:bot-cli


一、为什么要做这样一个工具

日常开发里,「打开浏览器 → 搜索 → 点开几条结果」路径很短,但在以下场景里,纯终端反而更顺手:

  • SSH 到远端、或本机就想少切一次窗口;
  • 希望结果列表结构化展示,而不是浏览器里一堆广告与折叠;
  • 想把「搜索」接进自己的脚本、CI,甚至 AI Agent 的 tool 调用里。

于是有了 search-bot-cli (命令行里叫 bot-cli):底层用 DuckDuckGo HTML 结果 拉取标题、链接与摘要,无需申请搜索 API Key;上层用 React + Ink 做交互式终端界面,并支持 JSON / 纯文本非交互输出,兼顾「人看」和「机器读」。


二、功能一览

能力 说明
免费搜索 基于 DuckDuckGo,不强制配置密钥即可搜索
交互 TUI 序号打开链接、剪贴板 + 默认浏览器联动
保存结果 /save/save json 导出到 output/ 目录
AI 摘要 /summary(可选,需 OpenAI 兼容 API 与 OPENAI_API_KEY
非交互模式 --output json / --output plain,适合管道与自动化

技术栈概览:TypeScript + Node 18+、Commander 14、Ink 7、React 19、Cheerio、clipboardy、open


三、安装:先认准包名与命令名

npm 上的包名是 search-bot-cli ,装好后在终端里执行的是 bot-cli 。若误装 npm install -g bot-cli,会装到 npm 上另一个同名包,与本文仓库无关。

bash 复制代码
npm install -g search-bot-cli

(公司私服、registry 不同步等环境差异,可到仓库 README 查看说明。)


四、使用方式速查

交互搜索(默认进入 Ink 界面):

bash 复制代码
bot-cli search "TypeScript"

非交互:只打印 JSON 后退出(脚本 / Agent 友好):

bash 复制代码
bot-cli search "Rust 异步" --output json
# 或简写
bot-cli search "关键词" -o plain

查看子命令与参数说明:

bash 复制代码
bot-cli --help
bot-cli search --help

交互模式下常用指令:1--10 打开对应结果,/save/save json/summary/clearCtrl+C 退出。默认 TUI 依赖真实终端;json / plain 模式不渲染 Ink,可无 TTY、可管道重定向。


五、实现思路(精简版)

5.1 CLI 入口:Commander 子命令 + 输出分流

search <keyword> 作为子命令;通过 -o, --output 在三种模式间切换:

  • interactive:拉取结果后 render(<SearchApp />)
  • json / plain:格式化写入 stdout 后直接结束进程,不进入 Ink。

这样同一套搜索逻辑既能服务「人类点选」,也能服务「机器解析」。

5.2 搜索层:HTTPS + Cheerio 解析 HTML

对 DuckDuckGo 的 HTML 端点发起请求,用 Cheerio 选择器抽取 titlelinksnippet,再截取前 N 条(当前为 10 条)。实现上注意 User-Agent、编码与页面结构变更带来的兼容风险------这是所有「爬 HTML」类工具的共同维护点。

5.3 交互层:Ink 里当 React 写

主界面在 SearchApp 中处理键盘输入、高亮、阶段状态(保存中、摘要生成中等),列表展示拆到 SearchResults;剪贴板、打开链接、写文件、调用兼容 OpenAI 的摘要接口则放在 utils/ 下,保持组件相对干净。


六、CLI 与 MCP:区别是什么,CLI 又好在哪里

Agent 要「动手」时,常见两条路:让模型生成并执行终端命令(CLI) ,或 通过 MCP(Model Context Protocol)把外部能力注册成结构化工具 。二者不是非此即彼,但取舍差异很大;下面把概念对齐,并说明在什么情况下 CLI 往往更划算 (也与本文 bot-cli --output json 的设计一致)。

6.1 各自是什么(一句话)

  • CLI(命令行接口) :本机或 CI 上的可执行程序,用参数、环境变量、stdin/stdout 交互;输出可以是人类可读文本,也可以是 JSON 等机器可读格式 ,便于管道(|)和脚本拼接。
  • MCP :以 JSON-RPC 为主的协议,在 Host(如 IDE)MCP Server 之间约定资源(Resources)、工具(Tools)、提示(Prompts)等;模型通过协议 发现 工具名与参数 schema,由 Host 代为调用。

MCP 由 Anthropic 在 2024 年提出后,已被多家 IDE / Agent 平台接入,用于把「数据库、文档、内部 API」等以统一形态挂到 AI 侧------这是它的主战场:标准化连接与权限边界

6.2 核心差异(怎么接、成本从哪来)

维度 CLI MCP
调用形态 一次(或多次)进程:命令 + 参数,stdout 即结果 常驻或按需连接:工具列表、schema、调用走协议消息
与 shell / CI 天然契合:&&、管道、重定向、Cron / Pipeline 通常由 Host 管理连接,较少手写 shell 编排
上下文占用 多数场景下模型只需 当前这一条命令(和必要说明) 连接或枚举工具时,易把 大量 tool 定义 带入上下文(「schema 膨胀」是社区常讨论的点)
调试体验 把同一条命令复制到终端重跑,报错栈与退出码一目了然 排障依赖 Host 日志与协议层,对人更像「黑盒」一步

社区与厂商文章里常提到:在 Token / 成本可组合性 上,CLI 往往更轻;在 多系统集成、OAuth、企业审计与统一治理 上,MCP 更易做成产品线能力(例如 CircleCI 对 MCP 与 CLI 的对比Firecrawl 的 Agent 场景选型)。具体倍数因任务与实现而异,不必迷信单一数字,但 「协议 + 全量 schema」带来的上下文压力 是结构性差异。

6.3 CLI 相对 MCP 更「占优」的典型场景

结合日常开发与本文工具特性,CLI 更值得优先的情况包括:

  1. 脚本化与管道 :搜索、格式化、再喂给下一步(bot-cli ... \| jq ...),与 Unix 哲学一致;MCP 更偏「IDE 内一站式」,而不是 shell 组合。
  2. 调试与可重现:同一命令可脱离 Agent 单独执行,便于定位是模型指令错了还是环境/网络问题(这也是许多团队仍保留「CLI 作为真相来源」的原因)。
  3. 非交互、机器可读输出 :例如 --output json,Agent 只需约定少量 flag,而不必在上下文里长期挂载一整套 MCP tool 描述。
  4. 内循环(inner loop):个人本机、小团队、原型阶段------上线快、依赖少,不必先搭 MCP Server 与 Host 配置。
  5. 模型对「命令」的先验强 :训练数据里终端与常见 CLI(gitcurlkubectl 等)密度高,短命令 + 明确 stdout 契约 往往比塞一长段 schema 更省对话轮次与上下文。

业内也有「CLI is the new API」的说法:产品暴露稳定 CLI,比强迫每个集成方都实现 MCP Server 更容易被自动化与 Agent 消费------与本仓库「搜索能力 CLI 化 + JSON 模式」是同一思路。

6.4 MCP 仍然更合适时(避免误读成「否定 MCP」)

在需要 统一鉴权(如 OAuth)多租户审计跨应用实时拉取结构化资源 、或 IDE 深度集成工具发现 时,MCP 的工程化收益明显。生态上也在缓解 token 压力:例如 按需加载工具 、网关聚合、以及「把部分能力仍以子进程 CLI 落地」的混合架构------CLI 与 MCP 叠用 在 Cursor、Claude Code 等产品线里已很常见。

6.5 和本文项目的关系

search-bot-cli 选择 CLI + 可选 JSON 输出 ,本质是:用最小协议面(argv + stdout)服务人与 Agent,避免为了一次搜索在上下文里常驻大段工具定义;若未来要做「在 IDE 里一键搜 + 带鉴权的私有索引」,再考虑 MCP 或混合方案会更自然。


七、小结

  • 终端 + React 并不是噱头:Ink 把状态、输入循环和布局表达得很接近前端日常经验,适合快速做出可用的 TUI。
  • --output json 把同一能力开放给自动化与 AI 工具链,和「把能力做成 CLI 给 Agent 调用」的方向一致。
  • CLI 与 MCP:简单可组合、低上下文契约的任务,CLI 往往更直接;复杂多源治理与 IDE 级集成,MCP 更对口------可按场景组合,而非二选一。
  • 安装时认准:包名 search-bot-cli,命令 bot-cli

若你对实现细节、DuckDuckGo 解析健壮性等话题感兴趣,欢迎在仓库提 Issue / 交流。


仓库地址: github.com/chenjiaobin...

相关推荐
SameX1 小时前
后台 GPS 记录从半天掉电 30% 到全天 8%,我的三版方案演进
前端
像我这样帅的人丶你还1 小时前
前端监控体系与实践(二):全局监控
前端·javascript·vue.js
颜酱1 小时前
LLM为核,上下文为限:拆解AI Agent生态的底层逻辑
前端·人工智能
前端那点事1 小时前
Vue3 超全复盘!30+前端高频核心知识点(开发+面试全覆盖)
前端·vue.js
熊猫钓鱼>_>1 小时前
当“虾”遇上“马”:QClaw 融合 Hermes 背后的智能体进化论
人工智能·ai·腾讯云·agent·openclaw·qclaw·hermes
幼儿园技术家2 小时前
为什么 SSR 一定会有 hydration mismatch?
前端
FlyWIHTSKY2 小时前
Vue 3 中 RouteRecord 详解(Vue Router 4)
前端·javascript·vue.js
yingyima2 小时前
用 cron 定时发送邮件报告:实战案例详解
前端
GAMC2 小时前
从 “凭感觉写代码” 到 “按规范做开发”:OpenSpec 让 AI 编程回归工程化
前端·人工智能