dsh-obsidian-bridge 0.1.15 → 0.1.18
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.md +72 -70
- package/README.zh.md +108 -0
- package/client.js +47 -2
- package/package.json +1 -1
- package/src/host/tools.js +4 -1
- package/README.en.md +0 -108
package/README.md
CHANGED
|
@@ -1,105 +1,107 @@
|
|
|
1
1
|
# Obsidian Vault Studio
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+

|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Connect a local Obsidian vault to DeepSeek Harness. After you grant access, the model can search your notes, read relevant passages, build grounded context, and create or append notes through a proposal-first workflow. The index, embeddings, and statistics stay on your machine.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
[中文](README.zh.md)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
[](https://www.npmjs.com/package/dsh-obsidian-bridge)[](https://github.com/spark-ai-boy/dsh-obsidian-bridge)
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
- **可用的检索**:默认关键词检索,支持英文前缀和输入时自动更新结果;可选 OpenAI 兼容或 Ollama Embedding,启用混合/语义检索。
|
|
13
|
-
- **会话访问开关**:默认禁止模型访问 Vault。关闭时所有 `obsidian_*` Agent 工具都会被拒绝,你自己的检索和笔记浏览不受影响。
|
|
14
|
-
- **安全写入**:模型只能提出新建或追加提案;你确认后才落盘。每次写入有备份,可撤销;不提供删除、移动、重命名或覆盖工具。
|
|
15
|
-
- **数据大盘**:笔记/字数/标签/片段统计、每日热度、活动曲线、Agent 调用次数、最近编辑和标签分布。
|
|
16
|
-
- **完全本地**:索引、向量、设置和调用统计都保存在本机。
|
|
11
|
+
## What it does
|
|
17
12
|
|
|
18
|
-
|
|
13
|
+
- **Local index** — parses Markdown, frontmatter, tags, headings, and modification times without uploading the whole vault.
|
|
14
|
+
- **Practical retrieval** — keyword search by default, with English prefix matching and live results; optional OpenAI-compatible or Ollama embeddings enable hybrid and semantic modes.
|
|
15
|
+
- **Conversation access switch** — model access is off by default. When off, every `obsidian_*` Agent tool is denied; your own search and note browsing keep working.
|
|
16
|
+
- **Safe writes** — the model can only propose a create or append. Nothing is written until you approve; writes are backed up and can be undone. There are no delete, move, rename, or overwrite tools.
|
|
17
|
+
- **Dashboard** — note, word, tag, and chunk counts; a daily heatmap; a 14-day activity curve; Agent call counters; recent notes and tag distribution.
|
|
18
|
+
- **Local by design** — index, vectors, settings, and usage counters all stay on your machine.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
## Install
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
- 一个本地 Obsidian Vault
|
|
22
|
+
### Requirements
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
- DeepSeek Harness 0.2.x desktop, with third-party plugin installation enabled
|
|
25
|
+
- A local Obsidian vault
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
### Install source
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
- **npm 包**:`dsh-obsidian-bridge`
|
|
29
|
+
DeepSeek Harness can install the plugin from either a GitHub repository or an npm package:
|
|
31
30
|
|
|
32
|
-
|
|
31
|
+
- **GitHub repository**: `https://github.com/spark-ai-boy/dsh-obsidian-bridge`
|
|
32
|
+
- **npm package**: `dsh-obsidian-bridge`
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
2. 点击 **添加插件** → **安装第三方插件**。
|
|
36
|
-
3. 在输入框中填写上面的 **GitHub 仓库地址** 或 **npm 包名**,然后点击安装;安装完成后点击启用。
|
|
37
|
-
4. 在左侧栏打开 **Obsidian 知识库**。
|
|
34
|
+
### Steps
|
|
38
35
|
|
|
39
|
-
|
|
36
|
+
1. Open **Plugins** in the DeepSeek Harness sidebar.
|
|
37
|
+
2. Choose **Add plugin** → **Install third-party plugin**.
|
|
38
|
+
3. Enter either the **GitHub repository URL** or the **npm package name** above, install it, then click **Enable**.
|
|
39
|
+
4. Open **Obsidian Vault Studio** in the sidebar.
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+

|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
2. 点击 **重建索引**。第一次索引完成后,概览和检索就可以用了。
|
|
45
|
-
3. 检索模式默认是 **关键词**,不需要额外配置。
|
|
46
|
-
4. 如果要使用语义或混合检索,在设置里填写 OpenAI 兼容或 Ollama 的 Embedding 地址、模型和维度,先点 **测试连接**,保存后再重建索引。
|
|
47
|
-
5. 首页右侧的 **允许 Obsidian 内容参与会话** 默认关闭。需要 Agent 使用 Vault 时再打开;关闭后所有 `obsidian_*` 工具调用会被直接拒绝。
|
|
43
|
+
## First run
|
|
48
44
|
|
|
49
|
-
|
|
45
|
+
1. Open **Settings**, choose your vault path, and click **Save**.
|
|
46
|
+
2. Click **Rebuild index**. The dashboard and search become available once the first index completes.
|
|
47
|
+
3. Retrieval mode defaults to **Keyword**; no extra setup is needed.
|
|
48
|
+
4. For semantic or hybrid search, enter an OpenAI-compatible or Ollama embedding endpoint, model, and dimensions in Settings. Click **Test connection**, save, then rebuild the index.
|
|
49
|
+
5. The **Allow vault context in conversations** switch on the dashboard is off by default. Turn it on when you want the Agent to use the vault; when off, every `obsidian_*` tool call is denied.
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+

|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
## Usage
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
### Dashboard
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
The home page shows note, word, tag, 7-day update, and chunk counts; a 365-day heatmap; a 14-day activity curve; Agent call counters; recent notes; and tag distribution.
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
### Search
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
Type a keyword or prefix on the **Search** page; results update as you type. Filter by folder or tag, add passages to the **Context** tray, then copy a source-attributed context packet or let the Agent search through tools.
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+

|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
### Notes
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
2. 页面展示目标路径和 diff。
|
|
69
|
-
3. 你确认后才会写入。
|
|
70
|
-
4. 写入后可以撤销,插件会保留备份。
|
|
67
|
+
Browse and read notes on the **Notes** page. Model writes follow a proposal flow:
|
|
71
68
|
|
|
72
|
-
|
|
69
|
+
1. The model proposes new or appended content.
|
|
70
|
+
2. The page shows the target path and a diff.
|
|
71
|
+
3. Nothing is written until you approve.
|
|
72
|
+
4. Writes can be undone and are backed up.
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
2. 在 DeepSeek Harness 会话里让模型检索你的笔记,例如:
|
|
76
|
-
- “从我的 Obsidian 里找 RAG 相关的笔记,并给出处。”
|
|
77
|
-
- “把今天的会议记录追加到项目笔记里。”
|
|
78
|
-
3. 只有实际检索到或读取的片段会进入会话,不会自动把整个 Vault 塞进 prompt。
|
|
79
|
-
4. 不需要时关闭访问开关,后续工具调用会被拒绝。
|
|
74
|
+
### Use in a conversation
|
|
80
75
|
|
|
81
|
-
|
|
76
|
+
1. Turn on **Allow vault context in conversations** on the dashboard.
|
|
77
|
+
2. Ask the model to search your notes, for example:
|
|
78
|
+
- "Find my notes about RAG and cite the sources."
|
|
79
|
+
- "Append today's meeting notes to the project note."
|
|
80
|
+
3. Only passages actually retrieved or read enter the conversation; the whole vault is never injected automatically.
|
|
81
|
+
4. Turn the access switch off when you no longer need it. Later tool calls will be denied.
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
### Agent tools
|
|
84
|
+
|
|
85
|
+
| Tool | Purpose |
|
|
84
86
|
| --- | --- |
|
|
85
|
-
| `obsidian_search` |
|
|
86
|
-
| `obsidian_read_note` |
|
|
87
|
-
| `obsidian_list_notes` |
|
|
88
|
-
| `obsidian_stats` |
|
|
89
|
-
| `obsidian_propose_write` |
|
|
90
|
-
| `obsidian_apply_write` |
|
|
91
|
-
| `obsidian_undo_write` |
|
|
92
|
-
| `obsidian_index_status` |
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
##
|
|
97
|
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
-
|
|
87
|
+
| `obsidian_search` | Search note passages by mode, folder, or tag |
|
|
88
|
+
| `obsidian_read_note` | Read a full note |
|
|
89
|
+
| `obsidian_list_notes` | List or filter notes |
|
|
90
|
+
| `obsidian_stats` | Read index, statistics, and workspace status |
|
|
91
|
+
| `obsidian_propose_write` | Create a create/append proposal without writing |
|
|
92
|
+
| `obsidian_apply_write` | Apply a proposal after your approval |
|
|
93
|
+
| `obsidian_undo_write` | Undo a write from this session |
|
|
94
|
+
| `obsidian_index_status` | Check indexing and embedding progress |
|
|
95
|
+
|
|
96
|
+
The plugin has no delete, move, rename, or overwrite tools.
|
|
97
|
+
|
|
98
|
+
## Privacy and safety
|
|
99
|
+
|
|
100
|
+
- The index, vectors, settings, and usage counters are local. The plugin contains no telemetry and does not upload the vault.
|
|
101
|
+
- When **Allow vault context in conversations** is off, every `obsidian_*` Agent tool is denied before execution. Vault Studio's own search and browsing remain available.
|
|
102
|
+
- The system prompt tells the model to report Obsidian tool failures and never bypass Vault Studio or the access switch through generic file tools.
|
|
103
|
+
- The access switch only gates `obsidian_*` tools. For a hard boundary, also check DeepSeek Harness workspace/sandbox permissions so generic `read`, `grep`, and `bash` cannot reach the vault path.
|
|
104
|
+
- Writes require approval, keep backups, and can be undone. The plugin never deletes or overwrites notes automatically.
|
|
103
105
|
|
|
104
106
|
## License
|
|
105
107
|
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Obsidian Vault Studio
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
把本地 Obsidian 知识库接入 DeepSeek Harness。模型经你授权后可以检索笔记、读取片段、组装上下文,并以“先提案、后写入”的方式创建或追加笔记。索引、向量和统计都留在本机。
|
|
6
|
+
|
|
7
|
+
[English](README.md)
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/dsh-obsidian-bridge)[](https://github.com/spark-ai-boy/dsh-obsidian-bridge)
|
|
10
|
+
|
|
11
|
+
## 能做什么
|
|
12
|
+
|
|
13
|
+
- **本地索引**:解析 Markdown、frontmatter、标签、标题与修改时间,不把整个 Vault 上传到远端。
|
|
14
|
+
- **可用的检索**:默认关键词检索,支持英文前缀和输入时自动更新结果;可选 OpenAI 兼容或 Ollama Embedding,启用混合/语义检索。
|
|
15
|
+
- **会话访问开关**:默认禁止模型访问 Vault。关闭时所有 `obsidian_*` Agent 工具都会被拒绝,你自己的检索和笔记浏览不受影响。
|
|
16
|
+
- **安全写入**:模型只能提出新建或追加提案;你确认后才落盘。每次写入有备份,可撤销;不提供删除、移动、重命名或覆盖工具。
|
|
17
|
+
- **数据大盘**:笔记/字数/标签/片段统计、每日热度、活动曲线、Agent 调用次数、最近编辑和标签分布。
|
|
18
|
+
- **完全本地**:索引、向量、设置和调用统计都保存在本机。
|
|
19
|
+
|
|
20
|
+
## 安装
|
|
21
|
+
|
|
22
|
+
### 要求
|
|
23
|
+
|
|
24
|
+
- DeepSeek Harness 0.2.x 桌面版,支持安装第三方插件
|
|
25
|
+
- 一个本地 Obsidian Vault
|
|
26
|
+
|
|
27
|
+
### 安装方式
|
|
28
|
+
|
|
29
|
+
DeepSeek Harness 支持从 GitHub 仓库或 npm 包安装,二选一:
|
|
30
|
+
|
|
31
|
+
- **GitHub 仓库**:`https://github.com/spark-ai-boy/dsh-obsidian-bridge`
|
|
32
|
+
- **npm 包**:`dsh-obsidian-bridge`
|
|
33
|
+
|
|
34
|
+
### 步骤
|
|
35
|
+
|
|
36
|
+
1. 在 DeepSeek Harness 左侧栏打开 **插件**。
|
|
37
|
+
2. 点击 **添加插件** → **安装第三方插件**。
|
|
38
|
+
3. 在输入框中填写上面的 **GitHub 仓库地址** 或 **npm 包名**,然后点击安装;安装完成后点击启用。
|
|
39
|
+
4. 在左侧栏打开 **Obsidian 知识库**。
|
|
40
|
+
|
|
41
|
+

|
|
42
|
+
|
|
43
|
+
## 首次配置
|
|
44
|
+
|
|
45
|
+
1. 在 **设置** 里选择 Vault 路径,点击 **保存**。
|
|
46
|
+
2. 点击 **重建索引**。第一次索引完成后,概览和检索就可以用了。
|
|
47
|
+
3. 检索模式默认是 **关键词**,不需要额外配置。
|
|
48
|
+
4. 如果要使用语义或混合检索,在设置里填写 OpenAI 兼容或 Ollama 的 Embedding 地址、模型和维度,先点 **测试连接**,保存后再重建索引。
|
|
49
|
+
5. 首页右侧的 **允许 Obsidian 内容参与会话** 默认关闭。需要 Agent 使用 Vault 时再打开;关闭后所有 `obsidian_*` 工具调用会被直接拒绝。
|
|
50
|
+
|
|
51
|
+

|
|
52
|
+
|
|
53
|
+
## 使用
|
|
54
|
+
|
|
55
|
+
### 概览
|
|
56
|
+
|
|
57
|
+
首页集中展示知识库状态:笔记数量、字数、标签、近 7 天更新、片段数、每日热度、14 天活动曲线、Agent 调用次数和最近编辑。
|
|
58
|
+
|
|
59
|
+
### 检索
|
|
60
|
+
|
|
61
|
+
在 **检索** 页输入关键词或前缀,结果会随输入自动更新。可以按文件夹、标签筛选,把需要的片段加入右侧 **上下文**,再复制为带来源的上下文包,或直接让 Agent 通过工具检索。
|
|
62
|
+
|
|
63
|
+

|
|
64
|
+
|
|
65
|
+
### 笔记
|
|
66
|
+
|
|
67
|
+
在 **笔记** 页浏览和阅读笔记。模型写入走提案流程:
|
|
68
|
+
|
|
69
|
+
1. 模型提出新建或追加内容。
|
|
70
|
+
2. 页面展示目标路径和 diff。
|
|
71
|
+
3. 你确认后才会写入。
|
|
72
|
+
4. 写入后可以撤销,插件会保留备份。
|
|
73
|
+
|
|
74
|
+
### 在会话中使用
|
|
75
|
+
|
|
76
|
+
1. 打开首页右侧的 **允许 Obsidian 内容参与会话**。
|
|
77
|
+
2. 在 DeepSeek Harness 会话里让模型检索你的笔记,例如:
|
|
78
|
+
- “从我的 Obsidian 里找 RAG 相关的笔记,并给出处。”
|
|
79
|
+
- “把今天的会议记录追加到项目笔记里。”
|
|
80
|
+
3. 只有实际检索到或读取的片段会进入会话,不会自动把整个 Vault 塞进 prompt。
|
|
81
|
+
4. 不需要时关闭访问开关,后续工具调用会被拒绝。
|
|
82
|
+
|
|
83
|
+
### Agent 工具
|
|
84
|
+
|
|
85
|
+
| 工具 | 用途 |
|
|
86
|
+
| --- | --- |
|
|
87
|
+
| `obsidian_search` | 检索笔记片段,支持模式、文件夹、标签筛选 |
|
|
88
|
+
| `obsidian_read_note` | 读取某篇笔记的完整内容 |
|
|
89
|
+
| `obsidian_list_notes` | 列出笔记或按条件筛选 |
|
|
90
|
+
| `obsidian_stats` | 读取索引、统计和工作区状态 |
|
|
91
|
+
| `obsidian_propose_write` | 生成新建/追加提案,不直接写入 |
|
|
92
|
+
| `obsidian_apply_write` | 在你确认后应用提案 |
|
|
93
|
+
| `obsidian_undo_write` | 撤销本次会话中的写入 |
|
|
94
|
+
| `obsidian_index_status` | 查看索引和向量化进度 |
|
|
95
|
+
|
|
96
|
+
插件不提供删除、移动、重命名或覆盖笔记的工具。
|
|
97
|
+
|
|
98
|
+
## 隐私与安全
|
|
99
|
+
|
|
100
|
+
- 索引、向量、设置、调用统计都在本机。插件不包含遥测,也不会上传 Vault。
|
|
101
|
+
- **允许 Obsidian 内容参与会话**关闭时,所有 `obsidian_*` Agent 工具在执行前被拒绝;Vault Studio 自己的检索和浏览仍然可用。
|
|
102
|
+
- 系统提示要求模型在 Obsidian 工具失败时报告错误,不得通过通用文件工具绕过 Vault Studio 或访问开关。
|
|
103
|
+
- 访问开关只限制 `obsidian_*` 工具;如果你需要更严格的隔离,请同时检查 DeepSeek Harness 的 workspace/sandbox 权限,避免通用 `read`、`grep`、`bash` 直接访问 Vault 路径。
|
|
104
|
+
- 写入操作需要确认,带备份,可撤销;插件不会自动删除或覆盖笔记。
|
|
105
|
+
|
|
106
|
+
## License
|
|
107
|
+
|
|
108
|
+
[MIT](LICENSE)
|
package/client.js
CHANGED
|
@@ -8,6 +8,7 @@ window.__ModuleLoader__.load({
|
|
|
8
8
|
const NS = "obsidian-vault-studio";
|
|
9
9
|
const PANEL_ID = "obsidian-vault-studio";
|
|
10
10
|
const NAMESPACE = "obsidianVault";
|
|
11
|
+
const REPO_URL = "https://github.com/spark-ai-boy/dsh-obsidian-bridge";
|
|
11
12
|
|
|
12
13
|
const DICT = {
|
|
13
14
|
en: {
|
|
@@ -205,7 +206,13 @@ window.__ModuleLoader__.load({
|
|
|
205
206
|
"index.chunks": "Chunks",
|
|
206
207
|
"index.vectors": "Vectors",
|
|
207
208
|
"index.idle": "idle",
|
|
208
|
-
"index.ready": "ready"
|
|
209
|
+
"index.ready": "ready",
|
|
210
|
+
"github.kicker": "OPEN SOURCE · BUILT IN PUBLIC",
|
|
211
|
+
"github.title": "Follow Obsidian Vault Studio on GitHub",
|
|
212
|
+
"github.body": "New features and fixes land in the repository first. Star the project to keep up, and open an issue to shape what comes next.",
|
|
213
|
+
"github.cta": "Star on GitHub",
|
|
214
|
+
"github.aria": "Open the dsh-obsidian-bridge repository on GitHub",
|
|
215
|
+
"github.repo": "spark-ai-boy / dsh-obsidian-bridge"
|
|
209
216
|
},
|
|
210
217
|
zh: {
|
|
211
218
|
"panel": "Obsidian 知识库",
|
|
@@ -402,7 +409,13 @@ window.__ModuleLoader__.load({
|
|
|
402
409
|
"index.chunks": "片段",
|
|
403
410
|
"index.vectors": "向量",
|
|
404
411
|
"index.idle": "空闲",
|
|
405
|
-
"index.ready": "就绪"
|
|
412
|
+
"index.ready": "就绪",
|
|
413
|
+
"github.kicker": "开源项目 · 与社区共建",
|
|
414
|
+
"github.title": "在 GitHub 上关注 Obsidian Vault Studio",
|
|
415
|
+
"github.body": "新功能与修复会先在仓库发布。给项目点个 Star 关注更新,也欢迎提 Issue 告诉我们你希望它变成什么样。",
|
|
416
|
+
"github.cta": "去 GitHub 加 Star",
|
|
417
|
+
"github.aria": "在 GitHub 上打开 dsh-obsidian-bridge 仓库",
|
|
418
|
+
"github.repo": "spark-ai-boy / dsh-obsidian-bridge"
|
|
406
419
|
}
|
|
407
420
|
};
|
|
408
421
|
|
|
@@ -852,6 +865,18 @@ window.__ModuleLoader__.load({
|
|
|
852
865
|
.vs-stat-grid .vs-stat-label { font: var(--dsw-font-xxxs-11); }
|
|
853
866
|
.vs-stat-grid .vs-stat-foot { font: var(--dsw-font-xxxs-11); margin-top: 4px; }
|
|
854
867
|
.vs-dash-grid { gap: 10px; }
|
|
868
|
+
.vs-github { display: flex; align-items: center; gap: 13px; padding: 12px 14px; border: 1px solid color-mix(in srgb, var(--vs-violet) 26%, var(--vs-line)); border-radius: 10px; background: linear-gradient(100deg, color-mix(in srgb, var(--vs-violet) 8%, var(--vs-card)), var(--vs-card) 62%); text-decoration: none; color: inherit; transition: .16s; }
|
|
869
|
+
.vs-github:hover { border-color: color-mix(in srgb, var(--vs-violet) 52%, var(--vs-line)); background: linear-gradient(100deg, color-mix(in srgb, var(--vs-violet) 12%, var(--vs-card)), var(--vs-card) 62%); }
|
|
870
|
+
.vs-github-mark { width: 40px; height: 40px; flex: none; border-radius: 10px; display: grid; place-items: center; background: var(--vs-fg); color: var(--vs-bg); box-shadow: 0 10px 24px -16px color-mix(in srgb, var(--vs-fg) 70%, transparent); }
|
|
871
|
+
.vs-github-copy { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
|
|
872
|
+
.vs-github-copy b { font: 600 14px/19px var(--dsw-font-family); }
|
|
873
|
+
.vs-github-copy > span { color: var(--vs-muted); font: var(--dsw-font-xxs-12); line-height: 1.5; }
|
|
874
|
+
.vs-github-side { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 5px; }
|
|
875
|
+
.vs-github-repo { color: var(--vs-soft); font: var(--dsw-font-xxxs-11); letter-spacing: .01em; }
|
|
876
|
+
.vs-github-cta { height: 30px; display: inline-flex; align-items: center; gap: 6px; padding: 0 11px; border-radius: 7px; background: var(--vs-fg); color: var(--vs-bg); font: var(--dsw-font-xxs-12); white-space: nowrap; }
|
|
877
|
+
.vs-github-cta svg:first-child { color: #f5c451; }
|
|
878
|
+
.vs-github:hover .vs-github-cta { opacity: .9; }
|
|
879
|
+
@media (max-width: 760px) { .vs-github { align-items: flex-start; flex-wrap: wrap; } .vs-github-copy { flex-basis: calc(100% - 53px); } .vs-github-side { width: 100%; flex-direction: row; align-items: center; justify-content: space-between; padding-left: 53px; } }
|
|
855
880
|
@media (max-width: 1180px) { .vs-dash-grid > .vs-span-7, .vs-dash-grid > .vs-span-5 { grid-column: span 12; } .vs-orbit { width: 230px; height: 178px; } }
|
|
856
881
|
@media (max-width: 1180px) { .vs-dash-grid > .vs-span-7, .vs-dash-grid > .vs-span-5 { grid-column: span 12; } .vs-orbit { width: 260px; height: 210px; } }
|
|
857
882
|
@media (max-width: 900px) { .vs-hero { align-items: flex-start; flex-direction: column; } .vs-orbit { display: none; } .vs-dashboard .vs-hero h2 { font-size: 27px; line-height: 34px; } .vs-head-actions { gap: 6px; } .vs-topline { align-items: flex-start; flex-direction: column; } .vs-topline-path { max-width: 100%; } }
|
|
@@ -873,6 +898,8 @@ window.__ModuleLoader__.load({
|
|
|
873
898
|
arrow: [h("path", { key: "a", d: "M5 12h13M13 6l6 6-6 6" })],
|
|
874
899
|
file: [h("path", { key: "a", d: "M6 3.5h8.5L19 8v12.5H6A1.5 1.5 0 0 1 4.5 19V5A1.5 1.5 0 0 1 6 3.5Z" }), h("path", { key: "b", d: "M14 3.8V8h4.2" })],
|
|
875
900
|
spark: [h("path", { key: "a", d: "M12 3l1.9 5.1L19 10l-5.1 1.9L12 17l-1.9-5.1L5 10l5.1-1.9L12 3Z" }), h("path", { key: "b", d: "M19 16l.8 2.2L22 19l-2.2.8L19 22l-.8-2.2L16 19l2.2-.8L19 16Z" })],
|
|
901
|
+
star: [h("path", { key: "a", d: "M12 3.6l2.6 5.3 5.9.9-4.3 4.2 1 5.9-5.2-2.8-5.2 2.8 1-5.9L3.5 9.8l5.9-.9L12 3.6Z" })],
|
|
902
|
+
github: [h("path", { key: "a", fill: "currentColor", stroke: "none", d: "M12 2C6.48 2 2 6.58 2 12.26c0 4.53 2.87 8.37 6.84 9.73.5.1.68-.22.68-.49 0-.24-.01-.88-.01-1.73-2.78.62-3.37-1.37-3.37-1.37-.45-1.18-1.11-1.5-1.11-1.5-.91-.63.07-.62.07-.62 1 .07 1.53 1.06 1.53 1.06.89 1.57 2.34 1.12 2.91.86.09-.66.35-1.12.63-1.38-2.22-.26-4.56-1.14-4.56-5.06 0-1.12.39-2.03 1.03-2.75-.1-.26-.45-1.3.1-2.71 0 0 .84-.28 2.75 1.05a9.36 9.36 0 0 1 2.5-.34c.85 0 1.71.12 2.5.34 1.91-1.33 2.75-1.05 2.75-1.05.55 1.41.2 2.45.1 2.71.64.72 1.03 1.63 1.03 2.75 0 3.93-2.34 4.8-4.57 5.05.36.32.68.94.68 1.9 0 1.37-.01 2.47-.01 2.81 0 .27.18.6.69.49A10.02 10.02 0 0 0 22 12.26C22 6.58 17.52 2 12 2Z" })],
|
|
876
903
|
link: [h("path", { key: "a", d: "M10 13.8a3.5 3.5 0 0 0 5 0l3-3a3.5 3.5 0 0 0-5-5l-1.3 1.3M14 10.2a3.5 3.5 0 0 0-5 0l-3 3a3.5 3.5 0 0 0 5 5l1.3-1.3" })],
|
|
877
904
|
alert: [h("path", { key: "a", d: "M12 3 2.8 19h18.4L12 3Z" }), h("path", { key: "b", d: "M12 9v4M12 16.5v.1" })],
|
|
878
905
|
check: [h("path", { key: "a", d: "m5 12.5 4.2 4.2L19 6.8" })],
|
|
@@ -1296,6 +1323,24 @@ window.__ModuleLoader__.load({
|
|
|
1296
1323
|
h(StatCard, { label: t("stats.tags"), value: stats.totalTags, icon: "link", foot: `${(stats.tags || []).slice(0, 2).map((tag) => tag.name).join(" · ") || "—"}` }),
|
|
1297
1324
|
h(StatCard, { label: t("stats.week"), value: stats.composition?.updatedLast7 ?? 0, icon: "refresh", foot: t("stats.weekFoot") }),
|
|
1298
1325
|
h(StatCard, { label: t("stats.chunks"), value: stats.totalChunks, icon: "grid", foot: t(`search.${stats.indexMode || "keyword"}`) })),
|
|
1326
|
+
h("a", {
|
|
1327
|
+
className: "vs-github",
|
|
1328
|
+
href: REPO_URL,
|
|
1329
|
+
target: "_blank",
|
|
1330
|
+
rel: "noreferrer noopener",
|
|
1331
|
+
"aria-label": t("github.aria")
|
|
1332
|
+
},
|
|
1333
|
+
h("span", { className: "vs-github-mark" }, h(Icon, { name: "github", size: 21 })),
|
|
1334
|
+
h("div", { className: "vs-github-copy" },
|
|
1335
|
+
h("div", { className: "vs-kicker" }, t("github.kicker")),
|
|
1336
|
+
h("b", null, t("github.title")),
|
|
1337
|
+
h("span", null, t("github.body"))),
|
|
1338
|
+
h("span", { className: "vs-github-side" },
|
|
1339
|
+
h("span", { className: "vs-github-repo" }, t("github.repo")),
|
|
1340
|
+
h("span", { className: "vs-github-cta" },
|
|
1341
|
+
h(Icon, { name: "star", size: 13 }),
|
|
1342
|
+
t("github.cta"),
|
|
1343
|
+
h(Icon, { name: "arrow", size: 12 })))),
|
|
1299
1344
|
(stats.heatmap || []).length
|
|
1300
1345
|
? (() => {
|
|
1301
1346
|
const summary = summarizeHeatmap(stats.heatmap || []);
|
package/package.json
CHANGED
package/src/host/tools.js
CHANGED
|
@@ -202,7 +202,10 @@ export function registerTools(ctx, service) {
|
|
|
202
202
|
reason: { type: "string", description: "Why this note or append is useful." },
|
|
203
203
|
citations: { type: "array", items: { type: "string" }, description: "Source note paths used for this content." }
|
|
204
204
|
},
|
|
205
|
-
output: {
|
|
205
|
+
output: {
|
|
206
|
+
schema: proposalSchema,
|
|
207
|
+
render: (_args, value) => text(`Proposed ${value.operation}: ${value.path}\n\nProposal id: ${value.id}\n\n${value.diff}`)
|
|
208
|
+
},
|
|
206
209
|
async execute(args) {
|
|
207
210
|
return service.proposeWrite(args);
|
|
208
211
|
},
|
package/README.en.md
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
# Obsidian Vault Studio
|
|
2
|
-
|
|
3
|
-
Connect a local Obsidian vault to DeepSeek Harness. After you grant access, the model can search your notes, read relevant passages, build grounded context, and create or append notes through a proposal-first workflow. The index, embeddings, and statistics stay on your machine.
|
|
4
|
-
|
|
5
|
-
[中文](README.md)
|
|
6
|
-
|
|
7
|
-

|
|
8
|
-
|
|
9
|
-
*Screenshots use sample data.*
|
|
10
|
-
|
|
11
|
-
## What it does
|
|
12
|
-
|
|
13
|
-
- **Local index** — parses Markdown, frontmatter, tags, headings, and modification times without uploading the whole vault.
|
|
14
|
-
- **Practical retrieval** — keyword search by default, with English prefix matching and live results; optional OpenAI-compatible or Ollama embeddings enable hybrid and semantic modes.
|
|
15
|
-
- **Conversation access switch** — model access is off by default. When off, every `obsidian_*` Agent tool is denied; your own search and note browsing keep working.
|
|
16
|
-
- **Safe writes** — the model can only propose a create or append. Nothing is written until you approve; writes are backed up and can be undone. There are no delete, move, rename, or overwrite tools.
|
|
17
|
-
- **Dashboard** — note, word, tag, and chunk counts; a daily heatmap; a 14-day activity curve; Agent call counters; recent notes and tag distribution.
|
|
18
|
-
- **Local by design** — index, vectors, settings, and usage counters all stay on your machine.
|
|
19
|
-
|
|
20
|
-
## Install
|
|
21
|
-
|
|
22
|
-
### Requirements
|
|
23
|
-
|
|
24
|
-
- DeepSeek Harness 0.2.x desktop, with third-party plugin installation enabled
|
|
25
|
-
- A local Obsidian vault
|
|
26
|
-
|
|
27
|
-
### Install source
|
|
28
|
-
|
|
29
|
-
DeepSeek Harness can install the plugin from either a GitHub repository or an npm package:
|
|
30
|
-
|
|
31
|
-
- **GitHub repository**: `https://github.com/spark-ai-boy/dsh-obsidian-bridge`
|
|
32
|
-
- **npm package**: `dsh-obsidian-bridge`
|
|
33
|
-
|
|
34
|
-
### Steps
|
|
35
|
-
|
|
36
|
-
1. Open **Plugins** in the DeepSeek Harness sidebar.
|
|
37
|
-
2. Choose **Add plugin** → **Install third-party plugin**.
|
|
38
|
-
3. Enter either the **GitHub repository URL** or the **npm package name** above, install it, then click **Enable**.
|
|
39
|
-
4. Open **Obsidian Vault Studio** in the sidebar.
|
|
40
|
-
|
|
41
|
-

|
|
42
|
-
|
|
43
|
-
## First run
|
|
44
|
-
|
|
45
|
-
1. Open **Settings**, choose your vault path, and click **Save**.
|
|
46
|
-
2. Click **Rebuild index**. The dashboard and search become available once the first index completes.
|
|
47
|
-
3. Retrieval mode defaults to **Keyword**; no extra setup is needed.
|
|
48
|
-
4. For semantic or hybrid search, enter an OpenAI-compatible or Ollama embedding endpoint, model, and dimensions in Settings. Click **Test connection**, save, then rebuild the index.
|
|
49
|
-
5. The **Allow vault context in conversations** switch on the dashboard is off by default. Turn it on when you want the Agent to use the vault; when off, every `obsidian_*` tool call is denied.
|
|
50
|
-
|
|
51
|
-

|
|
52
|
-
|
|
53
|
-
## Usage
|
|
54
|
-
|
|
55
|
-
### Dashboard
|
|
56
|
-
|
|
57
|
-
The home page shows note, word, tag, 7-day update, and chunk counts; a 365-day heatmap; a 14-day activity curve; Agent call counters; recent notes; and tag distribution.
|
|
58
|
-
|
|
59
|
-
### Search
|
|
60
|
-
|
|
61
|
-
Type a keyword or prefix on the **Search** page; results update as you type. Filter by folder or tag, add passages to the **Context** tray, then copy a source-attributed context packet or let the Agent search through tools.
|
|
62
|
-
|
|
63
|
-

|
|
64
|
-
|
|
65
|
-
### Notes
|
|
66
|
-
|
|
67
|
-
Browse and read notes on the **Notes** page. Model writes follow a proposal flow:
|
|
68
|
-
|
|
69
|
-
1. The model proposes new or appended content.
|
|
70
|
-
2. The page shows the target path and a diff.
|
|
71
|
-
3. Nothing is written until you approve.
|
|
72
|
-
4. Writes can be undone and are backed up.
|
|
73
|
-
|
|
74
|
-
### Use in a conversation
|
|
75
|
-
|
|
76
|
-
1. Turn on **Allow vault context in conversations** on the dashboard.
|
|
77
|
-
2. Ask the model to search your notes, for example:
|
|
78
|
-
- "Find my notes about RAG and cite the sources."
|
|
79
|
-
- "Append today's meeting notes to the project note."
|
|
80
|
-
3. Only passages actually retrieved or read enter the conversation; the whole vault is never injected automatically.
|
|
81
|
-
4. Turn the access switch off when you no longer need it. Later tool calls will be denied.
|
|
82
|
-
|
|
83
|
-
### Agent tools
|
|
84
|
-
|
|
85
|
-
| Tool | Purpose |
|
|
86
|
-
| --- | --- |
|
|
87
|
-
| `obsidian_search` | Search note passages by mode, folder, or tag |
|
|
88
|
-
| `obsidian_read_note` | Read a full note |
|
|
89
|
-
| `obsidian_list_notes` | List or filter notes |
|
|
90
|
-
| `obsidian_stats` | Read index, statistics, and workspace status |
|
|
91
|
-
| `obsidian_propose_write` | Create a create/append proposal without writing |
|
|
92
|
-
| `obsidian_apply_write` | Apply a proposal after your approval |
|
|
93
|
-
| `obsidian_undo_write` | Undo a write from this session |
|
|
94
|
-
| `obsidian_index_status` | Check indexing and embedding progress |
|
|
95
|
-
|
|
96
|
-
The plugin has no delete, move, rename, or overwrite tools.
|
|
97
|
-
|
|
98
|
-
## Privacy and safety
|
|
99
|
-
|
|
100
|
-
- The index, vectors, settings, and usage counters are local. The plugin contains no telemetry and does not upload the vault.
|
|
101
|
-
- When **Allow vault context in conversations** is off, every `obsidian_*` Agent tool is denied before execution. Vault Studio's own search and browsing remain available.
|
|
102
|
-
- The system prompt tells the model to report Obsidian tool failures and never bypass Vault Studio or the access switch through generic file tools.
|
|
103
|
-
- The access switch only gates `obsidian_*` tools. For a hard boundary, also check DeepSeek Harness workspace/sandbox permissions so generic `read`, `grep`, and `bash` cannot reach the vault path.
|
|
104
|
-
- Writes require approval, keep backups, and can be undone. The plugin never deletes or overwrites notes automatically.
|
|
105
|
-
|
|
106
|
-
## License
|
|
107
|
-
|
|
108
|
-
[MIT](LICENSE)
|