Star CLI:实现简单的Agent CLI

Star CLI 是一个用 TypeScript 编写的开源 AI agent 命令行工具。这篇文章聊聊它的设计架构、功能全貌和模块划分。

功能一览

对话与模型

  • 流式 REPL,带 thinking spinner 和推理过程的暗色预览
  • 多 provider 接入:OpenAI 兼容协议、Anthropic、OpenAI Responses,自选 baseURL,天然适配各种中转站
  • @file 提及:在 prompt 里 @src/main.ts 即把文件内容注入上下文
  • /compact 上下文压缩(可选 LLM 摘要)、token 用量与美元成本估算

工具能力

  • 文件:read_file / write_file / edit_file / glob / grep(后两者自实现,零依赖)
  • 执行:bash(支持后台任务)、web_fetch / web_search(DuckDuckGo,免 API key)
  • 规划:todo_read / todo_write 任务清单
  • subagent:把聚焦的子任务委派给独立的子 agent 执行,拿回一份自包含的报告,主对话保持干净

安全与控制

  • 五档权限模式:ask(默认)/ auto / readonly / yolo / plan
  • 硬性安全规则:危险命令、工作目录外的路径、.env 等敏感文件,任何白名单都无法覆盖
  • 权限确认时展示彩色 diff 预览,按 a 永久放行同类操作(写入配置文件)
  • plan 模式:只读研究 → 生成计划 → 你批准后才动手
  • /undo:一键撤销上一轮对话的文件改动和消息

会话与工程化

  • 会话自动持久化,/resumestar -r 恢复;崩溃中断的会话也能自愈
  • !cmd shell 直通、自定义 slash 命令(Markdown 即 prompt 模板)
  • /init 扫描项目生成 AGENTS.md,/doctor 环境体检,/export 导出 Markdown
  • --json NDJSON 事件流输出,方便脚本集成

架构设计

整体是清晰的分层结构,层与层之间靠两个”契约”解耦:

入口层   main.tsx —— commander 参数解析,分发到 REPL 或 print 模式
   │
 UI 层   cli/ —— Ink/React 终端界面,slash 命令体系
   │         通过 ChatBackend 接口与 agent 解耦(UI 可独立测试)
   │
 核心层  agent/ —— AgentLoop 主循环:多步工具调用、权限闸、压缩、持久化
   │         通过 StreamEvent 事件流向上汇报(文本/推理/工具调用/结果/完成/错误)
   │
 能力层  tools/(13+ 个工具)+ permissions/(纯函数权限门)+ tasks/(后台任务)
   │
 基础层  llm/(模型接入与流式封装)+ config/(TOML+zod 配置)+ session/(JSONL 持久化)
        + context/(token 估算与压缩)+ core/(共享类型)

几个值得一提的设计选择:

事件流是唯一的汇报通道。 Agent 主循环是一个 AsyncGenerator,模型文本、推理过程、工具调用、工具结果都以统一的 StreamEvent 吐出。REPL 把它渲染成卡片和流式文本;print 模式把它序列化成 NDJSON;subagent 把它聚合成一份报告。同一条流水线,三种消费方式。

UI 与 agent 解耦。 REPL 面对的是 ChatBackend 接口而非具体实现,测试里可以用一个逐词回吐的假后端驱动整个界面。

权限是两层防线。 每个工具声明自己的级别(读/写/执行),纯函数权限门按”模式 × 级别”矩阵裁决;plan 模式下写工具干脆不发给模型——模型看不到,权限门再兜底。

一切皆可降级。 LLM 摘要失败就退回纯截断,diff 预览失败就退回参数摘要,更新检查失败就当没发生过。辅助功能永远不该阻塞主流程。

subagent 是递归的 AgentLoop。 子代理不是什么特殊机制,就是一个不注册 subagent 工具、不写会话文件的子 AgentLoop——深度限制物理上不可能被突破,主 agent 收到的只是一次普通的工具调用结果。

模块速览

模块 职责
src/core/ 共享类型与对话历史修复算法
src/config/ zod schema、TOML 三级加载链(全局→项目→CLI)、密钥解析
src/llm/ Vercel AI SDK provider 工厂 + 带空闲看门狗的流式封装
src/agent/ 主循环 + subagent 子代理
src/tools/ 工具接口、注册表、全部内置工具、文件快照(/undo 的基础)
src/permissions/ 权限模式、硬安全规则、”始终允许”白名单
src/tasks/ 后台 shell 任务管理器
src/session/ JSONL 会话持久化与恢复
src/context/ token 估算与上下文压缩
src/cli/ Ink REPL 的全部组件、slash 命令、@file、diff 预览

结语

目前初步版本整体代码5000+行左右,它的设计哲学可以概括为——简单分层、事件驱动、安全默认、优雅降级

  • 仓库:https://github.com/cryer/star-cli
  • 安装:npm install -g @cryer/star-cli