claude-mem 动画式安装器设计与实现:基于 @clack/prompts 的交互式 CLI 安装向导
2026/9/7 16:58:30 网站建设 项目流程

claude-mem 动画式安装器设计与实现:基于 @clack/prompts 的交互式 CLI 安装向导

【免费下载链接】claude-memPersistent Context Across Sessions for Every Agent – Captures everything your agent does during sessions, compresses it with AI, and injects relevant context back into future sessions. Works with Claude Code, OpenClaw, Codex, Gemini, Hermes, Copilot, OpenCode + More项目地址: https://gitcode.com/GitHub_Trending/cl/claude-mem

claude-mem 的核心使用门槛在于:用户需要手动克隆仓库、构建插件、配置settings.json、再单独启动 worker 服务。animated-installer 计划文档给出了一套完整方案:用@clack/prompts构建一个带动画效果的 CLI 安装向导,通过npxcurl | bash两种分发方式一键完成全部流程。本文以该计划文档为主线,逐阶段还原其 API 选型、工程结构与验证标准,并对照仓库中已落地的 npx CLI 实现 与 运行时准备逻辑,讲解这套安装器从设计到源码的实际形态。读完本文,你可以掌握交互式 CLI 安装器的 API 用法边界、TTY 防护、依赖自检与 worker 健康检查等关键工程实践。

一、计划目标与两种分发形态

计划文档的 Overview 明确了两条分发路径:

  • npx 分发npx claude-mem-installer(计划阶段的包名;仓库最终实现为npx claude-mem install),package.jsonbin字段指向带 shebang 的dist/index.js
  • curl | bash 分发:Shell 引导脚本下载打包后的安装器 JS,直接用node script.js执行——关键是保留 TTY,因为@clack/prompts的交互式提示在管道输入下会无限挂起。

安装器的价值在于替代四个手动环节:clone 仓库、构建插件、配置设置、启动 worker。文档同时注明设计工作在独立 worktree(feat/animated-installer)中推进,主仓库只保留规划与最终实现。

二、Phase 0:@clack/prompts API 选型与反模式清单

计划文档把 API 选型作为 Phase 0,列出了 v1.0.1(ESM-only)下允许使用的 API 及其用途,这是理解后续每个步骤实现的基础:

API签名用途
intro(title?)void开场横幅
outro(message?)void完成消息
cancel(message?)void用户取消
isCancel(value)boolean判断用户是否按了 Ctrl+C
text(opts)Promise<string \| symbol>输入 API key、端口、数据目录
password(opts)Promise<string \| symbol>遮罩输入 API key
select(opts)Promise<Value \| symbol>选择 Provider、模型、认证方式
multiselect(opts)Promise<Value[] \| symbol>多选 IDE、观测类型
confirm(opts)Promise<boolean \| symbol>启用 Chroma、启动 worker
spinner()SpinnerResult安装依赖、构建、启动 worker 的动画
progress(opts)ProgressResult多步骤安装进度
tasks(tasks[])Promise<void>顺序执行安装步骤
group(prompts, opts)Promise<Results>链式提示并共享结果
note(message, title)void显示配置摘要、下一步
log.info/success/warn/error(msg)void状态消息
box(message, title, opts)void欢迎框、完成摘要框

反模式清单(Anti-Patterns)

计划文档特别列出六条必须规避的写法,每一条都对应一类真实的运行故障:

  1. 不要使用require()——@clack/prompts是 ESM-only;
  2. 不要未做 TTY 检查就调用提示——非 TTY 环境下会无限挂起;
  3. 每个 prompt 之后都要检查isCancel()(或使用带onCancelgroup());
  4. 不要引入chalk——统一用 clack 的依赖picocolors,保证颜色输出一致;
  5. text()没有数字模式——端口号必须手工做数值校验;
  6. spinner.stop()不接受状态码——失败场景要用spinner.error()

分发包的技术模式

  • npxbin字段指向./dist/index.js,产物首行需要#!/usr/bin/env node
  • curl | bash:引导脚本直接node script.js,不经 shell 中转,保住 TTY;
  • esbuild:打包成单文件 ESM,platform: 'node',用banner注入 shebang。

文档还给出了实现时应参考的 8 个关键源文件:SettingsDefaultsManager(默认设置 schema)、SettingsRoutes.ts(设置校验)、worker-service.ts(worker 启动)、HealthMonitor(健康检查)、plugin.json 与 marketplace.json(插件注册)、sync-marketplace.cjs(marketplace 同步)、CursorHooksInstaller(Cursor 集成)、openclaw.sh(既有安装脚本的逻辑参考)。

三、Phase 1:包结构、构建配置与验证标准

计划给出的目录结构按「步骤」与「工具」分层:

installer/ ├── src/ │ ├── index.ts # 入口,含 TTY 防护 │ ├── steps/ │ │ ├── welcome.ts # intro + 版本检查 │ │ ├── dependencies.ts # bun、uv、git 检查 │ │ ├── ide-selection.ts # IDE 选择 + 注册 │ │ ├── provider.ts # AI 供应商 + API key │ │ ├── settings.ts # 附加设置 │ │ ├── install.ts # 克隆、构建、注册插件 │ │ ├── worker.ts # 启动 worker + 健康检查 │ │ └── complete.ts # 摘要 + 下一步 │ └── utils/ │ ├── system.ts # OS 检测、命令执行 │ ├── dependencies.ts # bun/uv 安装辅助 │ └── settings-writer.ts # 写 ~/.claude-mem/settings.json ├── build.mjs # esbuild 配置 ├── package.json # bin、type: module、依赖 └── tsconfig.json

package.json的关键字段是type: "module"bin指向dist/index.jsengines.node >= 18build.mjs使用 esbuild 以format: 'esm'platform: 'node'target: 'node18'打包,banner 注入 shebang;tsconfig.json采用module: "ESNext"target: "ES2022"moduleResolution: "bundler"。验证标准三条:node build.mjs成功、产物带 shebang、空安装器也能运行。

仓库最终实现把这套结构落到了主包里:package.jsonbin"claude-mem": "./dist/npx-cli/index.js",运行时要求升级为"node": ">=20.12.0""bun": ">=1.0.0"(见 package.json)。值得注意的是 dependencies-note 的说明:@clack/prompts等库被 esbuild内联进 npx 包,属于构建期 devDependency,不会被消费该包的用户额外下载——这正是计划中「单文件 ESM 产物」模式的规模化版本,当前 package.json 中该依赖为^1.3.0

四、Phase 2:入口 TTY 防护与欢迎步骤

计划中src/index.ts的三个要点:

  1. TTY 防护!process.stdin.isTTY时打印错误并引导用户改用npx claude-mem-installerexit 1
  2. 导入并调用steps中的runInstaller()
  3. 顶层 catch 统一走p.cancel()并退出。

welcome.ts负责p.intro()(用 picocolors 加样式的标题)、版本号展示、已安装检测(探测~/.claude-mem/settings.json~/.claude/plugins/marketplaces/thedotmack/)、升级确认,以及 Fresh Install / Upgrade / Configure Only 三选一。system.ts提供四个基础工具:detectOS()commandExists()runCommand()(返回 stdout/stderr/exitCode)、expandHome()

仓库最终实现中,这一设计以 install.ts 的开头几行得到印证——交互性是全局一次性判定的,而非逐提示判断:

const isInteractive = process.stdin.isTTY === true; // src/npx-cli/commands/install.ts#L58 async function runTasks(tasks: TaskDescriptor[]): Promise<void> { if (isInteractive) { await p.tasks(tasks); } else { for (const t of tasks) { const result = await t.task((msg: string) => console.log(` ${msg}`)); console.log(` ${result}`); } } }

这里比计划更进一步:非 TTY 不是简单报错退出,而是降级为纯文本顺序执行——p.tasks换成逐条console.log,让 CI / 脚本环境也能跑通安装。而isCancel检查则严格遵循了 Phase 0 反模式清单,install.ts 中几乎每个 prompt 之后都有成对的模式(如 L294-L295、L946-L947):

if (p.isCancel(choice)) { p.cancel('Installation cancelled.');

欢迎横幅的样式实现位于 L1966:p.intro(styleText(['bgCyan', 'black'], ' claude-mem install '))——最终版用 Node 内置styleText替代了计划中的 picocolors,效果等价且零依赖。

五、Phase 3:依赖检查与自动安装

计划要求用p.tasks()依次以动画 spinner 检查四类依赖:

  • Node.jsprocess.version校验 >= 18.0.0;
  • gitcommandExists('git'),缺失时按 OS 给出安装指引(不能自动装则优雅失败);
  • Bun:查 PATH 与常见位置(~/.bun/bin/bun/usr/local/bin/bun/opt/homebrew/bin/bun),最低 1.1.14,确认后从官方脚本自动安装;
  • uv:查 PATH 与~/.local/bin/uv~/.cargo/bin/uv,确认后自动安装。

安装尝试之后必须重新验证一遍。验证标准覆盖四种终态:找到的依赖显示绿色对勾、缺失的显示黄色警告并提供安装选项、确认后真的完成安装、git 缺失时优雅失败。

这部分在 setup-runtime.ts 中有完整且更精细的落地。二进制搜索逻辑与计划完全一致——先探测 PATH,再回退到常见安装位置:

const BUN_COMMON_PATHS = IS_WINDOWS ? [join(homedir(), '.bun', 'bin', 'bun.exe')] : [join(homedir(), '.bun', 'bin', 'bun'), '/usr/local/bin/bun', '/opt/homebrew/bin/bun', ...]; const UV_COMMON_PATHS = IS_WINDOWS ? [join(homedir(), '.local', 'bin', 'uv.exe'), join(homedir(), '.cargo', 'bin', 'uv.exe')] : [join(homedir(), '.local', 'bin', 'uv'), join(homedir(), '.cargo', 'bin', 'uv'), '/usr/local/bin/uv', '/opt/homebrew/bin/uv'];

自动安装失败时的补救信息被做成平台感知的一等公民:Windows 下提示winget install Oven-sh.Bun/winget install astral-sh.uv,类 Unix 下提示curl -fsSL https://bun.sh/install | bash或 Homebrew 等价命令(见 setup-runtime.ts 中platformBunRemediation()/platformUvRemediation())。另一个工程化细节是安装超时可用环境变量覆盖,默认 5 分钟:

const INSTALL_TIMEOUT_MS = (() => { const override = process.env.CLAUDE_MEM_INSTALL_TIMEOUT_MS; if (override && Number.isFinite(Number(override))) return Number(override); return 5 * 60 * 1000; })();

六、Phase 4:IDE 多选与 Provider 配置

IDE 选择p.multiselect():Claude Code(默认选中,hint 为 "recommended")、Cursor、Windsurf(hint "coming soon",disabled: true)。选中 Claude Code 时提示插件将通过 marketplace 注册;选中 Cursor 时提示 hooks 将按 CursorHooksInstaller 的模式安装。

Provider 配置p.select()三选一,每个分支的追问结构是计划的精华:

  • Claude(hint:使用 Claude 订阅):再选认证方式——"CLI(Max Plan 订阅)" vs "API Key";API Key 走p.password()遮罩输入;
  • Gemini(hint:有免费额度):p.password()必填 key;p.select()选模型(默认 gemini-2.5-flash-lite,另有 gemini-2.5-flash、gemini-3-flash-preview);p.confirm()确认限流(默认 true);
  • OpenRouter(hint:有免费模型):p.password()必填 key;p.text()填模型(默认xiaomi/mimo-v2-flash:free)。

所有 key 尽量做非空与格式校验。验证标准四条:多选可用、各分支追问正确、key 全程遮罩、任意步骤可取消且优雅退出。

仓库的 index.ts 把这一交互层同时翻译成了非交互命令行参数,这是计划文档没有展开、但生产环境必需的能力:

npx claude-mem install --provider claude|gemini|openrouter|host # 非交互指定供应商 npx claude-mem install --model <id> # provider=claude 时指定模型 npx claude-mem install --no-auto-start # 跳过结束时的 worker 自启动 npx claude-mem install --runtime worker|server # 非交互选择运行时

参数解析用parseArgs(strict: false),并对--provider/--runtime做白名单校验,非法值直接报错退出(index.ts L66-L114)。还有一个关键的非交互默认值逻辑:当stdin.isTTY !== true且未显式传 provider 时,调用resolveInstallerProviderChoice({ ide })为特定 IDE 推导隐式 provider(L99-L104)——这正对应 Phase 0 反模式「不要未做 TTY 检查就调用提示」的彻底贯彻:非 TTY 下根本不会弹出任何 prompt。

七、Phase 5:设置向导与 Schema 对齐的设置写入

设置步骤的策略是「默认优先」:先用p.confirm()问 "Use default settings?"(推荐),选 yes 直接跳过明细;选自定义则用p.group()组织六个配置项,其中数值项都要手工校验——这正是反模式清单第 5 条text()无数字模式的应对:

  • Worker 端口:默认 37777,校验 1024-65535;
  • 数据目录:默认~/.claude-mem
  • Context 观测数:默认 50,校验 1-200;
  • 日志级别:DEBUG / INFO(默认)/ WARN / ERROR;
  • Python 版本:默认 3.13;
  • Chroma 向量检索:默认 true;若启用再选 local(默认)/ remote,remote 时追问 host、port 与 SSL。

进入下一步前用p.note()展示设置摘要。设置写入器(settings-writer.ts)的要求是:构建与 SettingsDefaultsManager schema 完全一致的扁平键值对象、升级时与既有设置合并(保留用户自定义)、写入~/.claude-mem/settings.json、目录不存在则创建。验证标准包括:默认模式跳过全部明细提示、自定义模式全量校验、产物与 schema 精确匹配、升级保留既有设置。

八、Phase 6:安装执行、插件注册与两阶段健康检查

install.ts(计划阶段的步骤文件)用p.tasks()呈现四个视觉化步骤:克隆仓库到临时目录(--depth 1)、npm installnpm run build、注册插件。插件注册是四个落点:拷贝插件文件到~/.claude/plugins/marketplaces/thedotmack/并建立 marketplace.json / plugin.json 结构、更新known_marketplaces.json、更新installed_plugins.json、在~/.claude/settings.jsonenabledPlugins下启用。若用户勾选了 Cursor,还要额外执行 hooks 安装逻辑:写hooks.json~/.cursor/或项目级.cursor/,并在.cursor/mcp.json配置 MCP。

worker.ts的步骤用p.spinner()呈现,并采用两阶段健康检查(计划注明该模式参考 OpenClaw 安装脚本):

  • 启动 worker:bun plugin/scripts/worker-service.cjs,PID 写入~/.claude-mem/worker.pid
  • Stage 1轮询/api/health(spinner 文案 "Starting worker service...");
  • Stage 2轮询/api/readiness(spinner 文案 "Initializing database...");
  • 预算:30 次尝试、间隔 1 秒;
  • 成功:spinner.stop("Worker running on port {port}");失败:spinner.error("Worker failed to start")并展示日志路径。

验证清单要求四个注册文件全部更新、worker 两个端点均返回 200。仓库侧对应的健康检查能力实现在 HealthMonitor,worker 启动路径见 worker-service.ts。

九、Phase 7 与 Phase 8:完成摘要与 curl | bash 引导

完成页用两段p.note():第一段是配置摘要(Provider + 模型、已配置 IDE、数据目录、worker 端口、Chroma 开关),第二段是下一步指引——打开 Claude Code 即可自动记忆、http://localhost:{port}查看记忆、用/mem-search搜索历史工作、若装了 Cursor 则 hooks 已生效——最后p.outro()收尾。验证要点:摘要与所选设置一致、URL 端口正确、下一步与已选 IDE 相关。

curl | bash 引导脚本(计划阶段的install/public/install.sh)要求:检查 Node >= 18、把打包好的安装器 JS 下载到临时文件、直接node执行以保留 TTY、用trap在成功和失败两种路径下都清理临时文件、透传--non-interactive--provider=X --api-key=Y。配套要求 install/vercel.json 把install.sh作为站点根路径服务出去。

这里值得对照仓库现状说明一次设计演进:当前 install.sh 已经不再是引导脚本,而是一个明确的迁移提示——

echo -e "${YELLOW}The curl-pipe-bash installer has been replaced.${NC}" echo " ${CYAN}npx claude-mem install${NC}" echo "This requires Node.js >= 20. ..."

也就是说,计划中 Phase 8 的 curl | bash 方案在演进中被npx claude-mem install取代(Node 门槛同步从 18 提到 20),而 vercel.json 的 rewrite 规则(//install.sh.shtext/plain服务并带短缓存头)保留了下来,用于继续承接旧安装命令的用户。这是「计划文档描述设计意图、仓库现状描述演进结果」的典型对照。

十、Phase 9:最终验证清单(可直接复用的验收模板)

计划把验收标准压缩成 12 条可勾选的检查项,这套清单本身就值得作为任何 CLI 安装器的模板:

  • npm run build产出单文件dist/index.js
  • node dist/index.js可完整跑通向导流程;
  • 干净系统全新安装端到端成功;
  • 升级路径保留既有设置;
  • 任意步骤 Ctrl+C 干净退出;
  • 非 TTY 显示错误消息(最终实现中进一步演进为非交互降级模式);
  • 写入的所有设置与 SettingsDefaultsManager.ts 的默认 schema 一致;
  • 安装后 worker 健康检查成功;
  • 插件出现在 Claude Code 插件列表中;
  • grep弃用/不存在的 API 结果为 0;
  • 源码中无require()调用(ESM-only);
  • chalk导入(统一 picocolors / 内置 styleText)。

小结

animated-installer.md 的价值不仅在于描述了一个安装器,更在于它示范了「计划文档如何与源码对齐」:Phase 0 的 API 表与反模式清单约束了全部代码形态(ESM-only、TTY 检查、isCancel成对出现);Phase 3 的常见二进制路径与平台补救话术在 setup-runtime.ts 中原样实现;Phase 4 的交互选择在 index.ts 中被扩展为非交互 CLI 参数,使同一套安装逻辑同时服务人类终端与自动化环境;Phase 8 的 curl | bash 则被npx claude-mem install平滑取代,旧入口改为迁移提示。对照计划与实现,可以推断出该仓库的 CLI 工程原则:交互体验由@clack/prompts承担、所有提示必须先过 TTY 判定、每个用户输入都有取消出口、设置产物必须与默认值 schema 逐字段对齐。

【免费下载链接】claude-memPersistent Context Across Sessions for Every Agent – Captures everything your agent does during sessions, compresses it with AI, and injects relevant context back into future sessions. Works with Claude Code, OpenClaw, Codex, Gemini, Hermes, Copilot, OpenCode + More项目地址: https://gitcode.com/GitHub_Trending/cl/claude-mem

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询