ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

claude-mem 安装与分发体系解析:从 TRIAGE-07 看插件首装失败的根因与修复

claude-mem 安装与分发体系解析:从 TRIAGE-07 看插件首装失败的根因与修复 claude-mem 安装与分发体系解析从 TRIAGE-07 看插件首装失败的根因与修复【免费下载链接】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-memclaude-mem 通过 Claude Code 插件机制分发给最终用户首次安装能否成功直接决定了新用户的第一印象。本文基于仓库内的问题修复记录 TRIAGE-07-Installation-Distribution系统梳理该修复周期解决的六类安装问题对应 issue #1128、#1166、#1187、#1156、#979、#1041并结合 plugin/package.json、src/npx-cli/install/setup-runtime.ts、tests/infrastructure/plugin-distribution.test.ts 等仓库源码还原每项修复的实现细节与回归验证方式。读完本文你可以掌握插件运行时依赖的审计方法、基于真实模块解析的 post-install 校验机制、三层分发链路以及 SQLite 双迁移系统版本冲突的根治思路。一、问题背景新用户首装失败的三类典型症状TRIAGE-07 文档开篇即列出了新用户遇到的安装失败场景这三类症状分别对应分发链路上的不同环节缓存式安装后缺少node_modulesissue #1128、#1166插件从缓存目录提取到 marketplace 目录后运行时依赖没有被安装worker 和 hooks 脚本一启动就报Cannot find module插件完全无法工作skills/目录未被复制issue #1187安装完成后plugin/skills/mem-search/SKILL.md缺失导致 Claude Code 无法按约定发现 mem-search 技能npnpm 发布工具被错误地列为运行时依赖issue #1156发布工具只应在开发机上使用出现在运行时依赖中会让消费者下载无用的包另外还涉及迁移失败issue #979全新数据库初始化即报错和marketplace not foundissue #1041插件根路径解析失败。修复记录中每项任务都附带了验证结论Verified 2026-02-23 / Fixed 2026-02-23这是理解下文各节的事实基础。二、依赖审计plugin/package.json里只允许放真正的运行时依赖修复的第一个动作是审计依赖面将 plugin/package.json 的dependencies与plugin/scripts/*.js中的实际运行时 import 逐一比对确认每个声明的依赖都有真实用途。文档中特别指出了一条判定准则自 v10.3.0 起claude-mem 的向量检索走chroma-mcp通过 uvx 拉起的独立进程不再依赖 npm 的chromadb包。因此审计时要在全仓搜索require(chromadb)确认无残留后再将其从依赖中移除并同步更新任何提及它的错误提示。文档结论为验证当日所有依赖均正确无任何chromadb残留引用无需变更。对照当前仓库的 plugin/package.json其dependencies目前只包含插件 hook 运行时真实用到的包zodschema 校验worker 运行时从插件目录内的副本解析一组tree-sitter-*语言解析器C、C、Go、Java、JavaScript、Python、Ruby、Rust、TypeScript、Kotlin、Swift、PHP、Lua、Scala、Bash、Haskell、Zig、CSS、SCSS、TOML、YAML、SQL、Markdown与tree-sitter-cli服务于代码结构解析shell-quote。注意overrides将tree-sitter固定到^0.25.0并把tree-sitter-cli列入trustedDependencies它带 native 构建需要 npm 信任才执行 install 脚本engines要求node 20.12.0、bun 1.0.0。这套声明即所需的依赖清单正是审计任务要维护的不变量。np的归类验证发布流程定义在根 package.json 中release: np等脚本依赖np^11.2.0而它确实只出现在devDependencies第 157 行dependencies仅有服务端认证面用到的better-auth与better-auth/api-key。根package.json里还有一段//dependencies-note注释明确解释了依赖归类原则只有经 bundler 后仍作为存活import/require出现在发布产物中的依赖才进dependencies其余express、bullmq、ioredis、react、zod 等全部由 esbuild 内联进 worker/server/npx 产物作为构建期 devDependency 存在不会让消费者下载。这条注释本身就是一份可审计的依赖治理策略。三、修复缓存安装缺少node_modules路径解析 post-install 校验3.1 根因硬编码路径 installCLI()路径错误修复记录给出的根因很具体原smart-install.js中硬编码了~/.claude/plugins/marketplaces/thedotmack这一路径对缓存式cache-based安装完全不适用同时installCLI()使用了错误的目标路径ROOT/plugin/scripts/而非ROOT/scripts/。修复方案是引入resolveRoot()采用多级回退策略解析插件根目录优先读取环境变量CLAUDE_PLUGIN_ROOT—— Claude Code 为所有 hook 进程注入该变量是最可靠的来源回退到脚本自身位置import.meta.url推导再回退到 XDG 路径与旧版legacy路径。这一思路在仓库中仍有体现plugin/hooks/hooks.json、plugin/scripts/bun-runner.js 等分发产物中都使用CLAUDE_PLUGIN_ROOT来定位插件文件避免依赖任何与用户名、安装方式相关的绝对路径。同时修复要求分发版与开发版使用同一套解析逻辑——即plugin/scripts/下的分发副本与scripts/下的开发副本保持相同实现杜绝开发机正常、用户机失败的漂移。3.2verifyCriticalModules把装没装从目录存在性升级为真实模块解析修复的第二层防线是安装后校验。当前实现位于 src/npx-cli/install/setup-runtime.ts其设计比检查node_modules/dep目录是否存在严谨得多值得逐点拆解1以安装树为锚点的解析。函数用createRequire(join(nodeModulesPath, noop.js))创建一个锚定在安装目录内的 require 实例使require.resolve遵守被安装package.json的exports映射而不是宿主环境的模块路径。这保证校验的是用户机器上这份安装的闭包完整性。2逐依赖解析 bin-only 包的二次确认。对dependencies中每个声明包先做裸名解析失败后不直接判死而是再尝试解析dep/package.json——因为像tree-sitter-cli这类只有bin没有入口点无main/module/exports/index.js的包裸名解析天然会失败但其package.json是可解析的说明它其实装好了。两次都失败才算真正缺失源码注释中将该行为追溯到 issue #2730。3zod 子路径导出的显式校验。被打包的 worker 会经由modelcontextprotocol/sdk等依赖传递性地import zod/v3、zod/v4、zod/v4-mini。注释指出一个隐蔽故障模式陈旧或半截的安装可能让zod目录存在但子路径导出解析失败最终在运行时才以Cannot find module zod/v3的形式爆发。因此校验对ZOD_REQUIRED_SUBPATHS [zod/v3, zod/v4, zod/v4-mini]逐一 resolve且不绑定具体版本号version-agnostic: we resolve subpaths, never a pinned version。4失败要响fail LOUD。所有无法解析的模块被收集进unresolvable列表循环结束后统一抛出Post-install check failed: unresolvable modules: 逗号分隔的列表该函数在安装主流程的尾部被调用setup-runtime.ts 第 458 行失败即中止安装而不是留下一个看起来装好了的破损闭包对应的回归测试在 tests/cli/verify-critical-modules.test.ts。文档中还记录了失败时的 npm 回退策略——校验不通过则触发重新npm install的兜底流程。四、skills/缺失问题技能是源文件不是构建产物对安装后缺skills/的排查结论是plugin/skills/mem-search/SKILL.md本就已提交进 git且就位于plugin/分发目录内——构建脚本 scripts/build-hooks.js 无需也不应该复制它因为技能是源文件而非构建输出。真正的分发保障来自三条独立链路任何一条失效都会被其他链路或测试兜住marketplace/缓存同步scripts/sync-marketplace.cjs 将完整的plugin/目录同步到 marketplace 与缓存两个路径对应根package.json的sync-marketplace脚本可加--force强制npm 发布面根 package.json 的files字段第 35–52 行显式包含plugin/skills、plugin/hooks、plugin/scripts/*.js、plugin/scripts/*.cjs、plugin/.claude-plugin、plugin/package.json、plugin/bun.lock等条目npm 发布时这些内容随包体走约定式发现plugin.json并不枚举技能文件Claude Code 按skills/*/SKILL.md约定自动发现——这解释了为什么构建不复制是正确的也说明分发完整性只依赖目录布局正确。在此之上修复又加了两道防回归的保险构建期验证在 scripts/build-hooks.js 中新增检查若plugin/skills/mem-search/SKILL.md、plugin/hooks/hooks.json或plugin/.claude-plugin/plugin.json任一缺失构建直接失败10 个回归测试tests/infrastructure/plugin-distribution.test.ts 覆盖技能文件存在性、YAML frontmatter 合法性必须以---开头且含name:与description:、三层工作流文档完整性搜索search/timeline/get_observations三个关键词、必需分发文件清单、hooks.json中CLAUDE_PLUGIN_ROOT引用的一致性、package.json的files字段以及构建脚本验证步骤本身。从该测试文件的源码结构看它还会读取plugin/hooks/hooks.json与plugin/hooks/codex-hooks.json中所有type: command的 hook 命令逐一核对路径引用属于典型的契约型分发测试。五、SQLite 迁移失败#979两套并行迁移系统争夺同一张schema_versions表这是本修复周期中根因最深刻的一项值得单独展开。5.1 根因版本号冲突 maxApplied 0门控当时库中存在两套并行的迁移系统旧DatabaseManager的迁移 1–7与新MigrationRunner的迁移 4–22两者共用同一张schema_versions表。版本号 5、6、7 发生语义冲突——旧系统的版本 5 是删除孤儿表新系统的版本 5 是给worker_port加列。一旦数据库里预记录了旧系统的版本号就触发连锁故障initializeSchema()内的门控条件maxApplied 0时跳过建表误判已经有版本核心表必然存在跳过了核心表的创建新系统的迁移 5–7 因版本号已存在而被视为已应用实际变更从未执行。最终表现就是全新数据库初始化失败或库处于表存在但列/约束缺失的半损坏状态。5.2 四条修复措施移除maxApplied 0门控核心表的创建改为无条件执行CREATE TABLE IF NOT EXISTS与版本记录状态解耦。从当前仓库 src/services/sqlite/SessionStore.ts 的源码结构看这一原则贯穿了后续所有演进——例如迁移 31–35、41sync_state、42sync_outbox、47–49 等的建表语句均为CREATE TABLE IF NOT EXISTS ...且每次应用都以SELECT version FROM schema_versions WHERE version ?查询 INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)写入构成幂等单元如第 927–935 行处schema_versions、sdk_sessions、observations、session_summaries的初始建表。状态驱动而非记录驱动迁移 5–7 不再只信schema_versions记录而是检查实际数据库状态列是否存在、约束是否存在再决定是否执行变更。这让版本表与真实结构不一致的历史包袱被状态检查吸收。崩溃安全crash-safety临时表重建类迁移7、9、21在创建xxx_new临时表前先DROP TABLE IF EXISTS xxx_new防止上一次中途崩溃留下的残留表导致CREATE TABLE报错补齐缺失迁移 FK 级联把只存在于SessionStore中的迁移 21addOnUpdateCascadeToForeignKeys补进MigrationRunner并在initializeSchema()的 FK 定义中加入ON UPDATE CASCADE。所有改动同时落到runner.ts与SessionStore.ts两个位置并新增 13 个回归测试tests/services/sqlite/migration-runner.test.ts 当时路径覆盖六大场景全新数据库初始化、幂等性连续跑两遍、版本冲突预记录旧版本 1–7、崩溃恢复残留临时表、FK 级联约束、数据完整性保持。5.3 可迁移的工程经验这段修复给出的通用教训是任何版本记录表 迁移脚本体系都应保证迁移幂等、建表语句使用IF NOT EXISTS、破坏性/结构变更以真实 schema 状态为准。当系统经历过多套迁移机制并存的演化如 claude-mem 从DatabaseManager迁到MigrationRunner版本表本身就可能成为不可信的单一事实来源此时状态检查是唯一可靠的真相。六、测试收尾21 个失败用例的修复清单TRIAGE-07 的最后一项任务是把npm test跑绿。文档记录了当日 8 个测试文件中 21 个失败的逐一归因本身也是一份很好的测试与实现漂移案例集类别失败数根因与修复服务端健康端点12ServerOptions接口新增了workerPath与getAiStatus但 3 个测试文件中的 mock/内联对象未同步补齐缺失属性日志规范检查1src/services/transcripts/cli.ts 的用户可见 CLI 输出使用console.log属合理用法被误判为后台服务加入排除模式MarkdownFormatter2源码重构后文案由 MCP tools 改为 mem-search skill / claude-mem skill更新测试断言SettingsDefaultsManager1getBool用例使用了默认值已变为false的CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS改用默认true的CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENTChromaSync3重构为ChromaMcpManager单例后测试仍在断言已不存在的内部client/transport/connected属性改为校验ChromaMcpManager.ts源码中的 transport 清理逻辑OpenClaw2测试预期的memory_工具跳过与响应截断功能源码缺失在openclaw/src/index.ts中补上memory_前缀检查防递归观察循环与MAX_TOOL_RESPONSE_LENGTH 1000截断最终结果为1008 通过、0 失败、3 跳过共 57 个文件。注意其中OpenClaw 两项是测试先于实现的反向证据测试把预期行为写死后源码补齐了功能——这也提示维护者断言与实现谁先漂移都应视为缺陷。七、小结安装分发的四道防线把 TRIAGE-07 的修复串联起来可以抽象出 claude-mem 在安装分发上的四层防御每一层都能对应当前的仓库证据依赖面最小化——plugin/package.json只声明 hook 运行时真实 import 的包根package.json用//dependencies-note固化bundler 存活依赖才进 dependencies的归类规则发布工具np严格留在 devDependencies路径与安装方式无关——resolveRoot()以CLAUDE_PLUGIN_ROOT为首选来源多级回退分发版与开发版共用同一解析实现杜绝硬编码用户目录分发完整性多层保障——sync-marketplace.cjs同步、npmfiles白名单、skills/*/SKILL.md约定式发现再由构建期校验 契约型测试tests/infrastructure/plugin-distribution.test.ts兜底安装后校验与幂等持久层——verifyCriticalModules()以真实模块解析含 bin-only 包与 zod 子路径导出在装完即验、失败即响SQLite 侧则以CREATE TABLE IF NOT EXISTS 状态检查保证全新库与历史库都能收敛到一致 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),仅供参考
返回列表