stellavault 0.8.4 → 0.8.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +469 -0
- package/README.ko.md +469 -0
- package/README.md +497 -372
- package/README.zh.md +469 -0
- package/dist/graph-ui/assets/{camera_utils-DBFmYlaE.js → camera_utils-DbH6FBwg.js} +1 -1
- package/dist/graph-ui/assets/{hands-CBFUH2Er.js → hands-DSGVtDgH.js} +1 -1
- package/dist/graph-ui/assets/index-nyIICe1Z.js +4524 -0
- package/dist/graph-ui/index.html +1 -1
- package/dist/stellavault.js +1107 -429
- package/package.json +21 -6
- package/dist/graph-ui/assets/index-BNGAzxHC.js +0 -4426
package/README.zh.md
ADDED
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<img src="images/banner.svg" alt="Stellavault — 丢进任何东西,它会自动编译成知识" width="100%" />
|
|
4
|
+
|
|
5
|
+
**让 Claude 记住一切的本地优先第二大脑。**<br/>
|
|
6
|
+
Karpathy 的自编译 wiki × 卡片盒笔记法 — 完全本地、仓库非破坏、MCP 原生。
|
|
7
|
+
|
|
8
|
+
[](#mcp-集成-21-个工具) [](https://www.npmjs.com/package/stellavault) [](https://github.com/Evanciel/stellavault/actions/workflows/ci.yml) []() []() [](LICENSE)
|
|
9
|
+
|
|
10
|
+
[English](README.md) · [한국어](README.ko.md) · [日本語](README.ja.md) · **简体中文**
|
|
11
|
+
|
|
12
|
+
[**🤖 添加到 Claude / Cursor**](#mcp-集成-21-个工具) · [**⬇ 桌面应用**](https://github.com/Evanciel/stellavault/releases/tag/desktop-v0.3.0) · [**⚡ 快速开始**](#安装) · [**🌐 在线演示**](https://evanciel.github.io/stellavault/)
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
> **让 Claude 读取你的知识库的一条命令:**
|
|
17
|
+
>
|
|
18
|
+
> ```bash
|
|
19
|
+
> npx -y stellavault setup # 将 MCP 服务器接入 Claude Code / Desktop、Cursor、Windsurf、VS Code
|
|
20
|
+
> ```
|
|
21
|
+
|
|
22
|
+
**一个会自我编译的第二大脑。** Stellavault 把两种关于"知识应当如何存活、生长"的思想融为一体:
|
|
23
|
+
|
|
24
|
+
- 🧠 **Karpathy 的自编译 wiki** — 丢进任何东西(PDF、YouTube 链接、一闪而过的想法),它都会被自动抽取进 `raw/`,再**编译**成概念与反向链接井然有序的 `_wiki/`。知识不会烂在文件夹里,而是随着积累不断自我重新编译。
|
|
25
|
+
- 🕸️ **卡片盒笔记法(Zettelkasten)** — 原子化笔记、`[[wikilink]]` 与自发涌现的连接,让*一张思想之网*(而非文件夹树)成为你思考的真正骨架。
|
|
26
|
+
|
|
27
|
+
二者被融合进一个本地优先的知识工具 — 功能完整的 Markdown 编辑器、3D 神经网络图谱、混合 AI 搜索,以及基于间隔重复(spaced repetition)的记忆衰减。而这一切都以 **桌面应用**、**CLI**、**Obsidian 插件**,以及**让 Claude 读取你整个仓库(vault)的 MCP 服务器**的形式提供。无需云端、无需 API 密钥,原始文件永不被修改。
|
|
28
|
+
|
|
29
|
+
<p align="center">
|
|
30
|
+
<img src="images/screenshots/graph-main-2.png" alt="3D 知识图谱" width="820" />
|
|
31
|
+
<br><em>把你的仓库变成一张神经网络。本地优先,无需云端。</em>
|
|
32
|
+
</p>
|
|
33
|
+
|
|
34
|
+
## 目录
|
|
35
|
+
|
|
36
|
+
[亮点](#亮点) · [为什么选择 Stellavault?](#为什么选择-stellavault) · [安装](#安装) · [编辑器](#编辑器) · [流水线](#流水线) · [智能功能](#智能功能) · [搜索与排名](#搜索与排名) · [MCP 集成](#mcp-集成-21-个工具) · [3D 可视化](#3d-可视化) · [配置](#配置) · [性能](#性能) · [技术栈](#技术栈) · [安全](#安全) · [故障排查](#故障排查)
|
|
37
|
+
|
|
38
|
+
## 亮点
|
|
39
|
+
|
|
40
|
+
- 🧠 **它会自我编译。** PDF、YouTube 链接、半成形的想法 — 丢进任何东西,它都会抽取进 `raw/`,再*编译*成概念与反向链接井然有序的 `_wiki/`。随积累自我整理的知识。
|
|
41
|
+
- 🔍 **真正能找到的搜索。** 用**加权 RRF** 融合语义、精确关键词(BM25)以及你自己的 `[[wikilink]]` / `#标签`,再用 FSRS 记忆模型重排序,把你*正在用*的笔记顶上来。50+ 种语言、完全本地、零 API 密钥。
|
|
42
|
+
- 🌌 **把你的思维变成 3D。** 实时神经网络图谱(React Three Fiber)— 聚类着色、星座、热力图、时间轴、多元宇宙 P2P 视图。一种*看见*自己所知形状的方式。
|
|
43
|
+
- 🤖 **Claude 读取你的整个仓库。** 一流的 **MCP 服务器**(21 个工具): 在 Claude Code、Claude Desktop、Cursor、Windsurf、VS Code 中直接搜索、问答、起草、检查与分析。
|
|
44
|
+
- ⏳ **它绝不*悄悄*遗忘。** FSRS 记忆衰减把你即将失去的真实笔记顶上来,还能检测整个仓库的知识缺口、矛盾与重复。
|
|
45
|
+
- 🔒 **本地优先。仓库非破坏。零密钥。** 本地嵌入 + 设备端向量存储,原始文件**永不被修改**。除非你主动选择,任何数据都不会离开你的机器。
|
|
46
|
+
|
|
47
|
+
## 为什么选择 Stellavault
|
|
48
|
+
|
|
49
|
+
大多数工具逼你在*写作*、*搜索*、*记忆*之间三选一。Stellavault 三者兼得 — 在本地,并以 Claude 能读取的方式。
|
|
50
|
+
|
|
51
|
+
| | **Stellavault** | Obsidian | Notion | 自写 RAG |
|
|
52
|
+
|---|:---:|:---:|:---:|:---:|
|
|
53
|
+
| 本地优先、离线可用 | ✅ | ✅ | ☁️ 云端 | ⚠️ 通常云端 |
|
|
54
|
+
| 无需 API 密钥的语义搜索 | ✅ | ⚠️ 插件+密钥 | 💰 付费 AI | ⚠️ 需密钥 |
|
|
55
|
+
| 原始文件永不修改 | ✅ | ✅ | ❌ 专有格式 | ➖ |
|
|
56
|
+
| 自编译(摄取 → wiki) | ✅ | ❌ | ❌ | ❌ |
|
|
57
|
+
| 3D 知识图谱 | ✅ | 2D / 插件 | ❌ | ❌ |
|
|
58
|
+
| 间隔重复衰减(FSRS) | ✅ | ⚠️ 插件 | ❌ | ❌ |
|
|
59
|
+
| 缺口 / 矛盾 / 重复检测 | ✅ | ❌ | ❌ | ❌ |
|
|
60
|
+
| MCP 原生(Claude 读取你的仓库) | ✅ | ➖ 社区 | ☁️ 云端 | ➖ |
|
|
61
|
+
|
|
62
|
+
> [!NOTE]
|
|
63
|
+
> 并非二选一 — Stellavault 甚至能**在 Obsidian 内**以[插件](https://github.com/Evanciel/stellavault-obsidian)形式运行。留住你的编辑器,加一个大脑。
|
|
64
|
+
|
|
65
|
+
## 安装
|
|
66
|
+
|
|
67
|
+
### 桌面应用 (推荐 — 一键搞定)
|
|
68
|
+
|
|
69
|
+
<table>
|
|
70
|
+
<tr>
|
|
71
|
+
<td align="center"><a href="https://github.com/Evanciel/stellavault/releases/download/desktop-v0.3.0/Stellavault-win32-x64-0.3.0.zip"><br/><b>⬇ 下载 Windows 版</b><br/><sub>x64 · 273 MB · ZIP</sub></a></td>
|
|
72
|
+
<td align="center"><a href="https://github.com/Evanciel/stellavault/releases/download/desktop-v0.3.0/Stellavault-linux-x64-0.3.0.zip"><br/><b>⬇ 下载 Linux 版</b><br/><sub>x64 · 243 MB · ZIP</sub></a></td>
|
|
73
|
+
<td align="center"><br/><b>macOS</b><br/><sub>即将推出</sub></td>
|
|
74
|
+
</tr>
|
|
75
|
+
</table>
|
|
76
|
+
|
|
77
|
+
> [!TIP]
|
|
78
|
+
> 下载 → 解压 → 运行 `stellavault.exe`(Windows) 或 `stellavault`(Linux) → 选择笔记文件夹 → 完成。
|
|
79
|
+
|
|
80
|
+
### CLI (面向开发者)
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
npm install -g stellavault # 或: npx stellavault
|
|
84
|
+
stellavault init # 交互式配置 (3 分钟): 索引仓库 + 连接 AI 客户端
|
|
85
|
+
stellavault setup # 连接 Claude Code/Desktop、Cursor、Windsurf、VS Code (一条命令)
|
|
86
|
+
stellavault graph # 在浏览器中启动 3D 图谱
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
> 需要 Node.js 20+。遇到问题请运行 `stellavault doctor` 进行诊断。
|
|
90
|
+
|
|
91
|
+
### Obsidian 插件
|
|
92
|
+
|
|
93
|
+
1. 从 [stellavault-obsidian releases](https://github.com/Evanciel/stellavault-obsidian/releases/latest) 下载 `main.js` + `manifest.json` + `styles.css`
|
|
94
|
+
2. 放入 `.obsidian/plugins/stellavault/`
|
|
95
|
+
3. 在 设置 → 社区插件 中启用
|
|
96
|
+
4. 在仓库文件夹启动 API: `npx stellavault graph`
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 编辑器
|
|
101
|
+
|
|
102
|
+
功能完整的 Markdown 编辑器 — 可与 Obsidian 媲美。
|
|
103
|
+
|
|
104
|
+
<details>
|
|
105
|
+
<summary><b>完整的格式与块支持</b> — 表格、代码、KaTeX、斜杠命令、wikilink、分屏… <i>(点击展开)</i></summary>
|
|
106
|
+
|
|
107
|
+
<br/>
|
|
108
|
+
|
|
109
|
+
| 功能 | 状态 |
|
|
110
|
+
|---------|--------|
|
|
111
|
+
| 加粗、斜体、下划线、删除线 | ✅ |
|
|
112
|
+
| 标题 1–6 级 | ✅ |
|
|
113
|
+
| 无序、有序、任务列表 (嵌套复选框) | ✅ |
|
|
114
|
+
| 表格 (创建、调整列宽、增删行列) | ✅ |
|
|
115
|
+
| 带语法高亮的代码块 (40+ 语言) | ✅ |
|
|
116
|
+
| 图片 (URL、剪贴板粘贴、拖放) | ✅ |
|
|
117
|
+
| KaTeX 数学渲染 (`$E=mc^2$` 行内, `$$...$$` 独立) | ✅ |
|
|
118
|
+
| `/斜杠命令` (12 种块, 模糊搜索) | ✅ |
|
|
119
|
+
| `[[wikilink]]` 自动补全 | ✅ |
|
|
120
|
+
| 分屏视图 (垂直 + 水平, Ctrl+\\) | ✅ |
|
|
121
|
+
| 文本对齐 (左 / 中 / 右) | ✅ |
|
|
122
|
+
| 高亮、上标、下标 | ✅ |
|
|
123
|
+
| 智能排版 (弯引号、em/en 破折号) | ✅ |
|
|
124
|
+
| 水平分隔线 | ✅ |
|
|
125
|
+
|
|
126
|
+
</details>
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 流水线
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
捕获 ──→ 整理 ──→ 提炼 ──→ 表达
|
|
134
|
+
(Capture ──→ Organize ──→ Distill ──→ Express)
|
|
135
|
+
|
|
136
|
+
丢进任何东西 → 自动抽取 → raw/ → 编译 → _wiki/ → 草稿
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
灵感来自 Karpathy 的自编译知识架构。
|
|
140
|
+
|
|
141
|
+
### 摄取(Ingest) 14 种格式
|
|
142
|
+
|
|
143
|
+
| 输入 | 方式 |
|
|
144
|
+
|-------|-----|
|
|
145
|
+
| PDF, DOCX, PPTX, XLSX | `stellavault ingest report.pdf` |
|
|
146
|
+
| JSON, CSV, XML, YAML, HTML, RTF | `stellavault ingest data.json` |
|
|
147
|
+
| YouTube | `stellavault ingest https://youtu.be/...` — 字幕 + 时间戳 |
|
|
148
|
+
| URL | `stellavault ingest https://...` — HTML → Markdown |
|
|
149
|
+
| 文本 | `stellavault ingest "一闪而过的想法"` |
|
|
150
|
+
| 文件夹 | `stellavault ingest ./papers/` — 批量处理所有文件 |
|
|
151
|
+
| 桌面 / Web UI | 直接拖放文件 |
|
|
152
|
+
|
|
153
|
+
### 表达(Express): 把知识取出来
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
stellavault draft "AI" --format blog # 基于仓库的博客文章
|
|
157
|
+
stellavault draft "AI" --format outline # 结构化大纲
|
|
158
|
+
stellavault draft "AI" --ai # Claude API 增强 ($0.03)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
或使用桌面应用的 **Express 标签页** — 输入主题、选择格式,即可生成一篇以你的仓库为依据的草稿。保存到 `_drafts/` 并行内编辑。
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## 智能功能
|
|
166
|
+
|
|
167
|
+
> 这些功能在 Obsidian 中 **并不存在** — 即使装了插件也没有。
|
|
168
|
+
|
|
169
|
+
| 功能 | 命令 / 桌面 | 说明 |
|
|
170
|
+
|---------|-------------------|-------------|
|
|
171
|
+
| **记忆衰减(Memory Decay)** | `stellavault decay` / Memory 标签页 | 基于 FSRS — 显示你正在遗忘的真实笔记 |
|
|
172
|
+
| **知识缺口(Knowledge Gaps)** | `stellavault gaps` | 检测主题簇之间的薄弱连接 |
|
|
173
|
+
| **矛盾(Contradictions)** | `stellavault contradictions` | 发现仓库中互相冲突的表述 |
|
|
174
|
+
| **重复(Duplicates)** | `stellavault duplicates` | 带相似度分数的近似重复笔记 |
|
|
175
|
+
| **健康检查(Health Check)** | `stellavault lint` | 汇总的仓库健康分 (0–100) |
|
|
176
|
+
| **学习路径(Learning Path)** | `stellavault learn` | AI 个性化复习推荐 |
|
|
177
|
+
| **每日简报** | 桌面应用主屏 | 推送式: 打开应用即显示衰减最严重的笔记 + 统计 |
|
|
178
|
+
| **自动打标签** | 摄取时自动 | 基于内容的关键词抽取 + 分类规则 |
|
|
179
|
+
| **自编译** | `stellavault compile` | raw/ → _wiki/,自动抽取概念 + 反向链接 |
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## 搜索与排名
|
|
184
|
+
|
|
185
|
+
用 **加权 RRF(Reciprocal Rank Fusion)** 融合多种信号的混合检索 — 专为个人知识仓库调优,完全本地,零 API 密钥:
|
|
186
|
+
|
|
187
|
+
| 信号 | 捕捉什么 | 默认权重 |
|
|
188
|
+
|--------|------------------|---------------:|
|
|
189
|
+
| **语义**(dense) | 含义; 多语言 (50+ 种语言) | `1.0` |
|
|
190
|
+
| **BM25**(关键词) | 精确词项、代码、名称 | `1.0` |
|
|
191
|
+
| **实体链接** | 你的 `[[wikilink]]`、`#标签`、标题、小标题 — 经过精选的图谱 | `1.5` |
|
|
192
|
+
| **FSRS 时新性** | 温和地浮现你正在使用 / 正在遗忘的笔记 | `±10%` |
|
|
193
|
+
|
|
194
|
+
- **实体匹配** 通过模糊子串 + 标点归一化匹配来解析自然语言查询(对韩语 / CJK 友好)。并配有 **单文档多样性上限(per-document diversity cap)**,防止某一篇大笔记霸占搜索结果顶部。
|
|
195
|
+
- **时新性** 复用与衰减引擎相同的 FSRS 记忆模型(而非简单的文件修改时间 mtime)— 正在遗忘的笔记会重新浮现,而已掌握的常青笔记不会仅因为"旧"就被埋没。
|
|
196
|
+
- **自适应重排序**(长时间运行的 MCP 服务器)还会根据你当前的会话上下文(最近的标签 / 路径)进一步提升结果。
|
|
197
|
+
- 每个权重都可按仓库或通过环境变量 **调优** — 参见 [配置](#配置)。
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## MCP 集成 (21 个工具)
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
stellavault setup # 一条命令 → Claude Code、Claude Desktop、Cursor、Windsurf、VS Code
|
|
205
|
+
# 或仅连接 Claude Code:
|
|
206
|
+
claude mcp add stellavault -- stellavault serve
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
<details>
|
|
210
|
+
<summary>手动配置 (任意 MCP 客户端) — 复制粘贴 JSON</summary>
|
|
211
|
+
|
|
212
|
+
```json
|
|
213
|
+
{
|
|
214
|
+
"mcpServers": {
|
|
215
|
+
"stellavault": {
|
|
216
|
+
"command": "npx",
|
|
217
|
+
"args": ["-y", "stellavault", "serve"]
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
已在 [MCP 注册表](https://registry.modelcontextprotocol.io) 注册为 `io.github.Evanciel/stellavault`(也可在 Glama、Smithery、mcp.so 中发现)。
|
|
224
|
+
</details>
|
|
225
|
+
|
|
226
|
+
Claude 可以直接搜索、问答、起草、检查并分析你的仓库。搜索会运行完整的混合流水线 — 对 语义 + BM25 + 实体链接 进行 **加权 RRF**,再加上 **FSRS 时新性** 和会话自适应重排序(详见 [搜索与排名](#搜索与排名))。
|
|
227
|
+
|
|
228
|
+
| 工具 | 作用 |
|
|
229
|
+
|------|-------------|
|
|
230
|
+
| `search` | 加权 RRF (语义 + BM25 + 实体) + FSRS 时新性 + 自适应重排序 |
|
|
231
|
+
| `ask` | 基于仓库依据的问答 |
|
|
232
|
+
| `generate-draft` | 用你的知识生成 AI 草稿 |
|
|
233
|
+
| `get-decay-status` | 记忆衰减报告 (FSRS) |
|
|
234
|
+
| `detect-gaps` | 知识缺口分析 |
|
|
235
|
+
| `create-knowledge-node` | AI 创建 wiki 级别的笔记 |
|
|
236
|
+
| `federated-search` | 跨多个仓库的 P2P 搜索 |
|
|
237
|
+
| + 另外 14 个 | 文档、主题、决策、快照、导出 |
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## 3D 可视化
|
|
242
|
+
|
|
243
|
+
- 带聚类着色的神经网络图谱 (React Three Fiber)
|
|
244
|
+
- 星座视图 (MST 星形图案)
|
|
245
|
+
- 热力图叠加 + 时间轴滑块 + 衰减叠加
|
|
246
|
+
- 多元宇宙视图 — 你的仓库化作 P2P 网络中的一颗宇宙
|
|
247
|
+
- 深色/浅色主题
|
|
248
|
+
|
|
249
|
+
<table>
|
|
250
|
+
<tr>
|
|
251
|
+
<td width="50%"><img src="images/screenshots/graph-heatmap.png" alt="热力图叠加" /><br/><sub><b>热力图</b> — 各聚类间的连接密度</sub></td>
|
|
252
|
+
<td width="50%"><img src="images/screenshots/graph-timeline.png" alt="时间轴滑块" /><br/><sub><b>时间轴</b> — 按时间观看仓库的生长</sub></td>
|
|
253
|
+
</tr>
|
|
254
|
+
<tr>
|
|
255
|
+
<td><img src="images/screenshots/search-active.png" alt="语义搜索高亮" /><br/><sub><b>搜索</b> — 在图谱中高亮语义匹配</sub></td>
|
|
256
|
+
<td><img src="images/screenshots/multiverse-view.png" alt="多元宇宙 P2P 视图" /><br/><sub><b>多元宇宙</b> — 化作环绕轨道的宇宙的联邦仓库</sub></td>
|
|
257
|
+
</tr>
|
|
258
|
+
</table>
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## 立即体验 (演示仓库)
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
npx stellavault index --vault ./examples/demo-vault # 索引 10 篇示例笔记
|
|
266
|
+
npx stellavault search "vector database" # 语义搜索
|
|
267
|
+
npx stellavault graph # 3D 图谱可视化
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
演示仓库包含关于 Vector Database、Knowledge Graph、Spaced Repetition、RAG、MCP 等互相关联的笔记 — 非常适合即刻体验所有功能。
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## 入门指南
|
|
275
|
+
|
|
276
|
+
### 桌面应用
|
|
277
|
+
|
|
278
|
+
1. **下载** → 解压 → 运行
|
|
279
|
+
2. 首次启动会让你选择笔记文件夹
|
|
280
|
+
3. 笔记出现在侧边栏 — 点击即可打开
|
|
281
|
+
4. 按 `Ctrl+P` 快速切换文件
|
|
282
|
+
5. 点击标题栏的 ✦ 打开 AI 面板 (语义搜索、统计、草稿)
|
|
283
|
+
6. 点击 ◉ 查看 3D 图谱
|
|
284
|
+
|
|
285
|
+
### CLI
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
npm install -g stellavault
|
|
289
|
+
stellavault init # 配置向导
|
|
290
|
+
stellavault search "machine learning" # 语义搜索
|
|
291
|
+
stellavault ingest paper.pdf # 添加知识
|
|
292
|
+
stellavault graph # 浏览器中的 3D 图谱
|
|
293
|
+
stellavault brief # 早间简报
|
|
294
|
+
stellavault decay # 你正在遗忘什么?
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### 键盘快捷键 (桌面)
|
|
298
|
+
|
|
299
|
+
| 快捷键 | 操作 |
|
|
300
|
+
|----------|--------|
|
|
301
|
+
| `Ctrl+P` | 快速切换器 (模糊文件搜索) |
|
|
302
|
+
| `Ctrl+Shift+P` | 命令面板 (所有操作) |
|
|
303
|
+
| `Ctrl+S` | 保存当前笔记 |
|
|
304
|
+
| `Ctrl+\` | 切换分屏视图 |
|
|
305
|
+
| `Ctrl+B` | 加粗 |
|
|
306
|
+
| `Ctrl+I` | 斜体 |
|
|
307
|
+
| `Ctrl+U` | 下划线 |
|
|
308
|
+
| `Ctrl+E` | 行内代码 |
|
|
309
|
+
| `/` | 斜杠命令 (在行首) |
|
|
310
|
+
| `[[` | wikilink 自动补全 |
|
|
311
|
+
|
|
312
|
+
### 快速参考
|
|
313
|
+
|
|
314
|
+
| 操作 | 桌面 | CLI |
|
|
315
|
+
|--------|---------|-----|
|
|
316
|
+
| 搜索笔记 | Ctrl+P 或 AI 面板 | `stellavault search "query"` |
|
|
317
|
+
| 添加笔记 | + Note 按钮 或 拖放 | `stellavault ingest "text"` |
|
|
318
|
+
| 查看 3D 图谱 | ◉ 按钮 | `stellavault graph` |
|
|
319
|
+
| 记忆衰减 | AI 面板 → Memory | `stellavault decay` |
|
|
320
|
+
| 生成草稿 | AI 面板 → Draft | `stellavault draft "topic"` |
|
|
321
|
+
| 健康检查 | AI 面板 → Stats | `stellavault lint` |
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## 配置
|
|
326
|
+
|
|
327
|
+
Stellavault 会读取 `./.stellavault.json`(或 `~/.stellavault.json`)。搜索排名完全可调,开箱即用的默认值就很合理:
|
|
328
|
+
|
|
329
|
+
```jsonc
|
|
330
|
+
{
|
|
331
|
+
"search": {
|
|
332
|
+
"rrfK": 60,
|
|
333
|
+
"weights": { "semantic": 1.0, "bm25": 1.0, "entity": 1.5 },
|
|
334
|
+
"recencyWeight": 0.2, // FSRS 时新性强度; 0 = 关闭
|
|
335
|
+
"entityAliases": { "k8s": ["kubernetes"] } // 同义词 / 跨语言分组 (仅精确匹配)
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
环境变量会覆盖配置 (带防护解析):
|
|
341
|
+
|
|
342
|
+
| 环境变量 | 作用 |
|
|
343
|
+
|---------|--------|
|
|
344
|
+
| `STELLAVAULT_W_SEMANTIC` / `_BM25` / `_ENTITY` | 各信号的 RRF 权重 (例如 `STELLAVAULT_W_ENTITY=2.0` 让实体更激进地浮现) |
|
|
345
|
+
| `STELLAVAULT_RECENCY_WEIGHT` | 时新性强度 `0`–`1` (`0` 表示禁用) |
|
|
346
|
+
| `STELLAVAULT_DB_PATH` | 覆盖索引数据库位置 |
|
|
347
|
+
| `STELLAVAULT_WATCH` | 设为 `0` 可在 `serve` 运行期间禁用自动重建索引的文件监视器 |
|
|
348
|
+
|
|
349
|
+
> 注: 跨语言召回(例如用中文查询找到英文笔记)由多语言嵌入模型自动处理 — `entityAliases` 是针对精选实体图谱(标签 / wikilink)和缩写的可选精度增强。
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## 性能
|
|
354
|
+
|
|
355
|
+
在合成仓库上测试 — 典型场景下所有操作均在 1 秒以内:
|
|
356
|
+
|
|
357
|
+
| 操作 | 100 文档 | 500 文档 | 1000 文档 |
|
|
358
|
+
|-----------|----------|----------|-----------|
|
|
359
|
+
| 存储初始化 | 15ms | 15ms | 16ms |
|
|
360
|
+
| 批量 upsert | 12ms | 102ms | ~200ms |
|
|
361
|
+
| 搜索 (BM25) | <1ms | <1ms | <1ms |
|
|
362
|
+
| 获取全部文档 | <1ms | 2ms | ~4ms |
|
|
363
|
+
| 124K 次点积 | — | 36ms | — |
|
|
364
|
+
|
|
365
|
+
运行你自己的基准测试:
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
node tests/stress.mjs 500 # 用 500 篇合成文档测试
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
关键优化:
|
|
372
|
+
- **HNSW 图构建** — 对 200+ 文档使用 sqlite-vec KNN (O(n·K·log n) vs O(n²))
|
|
373
|
+
- 预归一化向量: 余弦相似度 → 单次点积
|
|
374
|
+
- 批量加载嵌入 (每批 500,防止内存溢出)
|
|
375
|
+
- 小仓库(< 200 文档)使用上三角暴力计算
|
|
376
|
+
- 用类型化数组实现 O(n) 的 K-Means 质心更新
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
## 技术栈
|
|
381
|
+
|
|
382
|
+
| 层 | 技术 |
|
|
383
|
+
|-------|------|
|
|
384
|
+
| 桌面 | Electron + React + TipTap (15 个扩展) + Zustand |
|
|
385
|
+
| 运行时 | Node.js 20+ (ESM, TypeScript) |
|
|
386
|
+
| 向量存储 | SQLite-vec (本地, 零配置) |
|
|
387
|
+
| 嵌入 | MiniLM-L12-v2 (本地, 50+ 种语言, 批处理) |
|
|
388
|
+
| 搜索 | 加权 RRF (语义 + BM25 + 实体) + FSRS 时新性 |
|
|
389
|
+
| 数学 | KaTeX (行内 + 独立) |
|
|
390
|
+
| 代码 | lowlight / highlight.js (40+ 语言) |
|
|
391
|
+
| 3D | React Three Fiber + Three.js |
|
|
392
|
+
| AI | MCP (21 个工具) + Anthropic SDK |
|
|
393
|
+
| P2P | Hyperswarm (可选, 差分隐私) |
|
|
394
|
+
| CI | GitHub Actions (Node 20 + 22) |
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
## 安全
|
|
399
|
+
|
|
400
|
+
- **本地优先** — 除非你使用 `--ai`,否则数据不会离开你的机器
|
|
401
|
+
- **仓库文件永不修改** — 只索引进 SQLite,原文件保持原样
|
|
402
|
+
- **启用 Electron 沙箱** — 渲染进程以受限的操作系统权限运行
|
|
403
|
+
- **IPC 路径校验** — 所有文件操作都限制在仓库根目录内
|
|
404
|
+
- **API 认证令牌** — 每会话、仅请求头(`X-Stellavault-Token`)。令牌端点仅限同源(same-origin)
|
|
405
|
+
- **CORS 白名单** — 默认仅 `localhost` / `127.0.0.1`; MCP HTTP 传输需显式启用
|
|
406
|
+
- **SSRF 防护** — 摄取 URL 时屏蔽内网 IP
|
|
407
|
+
- **端到端加密** — 云同步采用 AES-256-GCM
|
|
408
|
+
|
|
409
|
+
### 联邦 (实验性, 默认关闭)
|
|
410
|
+
|
|
411
|
+
P2P 语义搜索作为 **可选的实验性功能** 提供。默认安装 **不会** 加入任何 swarm,也绝不分享数据。
|
|
412
|
+
|
|
413
|
+
显式启用:
|
|
414
|
+
|
|
415
|
+
```bash
|
|
416
|
+
# PowerShell
|
|
417
|
+
$env:STELLAVAULT_FEDERATION_EXPERIMENTAL = "1"
|
|
418
|
+
|
|
419
|
+
# bash / zsh
|
|
420
|
+
export STELLAVAULT_FEDERATION_EXPERIMENTAL=1
|
|
421
|
+
|
|
422
|
+
stellavault federate join
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
启用后,联邦使用 Ed25519 身份与签名信封(signed envelope)、双向质询-应答握手、每信封重放随机数(nonce)、握手超时、按节点限速,以及"仅接收"的分享默认值(`myNodeLevel=0`)。要真正与对等节点分享标题/摘要,请在联邦提示符中运行 `set-level 1+`。
|
|
426
|
+
|
|
427
|
+
> [!WARNING]
|
|
428
|
+
> **升级提示 (v0.7.4)** — 联邦传输格式从 v2.0 升级到 v2.1(信封级 nonce)。v0.7.3 的联邦节点不兼容。现有的 `~/.stellavault/federation/sharing.json` **不会** 自动降级为更安全的默认值;若你此前曾选择加入,请复查你的 `myNodeLevel`。
|
|
429
|
+
|
|
430
|
+
完整细节见 [SECURITY.md](SECURITY.md)。
|
|
431
|
+
|
|
432
|
+
## 故障排查
|
|
433
|
+
|
|
434
|
+
```bash
|
|
435
|
+
stellavault doctor # 检查配置、仓库、数据库、模型、Node 版本
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
常见问题:
|
|
439
|
+
- **"Command not found"** → `npm i -g stellavault@latest`
|
|
440
|
+
- **"API server not found"** → `npx stellavault graph`
|
|
441
|
+
- **图谱为空** → `stellavault index`
|
|
442
|
+
- **首次运行很慢** → AI 模型首次需下载约 30MB
|
|
443
|
+
|
|
444
|
+
## 参与贡献
|
|
445
|
+
|
|
446
|
+
欢迎提交 Issue 和 Pull Request。请参阅 [CONTRIBUTING.md](CONTRIBUTING.md) 开始,并通过 [SECURITY.md](SECURITY.md) 负责任地报告漏洞。
|
|
447
|
+
|
|
448
|
+
## 许可证
|
|
449
|
+
|
|
450
|
+
MIT — 全部源代码可供审计。
|
|
451
|
+
|
|
452
|
+
## 链接
|
|
453
|
+
|
|
454
|
+
- **[⬇ 下载桌面应用](https://github.com/Evanciel/stellavault/releases/tag/desktop-v0.3.0)**
|
|
455
|
+
- [着陆页](https://evanciel.github.io/stellavault/)
|
|
456
|
+
- [Obsidian 插件](https://github.com/Evanciel/stellavault-obsidian)
|
|
457
|
+
- [npm](https://www.npmjs.com/package/stellavault)
|
|
458
|
+
- [GitHub Releases](https://github.com/Evanciel/stellavault/releases)
|
|
459
|
+
- [安全策略](SECURITY.md)
|
|
460
|
+
|
|
461
|
+
---
|
|
462
|
+
|
|
463
|
+
<div align="center">
|
|
464
|
+
|
|
465
|
+
**觉得有用?** ⭐ [**给 Stellavault 点星**](https://github.com/Evanciel/stellavault) — 这能实实在在帮助项目触达更多以连接方式思考的人。
|
|
466
|
+
|
|
467
|
+
<sub>为构建第二大脑的人们,以 ✦ 打造。 · <a href="https://github.com/Evanciel/stellavault/releases">下载</a> · <a href="#mcp-集成-21-个工具">连接 Claude</a> · <a href="https://github.com/Evanciel/stellavault/issues">报告问题</a></sub>
|
|
468
|
+
|
|
469
|
+
</div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as q,g as K}from"./index-
|
|
1
|
+
import{c as q,g as K}from"./index-nyIICe1Z.js";function L(d,m){for(var w=0;w<m.length;w++){const f=m[w];if(typeof f!="string"&&!Array.isArray(f)){for(const a in f)if(a!=="default"&&!(a in d)){const j=Object.getOwnPropertyDescriptor(f,a);j&&Object.defineProperty(d,a,j.get?j:{enumerable:!0,get:()=>f[a]})}}}return Object.freeze(Object.defineProperty(d,Symbol.toStringTag,{value:"Module"}))}var F={},T;function Q(){return T||(T=1,(function(){function d(t){var e=0;return function(){return e<t.length?{done:!1,value:t[e++]}:{done:!0}}}var m=typeof Object.defineProperties=="function"?Object.defineProperty:function(t,e,o){return t==Array.prototype||t==Object.prototype||(t[e]=o.value),t};function w(t){t=[typeof globalThis=="object"&&globalThis,t,typeof window=="object"&&window,typeof self=="object"&&self,typeof q=="object"&&q];for(var e=0;e<t.length;++e){var o=t[e];if(o&&o.Math==Math)return o}throw Error("Cannot find global object")}var f=w(this);function a(t,e){if(e)t:{var o=f;t=t.split(".");for(var i=0;i<t.length-1;i++){var s=t[i];if(!(s in o))break t;o=o[s]}t=t[t.length-1],i=o[t],e=e(i),e!=i&&e!=null&&m(o,t,{configurable:!0,writable:!0,value:e})}}a("Symbol",function(t){function e(l){if(this instanceof e)throw new TypeError("Symbol is not a constructor");return new o(i+(l||"")+"_"+s++,l)}function o(l,n){this.g=l,m(this,"description",{configurable:!0,writable:!0,value:n})}if(t)return t;o.prototype.toString=function(){return this.g};var i="jscomp_symbol_"+(1e9*Math.random()>>>0)+"_",s=0;return e}),a("Symbol.iterator",function(t){if(t)return t;t=Symbol("Symbol.iterator");for(var e="Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array".split(" "),o=0;o<e.length;o++){var i=f[e[o]];typeof i=="function"&&typeof i.prototype[t]!="function"&&m(i.prototype,t,{configurable:!0,writable:!0,value:function(){return j(d(this))}})}return t});function j(t){return t={next:t},t[Symbol.iterator]=function(){return this},t}function A(t){var e=typeof Symbol<"u"&&Symbol.iterator&&t[Symbol.iterator];return e?e.call(t):{next:d(t)}}function E(){this.i=!1,this.g=null,this.o=void 0,this.j=1,this.m=0,this.h=null}function S(t){if(t.i)throw new TypeError("Generator is already running");t.i=!0}E.prototype.l=function(t){this.o=t};function _(t,e){t.h={F:e,G:!0},t.j=t.m}E.prototype.return=function(t){this.h={return:t},this.j=this.m};function U(t){this.g=new E,this.h=t}function H(t,e){S(t.g);var o=t.g.g;return o?C(t,"return"in o?o.return:function(i){return{value:i,done:!0}},e,t.g.return):(t.g.return(e),b(t))}function C(t,e,o,i){try{var s=e.call(t.g.g,o);if(!(s instanceof Object))throw new TypeError("Iterator result "+s+" is not an object");if(!s.done)return t.g.i=!1,s;var l=s.value}catch(n){return t.g.g=null,_(t.g,n),b(t)}return t.g.g=null,i.call(t.g,l),b(t)}function b(t){for(;t.g.j;)try{var e=t.h(t.g);if(e)return t.g.i=!1,{value:e.value,done:!1}}catch(o){t.g.o=void 0,_(t.g,o)}if(t.g.i=!1,t.g.h){if(e=t.g.h,t.g.h=null,e.G)throw e.F;return{value:e.return,done:!0}}return{value:void 0,done:!0}}function I(t){this.next=function(e){return S(t.g),t.g.g?e=C(t,t.g.g.next,e,t.g.l):(t.g.l(e),e=b(t)),e},this.throw=function(e){return S(t.g),t.g.g?e=C(t,t.g.g.throw,e,t.g.l):(_(t.g,e),e=b(t)),e},this.return=function(e){return H(t,e)},this[Symbol.iterator]=function(){return this}}function G(t){function e(i){return t.next(i)}function o(i){return t.throw(i)}return new Promise(function(i,s){function l(n){n.done?i(n.value):Promise.resolve(n.value).then(e,o).then(l,s)}l(t.next())})}a("Promise",function(t){function e(n){this.h=0,this.i=void 0,this.g=[],this.o=!1;var r=this.j();try{n(r.resolve,r.reject)}catch(u){r.reject(u)}}function o(){this.g=null}function i(n){return n instanceof e?n:new e(function(r){r(n)})}if(t)return t;o.prototype.h=function(n){if(this.g==null){this.g=[];var r=this;this.i(function(){r.l()})}this.g.push(n)};var s=f.setTimeout;o.prototype.i=function(n){s(n,0)},o.prototype.l=function(){for(;this.g&&this.g.length;){var n=this.g;this.g=[];for(var r=0;r<n.length;++r){var u=n[r];n[r]=null;try{u()}catch(c){this.j(c)}}}this.g=null},o.prototype.j=function(n){this.i(function(){throw n})},e.prototype.j=function(){function n(c){return function(h){u||(u=!0,c.call(r,h))}}var r=this,u=!1;return{resolve:n(this.A),reject:n(this.l)}},e.prototype.A=function(n){if(n===this)this.l(new TypeError("A Promise cannot resolve to itself"));else if(n instanceof e)this.C(n);else{t:switch(typeof n){case"object":var r=n!=null;break t;case"function":r=!0;break t;default:r=!1}r?this.v(n):this.m(n)}},e.prototype.v=function(n){var r=void 0;try{r=n.then}catch(u){this.l(u);return}typeof r=="function"?this.D(r,n):this.m(n)},e.prototype.l=function(n){this.u(2,n)},e.prototype.m=function(n){this.u(1,n)},e.prototype.u=function(n,r){if(this.h!=0)throw Error("Cannot settle("+n+", "+r+"): Promise already settled in state"+this.h);this.h=n,this.i=r,this.h===2&&this.B(),this.H()},e.prototype.B=function(){var n=this;s(function(){if(n.I()){var r=f.console;typeof r<"u"&&r.error(n.i)}},1)},e.prototype.I=function(){if(this.o)return!1;var n=f.CustomEvent,r=f.Event,u=f.dispatchEvent;return typeof u>"u"?!0:(typeof n=="function"?n=new n("unhandledrejection",{cancelable:!0}):typeof r=="function"?n=new r("unhandledrejection",{cancelable:!0}):(n=f.document.createEvent("CustomEvent"),n.initCustomEvent("unhandledrejection",!1,!0,n)),n.promise=this,n.reason=this.i,u(n))},e.prototype.H=function(){if(this.g!=null){for(var n=0;n<this.g.length;++n)l.h(this.g[n]);this.g=null}};var l=new o;return e.prototype.C=function(n){var r=this.j();n.s(r.resolve,r.reject)},e.prototype.D=function(n,r){var u=this.j();try{n.call(r,u.resolve,u.reject)}catch(c){u.reject(c)}},e.prototype.then=function(n,r){function u(v,y){return typeof v=="function"?function(k){try{c(v(k))}catch(D){h(D)}}:y}var c,h,M=new e(function(v,y){c=v,h=y});return this.s(u(n,c),u(r,h)),M},e.prototype.catch=function(n){return this.then(void 0,n)},e.prototype.s=function(n,r){function u(){switch(c.h){case 1:n(c.i);break;case 2:r(c.i);break;default:throw Error("Unexpected state: "+c.h)}}var c=this;this.g==null?l.h(u):this.g.push(u),this.o=!0},e.resolve=i,e.reject=function(n){return new e(function(r,u){u(n)})},e.race=function(n){return new e(function(r,u){for(var c=A(n),h=c.next();!h.done;h=c.next())i(h.value).s(r,u)})},e.all=function(n){var r=A(n),u=r.next();return u.done?i([]):new e(function(c,h){function M(k){return function(D){v[k]=D,y--,y==0&&c(v)}}var v=[],y=0;do v.push(void 0),y++,i(u.value).s(M(v.length-1),h),u=r.next();while(!u.done)})},e});var N=typeof Object.assign=="function"?Object.assign:function(t,e){for(var o=1;o<arguments.length;o++){var i=arguments[o];if(i)for(var s in i)Object.prototype.hasOwnProperty.call(i,s)&&(t[s]=i[s])}return t};a("Object.assign",function(t){return t||N});var z=this||self,R={facingMode:"user",width:640,height:480};function O(t,e){this.video=t,this.i=0,this.h=Object.assign(Object.assign({},R),e)}O.prototype.stop=function(){var t=this,e,o,i,s;return G(new I(new U(function(l){if(t.g){for(e=t.g.getTracks(),o=A(e),i=o.next();!i.done;i=o.next())s=i.value,s.stop();t.g=void 0}l.j=0})))},O.prototype.start=function(){var t=this,e;return G(new I(new U(function(o){return navigator.mediaDevices&&navigator.mediaDevices.getUserMedia||alert("No navigator.mediaDevices.getUserMedia exists."),e=t.h,o.return(navigator.mediaDevices.getUserMedia({video:{facingMode:e.facingMode,width:e.width,height:e.height}}).then(function(i){$(t,i)}).catch(function(i){var s="Failed to acquire camera feed: "+i;throw console.error(s),alert(s),i}))})))};function P(t){window.requestAnimationFrame(function(){J(t)})}function $(t,e){t.g=e,t.video.srcObject=e,t.video.onloadedmetadata=function(){t.video.play(),P(t)}}function J(t){var e=null;t.video.paused||t.video.currentTime===t.i||(t.i=t.video.currentTime,e=t.h.onFrame()),e?e.then(function(){P(t)}):P(t)}var x=["Camera"],g=z;x[0]in g||typeof g.execScript>"u"||g.execScript("var "+x[0]);for(var p;x.length&&(p=x.shift());)x.length||O===void 0?g[p]&&g[p]!==Object.prototype[p]?g=g[p]:g=g[p]={}:g[p]=O}).call(F)),F}var B=Q();const V=K(B),X=L({__proto__:null,default:V},[B]);export{X as c};
|