# 记忆匠
**Repository Path**: wb04307201/Mnemosmith
## Basic Information
- **Project Name**: 记忆匠
- **Description**: 桌面端 Markdown 知识库工作台 —— 笔记是原料,AI 技能是工匠,知识库是铸锭。
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2026-10-02
- **Last Updated**: 2026-10-10
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Mnemosmith —— 记忆匠
> 桌面端 Markdown 知识库工作台 —— 笔记是原料,AI 技能是工匠,知识库是铸锭。
**中文** · [English](README.md)
一个运行在你自己磁盘上的知识库工作台:管理 Markdown 笔记,用自然语言问它,AI 检索库内文章回答并给引用,
需要时派技能做体检、面试、沉淀规划——所有改动先进「待审暂存」,你批准后才落盘并生成 git 提交。
[](https://tauri.app)
[](https://react.dev)
[](https://www.rust-lang.org)
[](https://sqlite.org)
---
## 界面
**三栏工作台** —— 左:笔记树 / 中:编辑器(查看模式渲染中)/ 右:AI 对话。
打开笔记与提问可以同时进行,AI 的回答带库内引用。

|
**Markdown 渲染**
Mermaid 图、KaTeX 公式、shiki 代码高亮,`.md` 相对链接可点击跳转。

|
**编辑器源码模式**
CodeMirror 6,三模式切换(编辑 / 对比 / 查看),多标签页。

|
|
**全文搜索**
SQLite FTS5,正文 + 文件名双模式,千级库实测 < 40ms。

|
**命令面板**
`Ctrl/⌘+K` 模糊搜索全部命令。

|
|
**链接图谱**
cytoscape 力导向布局,孤儿 / 单向链接 / 兄弟互链不全三类高亮。

|
**体检报告**
六维雷达图 + P0–P3 分级问题清单 + 分批修复计划。

|
|
**变更审阅**
技能产生的改动全部进待审队列,逐项/批量审批后才落盘并提交。

|
**沉淀看板**
把「待沉淀」的知识排成四列看板,拖拽推进状态。

|
---
## 目录
- [核心特性](#核心特性)
- [快速开始](#快速开始)
- [AI 配置](#ai-配置)
- [三个技能](#三个技能)
- [技术栈](#技术栈)
- [项目结构](#项目结构)
- [开发](#开发)
- [文档](#文档)
- [设计约束](#设计约束)
---
## 核心特性
### 知识库管理
- **多仓库**:本地目录 / 远程仓库 clone,笔记子目录可指定
- **Git 集成**:状态栏实时显示分支、领先落后、脏标记、冲突;Pull / Commit / Commit & Push
- **笔记树**:千级文件虚拟化滚动,展开折叠、过滤搜索、右键菜单、多选批量、最近打开
- **编辑器**:CodeMirror 6,三模式(编辑 / 对比 / 查看),多标签页(脏点标记、拖拽排序、关闭确认、重启恢复)
- **Markdown 渲染**:KaTeX 公式、Mermaid 图、shiki 代码高亮、`.md` 相对链接点击跳转
- **全文搜索**:SQLite FTS5,正文 + 文件名双模式,1189 篇库实测最慢 36ms
- **反链与孤页**:底部信息栏展示入链来源,孤页标记
### AI 能力
- **多 Profile**:多个 AI 配置并存,API Key 存系统钥匙串(不明文落盘),可热切换
- **双协议**:Anthropic 协议 与 OpenAI 兼容协议(含流式、tool_use、思考过程)
- **技能引擎**:三个技能自主规划步骤、调工具检索库内笔记、生成待审变更
- **面试卡片链**:出题 → 作答 → 评价 → 追问(≤3 轮)→ 总结
- **变更审阅闭环**:diff 预览 → 逐项/批量审批 → 自动提交(带技能标记)→ 一键回滚
- **上下文压缩**:会话过长时把早段摘要替换,保留历史配对不变量
- **学习路径自适应**:按薄弱点调整「考考我」的出题策略
### 界面
- **三栏布局**:笔记树 / 编辑器 / 工作台 Dock(Dock 可折叠、可调宽 300–720px)
- **三态主题**:跟随系统 → 夜间 → 日间循环,持久化
- **命令面板**:`Ctrl/⌘+K` 模糊搜索命令
- **深色模式**:CSS 变量 token 驱动
---
## 快速开始
### 环境要求
| 依赖 | 版本 |
|---|---|
| Node.js | ≥ 22(CI 用 22,本地开发用 24) |
| pnpm | 9.x(见 `package.json` 的 `packageManager`) |
| Rust | stable |
| 系统依赖 | Windows 需 WebView2 |
> 本项目**只发 Windows**(见 `tauri.conf.json` 的 `bundle.targets`)。
### 安装与运行
```bash
git clone https://gitee.com/wb04307201/Mnemosmith.git
cd Mnemosmith
pnpm install
pnpm tauri:dev # 起开发窗口(含 CDP 调试端口 :9222)
pnpm tauri:build # 打包安装包 → src-tauri/target/release/bundle/
```
首次启动是欢迎页 → **添加本地仓库** → 选你的 Markdown 知识库根目录。
### 打包产物
`pnpm tauri:build` 产出(`src-tauri/target/release/bundle/`):
| 格式 | 文件 | 说明 |
|---|---|---|
| NSIS | `nsis/mnemosmith_<版本>_x64-setup.exe` | 免管理员,装到 `%LOCALAPPDATA%\mnemosmith` |
> 只有 NSIS 一种包(Windows-only,见 `tauri.conf.json` 的 `bundle.targets`)。
> 用 `nsis/*-setup.exe` 通配即可,不必写死。
> 安装器与卸载器界面语言由 `bundle.windows.nsis.languages` 决定(当前 `SimpChinese`)—— 全程中文。
>
> **卸载**:走「设置 → 应用」或安装目录的 `uninstall.exe`,确认页上有一个
> **默认不勾选**的「删除应用程序数据」勾选框。勾了才删 `%APPDATA%\com.mnemosmith.app`
> 与 `%LOCALAPPDATA%\com.mnemosmith.app`(**不含**你自己的知识库目录);
> 不勾则只卸程序。静默卸载(`/S`)一律保留数据。
>
> 选 NSIS 而非 MSI 的原因:MSI 的 ARP 卸载走 `msiexec /x` → basic UI → **跳过所有对话框**,
> 「设置 → 应用」这条路径下用户永远看不到任何提示。这是 Windows Installer 的架构行为,
> 无法在 MSI 内修复(两次实测尝试均失败)。详见
> `docs/superpowers/specs/2026-10-05-nsis-migration-design.md`。
安装包含 `skills-src/`(三个技能的 SKILL.md)—— 装出来即可用,无需另拷技能文件。
纯绿色单文件用 `src-tauri/target/release/mnemosmith.exe`(需已装 WebView2)。
### 知识库约定
应用对知识库结构有期望(不满足时降级提示,不报错):
```
$KB_DIR/
├── SPEC.md # 全局规范:评分维度、扫描规则、互链规则
├── 01.<模块>/ # 一级编号模块目录,运行时动态读取
│ └── README.md
├── 12.interview/ # 面试题精炼层
└── 13.story/ # 叙事层
```
笔记带 YAML frontmatter(difficulty / depth 等)。模块数不硬编码 —— 技能执行时 `find "$KB_DIR" -maxdepth 1 -type d` 实时读取。
---
## AI 配置
应用内 **设置 → AI 配置** 添加。两点要注意:

**1. base_url 不要重复写 `/v1`**
代码里的 `normalize_base_url` 会自动补 `/v1`(已含则保留),两种协议挂 system 的位置不同:
Anthropic 走顶层 `system` 字段,OpenAI 走 messages 首条。
**2. 可用端点示例**
| 服务商 | provider | base_url |
|---|---|---|
| Anthropic 官方 | `anthropic` | `https://api.anthropic.com` |
| OpenAI 官方 | `openai` | `https://api.openai.com/v1` |
| OpenCode Zen | `anthropic` | `https://opencode.ai/zen` |
| OpenCode Zen(OpenAI 协议) | `openai` | `https://opencode.ai/zen/v1` |
| 任意 OpenAI 兼容网关 | `openai` | `<网关地址>/v1` |
API Key 存**系统钥匙串**,不写数据库、不进日志。
---
## 三个技能
技能是 `SKILL.md` 说明书 + 引擎能力的组合,随应用分发,开箱可用。
### `note-health` — 知识库体检
批量扫描笔记质量:结构完整性、断链、孤儿目录、frontmatter 覆盖、逐篇打分,
产出 P0–P3 分级问题清单 + 分批修复计划。技能可以执行修复(进待审暂存,你批准才落盘)。
### `note-knowledge-qa` — 知识问答
按库内文章回答并附引用,**不凭模型记忆答**。七种模式:
| 模式 | 用途 | 入口 |
|---|---|---|
| A 技术问答 | 「HashMap 为什么线程不安全」 | 直接提问 |
| B 出题模式 | 批量出题 + 答案 | `/` 菜单,或「考考我」 |
| C 设计指导 | 方案对比 | 直接提问 |
| D 模拟面试 | 出题 → 作答 → 评价 → 追问 → 总结 | `/interview D` |
| E 简历面试 | 按简历技术栈出题 | `/interview E` |
| F 学习路径 | 分层知识地图 | `/learn` |
| G 面试官出题 | 按候选人画像选题 | `/interview G` |
> **模式不是技能**:D/E/F/G 是 `note-knowledge-qa` 的交互形态,共用同一套检索与引用规范。
> 选模式 = 锁定该技能 + 注入模式指令,技能侧 SKILL.md 的模式表据此生效。
### `note-precipitation-planning` — 沉淀规划
把新知识规划成笔记:判断落哪个模块、要不要双层/三层沉淀、建立互链(新→旧、旧→新、README→新、兄弟互链)。
---
## 技术栈
**壳层**:Tauri 2(Rust 后端 + 系统 WebView)
**前端**:React 19 · TypeScript · Vite 8 · Tailwind CSS v4 · shadcn/ui(vendored,底层 Radix)· zustand · CodeMirror 6 · cytoscape
**后端**:Rust · SQLite(rusqlite,FTS5 全文索引)· git2 · reqwest(流式 SSE)· lopdf(PDF 提取)
**引擎**:tokio 异步任务树(技能 run / 子任务派发)· 自研工具注册表
---
## 项目结构
```
src/ 前端
├── components/
│ ├── MainLayout.tsx 三栏骨架 + Dock 宽度调节
│ ├── note-tree/ 虚拟化笔记树
│ ├── editor/ CodeMirror 三模式 + 标签页
│ ├── chat/ 对话流 + 卡片
│ │ ├── qaModes.ts note-qa 的 B/D/E/F/G 模式定义
│ │ └── cards/interview/ 面试卡片链 + PreCheckCard
│ ├── dock/ 右侧工作台(5 个页签)
│ ├── health/ board/ review/ timeline/ graph/
│ └── ui/ shadcn/ui 原子件
├── stores/ zustand(chat / editor / dock / review …)
└── commands/manifest.ts ⌘K 命令注册表
src-tauri/src/
├── ai/ AI 层
│ ├── identity.rs 应用身份 system prompt ★
│ ├── stream.rs 双协议流式客户端
│ ├── proto.rs SSE 解析(Anthropic / OpenAI 归一)
│ └── skills.rs SKILL.md 加载
├── engine/ 技能引擎
│ ├── run.rs run 生命周期
│ ├── tools.rs 工具注册表(笔记/搜索/git/ask_user…)
│ ├── graph.rs 链接图谱构建
│ └── learning.rs interview.rs compress.rs
├── db.rs SQLite + schema 迁移链
└── gitx.rs repos.rs fs.rs search.rs review.rs
skills-src/ 三个技能的 SKILL.md(随应用分发)
scripts/cdp.mjs CDP 驱动层(交互级 E2E 用)
docs/ PRD / ROADMAP / TECH_STACK / 测试报告
```
---
## 开发
```bash
pnpm tauri:dev # 开发窗口(WebView2 CDP :9222,便于调试)
pnpm dev # 仅前端(浏览器调试)
pnpm test # vitest(763 项)
pnpm lint # oxlint
pnpm build # tsc + vite build
cd src-tauri
cargo test # 335 项
cargo clippy --all-targets
```
### 测试分层
| 层次 | 位置 | 何时跑 |
|---|---|---|
| 单元 / 集成 | `pnpm test`(763 项)+ `cargo test`(335 项) | 每次改动,CI 强制 |
| 类型 + lint | `pnpm build` / `pnpm lint` / `cargo clippy` | 每次改动,CI 强制 |
| 打包产物验证 | CI `build` job —— 断言 `skills-src` 在 bundle 内、NSIS 出包且无 MSI | 每次 push,CI 强制 |
| 安装/卸载真机验证 | CI `verify-nsis-install` job —— 真装真卸,断言数据保留 / 未越界 / ARP 指向 | 每次 push,CI 强制 |
| **交互级 E2E** | `test-output/full-audit/`(16 组 / 341 测试点,CDP 驱动真实窗口) | 发布前人工跑 |
交互级 E2E 不进 CI —— 需要图形环境且对窗口状态敏感,容易产生假失败。
最近一次全功能验收报告:[docs/TEST-REPORT-2026-10-06.md](docs/TEST-REPORT-2026-10-06.md)(341 点 / 0 FAIL)。
### 发版
打 tag → 建 Release 即触发 CI 自动出包:
```
在 Gitee 打 tag v0.1.0 → 自动同步到 GitHub 镜像(CI 不跑)
在 GitHub 建 Release 指向该 tag → 触发 CI(release: published)
├─ 三个 job 全绿
├─ NSIS 包挂到该 Release
└─ 版本号回写仓库
```
CI **不监听 tag**(只监听 `release: published`)—— 因为若监听 tag,Gitee 打 tag 时
Release 还不存在,包挂不上去。详见 `.github/workflows/ci.yml` 顶部注释。
---
## 文档
| 文档 | 内容 |
|---|---|
| [docs/PRD.md](docs/PRD.md) | 产品需求 v2.6 —— 功能定义、界面布局、优先级规划 |
| [docs/ROADMAP.md](docs/ROADMAP.md) | 切片路线图 + 验收日志(唯一跟踪源) |
| [docs/TECH_STACK.md](docs/TECH_STACK.md) | 技术选型与决策依据 |
| [skills-src/](skills-src/) | 三个技能的说明书(技能行为的权威来源) |
| [docs/TEST-REPORT-2026-10-06.md](docs/TEST-REPORT-2026-10-06.md) | 全功能 E2E 验收报告 + 缺陷台账 |
---
## 设计约束
几条贯穿全项目的红线,改动时注意:
1. **技能改文件必经用户审阅** —— 写工具只进「待审暂存」,磁盘不动,批准后才落盘 + 提交
2. **回滚不重写历史** —— 生成一条回滚提交,技能提交仍保留可追溯
3. **AI 不编造库内路径** —— system prompt 明确禁止,引用必须真实存在
4. **知识库结构运行时读取** —— 不硬编码模块列表,换库即生效
5. **API Key 不落库** —— 存系统钥匙串
6. **卸载不删知识库** —— 卸载器只碰 `%APPDATA%` / `%LOCALAPPDATA%` 下的应用数据目录,
你自己的笔记库目录永不被触碰
---
## License
私有项目,未开源(`package.json` 标记 `private: true`)。