dsh-vault 0.1.0 → 0.1.2

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-zh.md ADDED
@@ -0,0 +1,187 @@
1
+ # dsh-vault — 加密凭据保险库插件
2
+
3
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
4
+ [![npm version](https://img.shields.io/npm/v/dsh-vault?color=cb3837&logo=npm)](https://www.npmjs.com/package/dsh-vault)
5
+ [![GitHub Release](https://img.shields.io/github/v/release/Ox0400/dsh-vault?logo=github)](https://github.com/Ox0400/dsh-vault/releases)
6
+ [![npm downloads](https://img.shields.io/npm/dm/dsh-vault)](https://www.npmjs.com/package/dsh-vault)
7
+ [![GitHub issues](https://img.shields.io/github/issues/Ox0400/dsh-vault)](https://github.com/Ox0400/dsh-vault/issues)
8
+
9
+ dsh-vault 是一个面向 DeepSeek Harness 的安全加密插件:把你在使用 AI 过程中产生的**用户名、邮箱、手机号、密码、二次动态密钥(TOTP)** 以及开发工作流中常用的 **SSH 连接、API Key、Secret、OAuth access/refresh token** 等敏感凭据加密存储,并通过模型工具提供增删改查、检索、密码生成与动态验证码生成能力。
10
+
11
+ **安全性与实现**
12
+
13
+ - **零外部依赖**:全部加密基于 Node 内置 `node:crypto`(AES-256-GCM 认证加密 + scrypt 密钥派生 + RFC 6238 TOTP),不引入任何第三方加密库。
14
+ - **主密码**:所有条目由 `scrypt(主密码, 盐)` 派生的 256 位密钥经 **AES-256-GCM** 加密。密钥永不落盘;进程内解锁后缓存复用(避免每次写入重复 scrypt),重启后重新派生。
15
+ - **防篡改**:GCM 认证标签 + 文档内固定明文的校验信封,错误主密码、密文被改动都会立即失败,绝不返回垃圾数据。
16
+ - **磁盘无明文**:加密文档中不含任何明文凭据;每个条目独立随机 nonce。
17
+ - **原子写入**:复用 harness 的 `writeFileAtomic` + 文件锁,任何时刻磁盘上都是完整的新/旧文档;进程内写入串行化、跨进程写入加锁。
18
+ - **检索不泄密**:`vault_search` 只返回摘要(id/标题/分类/用户名/邮箱/手机/主机/端口/URL/标签),**绝不返回密码、密钥、令牌与 TOTP 密钥**;完整凭据只能通过 `vault_get` 按 id 显式读取。
19
+
20
+ ## 条目模型
21
+
22
+ 每条记录包含一个 `title`、一个可选 `kind` 分类,以及任意组合的字段:
23
+
24
+ | 字段 | 说明 |
25
+ |---|---|
26
+ | `kind` | `login`(默认)/ `ssh` / `api-key` / `secret` / `oauth` / `custom` |
27
+ | `username` / `email` / `phone` | 账号身份 |
28
+ | `password` | 密码 |
29
+ | `host` / `port` | SSH 主机与端口(如 `db.internal` / `2222`) |
30
+ | `privateKey` | SSH 私钥(PEM) |
31
+ | `apiKey` | API 密钥 |
32
+ | `secret` | 通用 Secret(client secret、共享密钥等) |
33
+ | `accessToken` / `refreshToken` / `expiresAt` | OAuth 令牌对与过期时间(epoch millis) |
34
+ | `otpSecret` | TOTP 密钥(Base32 或 otpauth:// URI) |
35
+ | `url` / `notes` / `tags` | 元信息 |
36
+ | `fields` | 任意附加键值(如 `{"region": "us-east-1"}`),可检索 |
37
+
38
+ ## 工具
39
+
40
+ | 工具 | 作用 |
41
+ |---|---|
42
+ | `vault_add` | 新增条目(上述字段任意组合;空字符串/空数组字段会被忽略) |
43
+ | `vault_get` | 按 id 读取完整条目(含全部密钥) |
44
+ | `vault_search` | 跨标题/分类/用户名/邮箱/手机/主机/端口/URL/备注/标签/自定义字段(含数字/布尔/嵌套值)检索,返回无密摘要;`limit` 须为 1–100 的整数 |
45
+ | `vault_update` | 按 id 更新字段(未提供的字段保留;空字符串清除该字段;`title` 可改名) |
46
+ | `vault_delete` | 按 id 删除条目(不可恢复) |
47
+ | `vault_totp` | 为存储的 otpSecret(或直接传入的 Base32/otpauth URI)生成当前 6 位动态验证码 |
48
+ | `vault_generate_password` | 生成强随机密码(长度/字符集/去歧义/分组可选;`group` 须为 ≥2 的整数) |
49
+
50
+ **典型开发场景**:存一条 SSH 凭据(`kind: ssh` + host/port/username/password 或 privateKey),开发时让模型 `vault_search` 找主机、`vault_get` 取连接信息;存 API 网关的 `api-key`/`oauth` 条目管理 access/refresh token 轮换。
51
+
52
+ ## 安装
53
+
54
+ dsh-vault 是一个 **bundle**(声明 `dsh.bundle` 的包):安装到 profile 后,它的 `cordis.patch.yml` 会自动插入 `vault` 插件行(按包名 `dsh-vault` 引用,主密码经 `DSH_VAULT_PASSWORD` 环境变量注入)。包内含自包含构建脚本,git 安装时会自动编译 `lib/`。
55
+
56
+ 以下四种安装方式均已**端到端实测通过**(安装 → bundle 层被识别 → 插件激活且 7 个 `vault_*` 工具全部注册 → `vault_add`/`vault_get` 真实往返成功 → 卸载移除 layer):
57
+
58
+ | 方式 | 命令 | 需构建 | 需 allowBuilds |
59
+ |---|---|---|---|
60
+ | npm | `add dsh-vault` | 否(预构建 lib) | 否 |
61
+ | GitHub | `add github:Ox0400/dsh-vault#v0.1.1` | 是(prepare) | 是(首次) |
62
+ | 本地路径 | `add /绝对/路径/to/dsh-vault` | 否(链接已构建源码) | 否 |
63
+ | tarball | `add ./dsh-vault-0.1.1.tgz` | 否(预构建 lib) | 否 |
64
+
65
+ ### 方式一:从 npm 安装(最省事)
66
+
67
+ ```sh
68
+ dsh plugin --profile demo add dsh-vault
69
+ ```
70
+
71
+ npm 包自带**预构建的 `lib/` 产物**,无需 allowBuilds、无需本地编译,安装即用。启动前设置主密码:
72
+
73
+ ```sh
74
+ export DSH_VAULT_PASSWORD='你的强主密码'
75
+ ```
76
+
77
+ ### 方式二:从 GitHub 安装(锁 tag 或 commit)
78
+
79
+ ```sh
80
+ dsh plugin --profile demo add github:Ox0400/dsh-vault#v0.1.1
81
+ ```
82
+
83
+ git 安装拉取的是**源码**,`prepare` 脚本会在安装时构建 `lib/`。pnpm ≥10 默认阻止 git 依赖执行构建脚本。实测流程:
84
+
85
+ 1. 执行 `add` 命令——会因 `allowBuilds` 失败,并打印需要放行的**精确键**(含仓库 URL 与解析后的 commit hash 的那行):
86
+
87
+ ```text
88
+ allowBuilds:
89
+ dsh-vault@https://codeload.github.com/Ox0400/dsh-vault/tar.gz/<sha>: true
90
+ ```
91
+
92
+ 2. 把该精确键追加到 profile 的 `pnpm-workspace.yaml`(`$DSH_HOME/profiles/<name>/pnpm-workspace.yaml`):
93
+
94
+ ```yaml
95
+ packages:
96
+ - .
97
+ allowBuilds:
98
+ dsh-vault@https://codeload.github.com/Ox0400/dsh-vault/tar.gz/<sha>: true
99
+ ```
100
+
101
+ 3. 重新执行 `add`——pnpm 现在会运行 `prepare` 脚本,构建 `lib/` 并完成安装。
102
+
103
+ 建议**锁定 tag/commit** 再安装,避免上游推送改变安装时执行的代码。允许构建 = 允许该包的代码在你的机器上于安装时执行;只对你信任的源码授予。
104
+
105
+ ### 方式三:本地路径安装到 profile
106
+
107
+ ```sh
108
+ dsh plugin --profile demo add /绝对/路径/to/dsh-vault
109
+ ```
110
+
111
+ pnpm 将 checkout 链接进 profile;只要 `lib/` 存在(必要时先在 checkout 里执行 `pnpm build`)即被识别为 bundle。
112
+
113
+ ### 方式四:本地 tarball 安装
114
+
115
+ ```sh
116
+ npm pack && dsh plugin --profile demo add ./dsh-vault-0.1.1.tgz
117
+ ```
118
+
119
+ tarball 自带预构建 `lib/` 产物,无需构建或 allowBuilds。
120
+
121
+ `dsh plugin --profile demo remove dsh-vault` 卸载(同时移除依赖与 layer)。
122
+
123
+ ## 配置
124
+
125
+ | 配置项 | 说明 |
126
+ |---|---|
127
+ | `masterPassword` | 直接配置主密码(会出现在 cordis.yml 中,不推荐) |
128
+ | `masterPasswordEnv` | 环境变量名,运行时从该变量读取主密码(推荐) |
129
+ | `path` | 保险库文件路径,默认 `$DSH_HOME/vault/default.json` |
130
+ | `name` | 保险库名,用于默认路径(如 `name: work` → `$DSH_HOME/vault/work.json`) |
131
+
132
+ 首次调用任一工具时自动创建保险库;之后每次启动用主密码重新解锁。**忘记主密码 = 数据永久丢失**(无后门,这是设计使然)。
133
+
134
+ ## 开发
135
+
136
+ 本地 clone 开发:
137
+
138
+ ```sh
139
+ git clone git@github.com:Ox0400/dsh-vault.git
140
+ cd dsh-vault
141
+ pnpm install # 安装 devDependencies(typescript/tsdown/vitest 等)
142
+ pnpm build # 构建 host 侧 lib/*.js 与浏览器 bundle lib/client.js
143
+ pnpm test # 运行 41 项 vitest 测试
144
+ ```
145
+
146
+ > 测试需要 harness 的 `dsh-llm`/`dsh-system-prompt` 等 peer 包,在 harness monorepo 内开发时由 workspace 链接提供。
147
+
148
+ 常用命令:
149
+
150
+ ```sh
151
+ # 单元 + 集成测试(vitest,41 项)
152
+ pnpm test # 或 npx vitest run
153
+
154
+ # 类型检查
155
+ pnpm typecheck # tsc -p tsconfig.json --noEmit
156
+
157
+ # 构建(host 侧 lib/*.js 与浏览器 bundle lib/client.js)
158
+ pnpm build # = build:host (tsc) + build:client (tsdown)
159
+
160
+ # 打包发布(可选:npm pack 产物可直接 `dsh plugin add ./dsh-vault-0.1.1.tgz`)
161
+ npm pack
162
+ ```
163
+
164
+ 仓库内所有测试通过:41/41(crypto/TOTP/密码生成/store CRUD/网关/集成)。
165
+
166
+ ## 打包与发布
167
+
168
+ 本包是标准 npm bundle:
169
+
170
+ - `dsh.bundle.patch` → `cordis.patch.yml`(安装到 profile 后自动应用的 layer)
171
+ - `dsh.client` → 浏览器端声明(`exports["./client"]` 指向 `lib/client.js`)
172
+ - `prepare` 脚本 → git 安装时自包含构建(`tsc` host + `tsdown` client)
173
+ - 运行时依赖全部走 `peerDependencies`(由宿主 harness 提供,避免重复实例)
174
+
175
+ 可选发布途径:
176
+
177
+ ```sh
178
+ npm pack # 产出 tarball → dsh plugin add ./dsh-vault-0.1.1.tgz
179
+ npm publish --access public # 发布 npm → dsh plugin add dsh-vault
180
+ ```
181
+
182
+ ## 安全边界与已知限制
183
+
184
+ - 主密码强度决定保险库强度;建议 ≥ 16 字符高熵。
185
+ - scrypt 成本参数(N=32768, r=8, p=1)已持久化在文档中,可随版本提升,旧文档仍可解密。
186
+ - 明文凭据仅存在于进程内存与 `vault_get` 显式读取期间;`vault_search`/`vault_update` 的输出均不含密码、密钥与令牌。`vault_get` 返回的秘密会进入该次工具调用结果(模型上下文),调用方应避免在对话中复述。
187
+ - 本插件面向单机/个人部署;团队共享保险库不在范围内。
package/README.md CHANGED
@@ -1,150 +1,182 @@
1
- # dsh-vault — 加密凭据保险库插件
1
+ # dsh-vault — Encrypted Credential Vault for DeepSeek Harness
2
2
 
3
3
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
4
+ [![npm version](https://img.shields.io/npm/v/dsh-vault?color=cb3837&logo=npm)](https://www.npmjs.com/package/dsh-vault)
5
+ [![GitHub Release](https://img.shields.io/github/v/release/Ox0400/dsh-vault?logo=github)](https://github.com/Ox0400/dsh-vault/releases)
6
+ [![npm downloads](https://img.shields.io/npm/dm/dsh-vault)](https://www.npmjs.com/package/dsh-vault)
7
+ [![GitHub issues](https://img.shields.io/github/issues/Ox0400/dsh-vault)](https://github.com/Ox0400/dsh-vault/issues)
4
8
 
5
- dsh-vault 是一个面向 DeepSeek Harness 的安全加密插件:把你在使用 AI 过程中产生的**用户名、邮箱、手机号、密码、二次动态密钥(TOTP)** 以及开发工作流中常用的 **SSH 连接、API Key、Secret、OAuth access/refresh token** 等敏感凭据加密存储,并通过模型工具提供增删改查、检索、密码生成与动态验证码生成能力。
9
+ **English** | [中文](README-zh.md)
6
10
 
7
- **安全性与实现**
11
+ dsh-vault is a security-focused plugin for DeepSeek Harness that stores sensitive credentials — **usernames, emails, phone numbers, passwords, TOTP secrets**, and developer credentials like **SSH connections, API keys, secrets, and OAuth access/refresh tokens** — encrypted at rest, and exposes them to the model through CRUD, search, password generation, and TOTP tools, plus a Settings UI page.
8
12
 
9
- - **零外部依赖**:全部加密基于 Node 内置 `node:crypto`(AES-256-GCM 认证加密 + scrypt 密钥派生 + RFC 6238 TOTP),不引入任何第三方加密库。
10
- - **主密码**:所有条目由 `scrypt(主密码, 盐)` 派生的 256 位密钥经 **AES-256-GCM** 加密。密钥永不落盘;进程内解锁后缓存复用(避免每次写入重复 scrypt),重启后重新派生。
11
- - **防篡改**:GCM 认证标签 + 文档内固定明文的校验信封,错误主密码、密文被改动都会立即失败,绝不返回垃圾数据。
12
- - **磁盘无明文**:加密文档中不含任何明文凭据;每个条目独立随机 nonce。
13
- - **原子写入**:复用 harness 的 `writeFileAtomic` + 文件锁,任何时刻磁盘上都是完整的新/旧文档;进程内写入串行化、跨进程写入加锁。
14
- - **检索不泄密**:`vault_search` 只返回摘要(id/标题/分类/用户名/邮箱/手机/主机/端口/URL/标签),**绝不返回密码、密钥、令牌与 TOTP 密钥**;完整凭据只能通过 `vault_get` 按 id 显式读取。
13
+ ## Security & Implementation
15
14
 
16
- ## 条目模型
15
+ - **Zero external crypto dependencies**: everything is built on Node's built-in `node:crypto` (AES-256-GCM authenticated encryption, scrypt key derivation, RFC 6238 TOTP).
16
+ - **Master password**: every entry is encrypted with a 256-bit key derived via `scrypt(master password, salt)` and AES-256-GCM. The key never touches disk; after unlock it is cached in-process and re-derived on restart.
17
+ - **Tamper-evident**: GCM auth tags plus a fixed-plaintext verification envelope — a wrong master password or modified ciphertext fails immediately, never returning garbage.
18
+ - **No plaintext at rest**: the on-disk document contains no plaintext credentials; each entry uses an independent random nonce.
19
+ - **Atomic writes**: reuses the harness `writeFileAtomic` + file lock; in-process writes are serialized, cross-process writers take the lock.
20
+ - **Search never leaks**: `vault_search` returns summaries only (id/title/kind/username/email/phone/host/port/url/tags) — **never passwords, keys, tokens, or TOTP secrets**. Full credentials are readable only via explicit `vault_get` by id.
17
21
 
18
- 每条记录包含一个 `title`、一个可选 `kind` 分类,以及任意组合的字段:
22
+ ## Entry Model
19
23
 
20
- | 字段 | 说明 |
24
+ Each record has a `title`, an optional `kind`, and any combination of fields:
25
+
26
+ | Field | Description |
21
27
  |---|---|
22
- | `kind` | `login`(默认)/ `ssh` / `api-key` / `secret` / `oauth` / `custom` |
23
- | `username` / `email` / `phone` | 账号身份 |
24
- | `password` | 密码 |
25
- | `host` / `port` | SSH 主机与端口(如 `db.internal` / `2222`) |
26
- | `privateKey` | SSH 私钥(PEM |
27
- | `apiKey` | API 密钥 |
28
- | `secret` | 通用 Secret(client secret、共享密钥等) |
29
- | `accessToken` / `refreshToken` / `expiresAt` | OAuth 令牌对与过期时间(epoch millis |
30
- | `otpSecret` | TOTP 密钥(Base32 otpauth:// URI |
31
- | `url` / `notes` / `tags` | 元信息 |
32
- | `fields` | 任意附加键值(如 `{"region": "us-east-1"}`),可检索 |
33
-
34
- ## 工具
35
-
36
- | 工具 | 作用 |
28
+ | `kind` | `login` (default) / `ssh` / `api-key` / `secret` / `oauth` / `custom` |
29
+ | `username` / `email` / `phone` | Account identity |
30
+ | `password` | The password |
31
+ | `host` / `port` | SSH host and port (e.g. `db.internal` / `2222`) |
32
+ | `privateKey` | SSH private key (PEM) |
33
+ | `apiKey` | API key |
34
+ | `secret` | Generic secret (client secret, shared secret, …) |
35
+ | `accessToken` / `refreshToken` / `expiresAt` | OAuth token pair and expiry (epoch millis) |
36
+ | `otpSecret` | TOTP secret (bare Base32 or otpauth:// URI) |
37
+ | `url` / `notes` / `tags` | Metadata |
38
+ | `fields` | Arbitrary key/value pairs (e.g. `{"region": "us-east-1"}`), searchable |
39
+
40
+ ## Tools
41
+
42
+ | Tool | Purpose |
37
43
  |---|---|
38
- | `vault_add` | 新增条目(上述字段任意组合;空字符串/空数组字段会被忽略) |
39
- | `vault_get` | id 读取完整条目(含全部密钥) |
40
- | `vault_search` | 跨标题/分类/用户名/邮箱/手机/主机/端口/URL/备注/标签/自定义字段(含数字/布尔/嵌套值)检索,返回无密摘要;`limit` 须为 1–100 的整数 |
41
- | `vault_update` | id 更新字段(未提供的字段保留;空字符串清除该字段;`title` 可改名) |
42
- | `vault_delete` | id 删除条目(不可恢复) |
43
- | `vault_totp` | 为存储的 otpSecret(或直接传入的 Base32/otpauth URI)生成当前 6 位动态验证码 |
44
- | `vault_generate_password` | 生成强随机密码(长度/字符集/去歧义/分组可选;`group` 须为 ≥2 的整数) |
44
+ | `vault_add` | Add an entry (any combination of fields; empty strings/arrays are ignored) |
45
+ | `vault_get` | Read a full entry by id (including all secrets) |
46
+ | `vault_search` | Search titles/categories/usernames/emails/phones/hosts/ports/URLs/notes/tags/custom fields (incl. numeric/boolean/nested values); returns secret-free summaries; `limit` must be an integer 1–100 |
47
+ | `vault_update` | Update fields by id (unprovided fields kept; empty string clears a field; `title` is renamable) |
48
+ | `vault_delete` | Delete an entry by id (irreversible) |
49
+ | `vault_totp` | Generate the current 6-digit code for a stored otpSecret (or a bare Base32 / otpauth URI) |
50
+ | `vault_generate_password` | Generate a strong random password (length/character classes/ambiguity exclusion/grouping; `group` must be an integer 2) |
51
+
52
+ **Typical workflows**: store an SSH credential (`kind: ssh` + host/port/username/password or privateKey) and have the model `vault_search` for the host then `vault_get` the connection details; keep `api-key`/`oauth` entries for API-gateway access/refresh token rotation.
53
+
54
+ ## Installation
45
55
 
46
- **典型开发场景**:存一条 SSH 凭据(`kind: ssh` + host/port/username/password privateKey),开发时让模型 `vault_search` 找主机、`vault_get` 取连接信息;存 API 网关的 `api-key`/`oauth` 条目管理 access/refresh token 轮换。
56
+ dsh-vault is a **bundle** (a package declaring `dsh.bundle`): once installed into a profile, its `cordis.patch.yml` automatically inserts the `vault` plugin row (referenced by package name `dsh-vault`; the master password is injected via the `DSH_VAULT_PASSWORD` environment variable). The package ships a self-contained build script — git installs compile `lib/` automatically.
47
57
 
48
- ## 安装
58
+ All four install paths below are **verified end-to-end** (install → bundle layer recognized → plugin activates with all 7 `vault_*` tools registered → real `vault_add`/`vault_get` round trip → uninstall removes the layer):
49
59
 
50
- dsh-vault 是一个 **bundle**(声明 `dsh.bundle` 的包):安装到 profile 后,它的 `cordis.patch.yml` 会自动插入 `vault` 插件行(按包名 `dsh-vault` 引用,主密码经 `DSH_VAULT_PASSWORD` 环境变量注入)。包内含自包含构建脚本,git 安装时会自动编译 `lib/`。
60
+ | Path | Command | Build needed | `allowBuilds` |
61
+ |---|---|---|---|
62
+ | npm | `add dsh-vault` | no (prebuilt `lib/`) | no |
63
+ | GitHub | `add github:Ox0400/dsh-vault#v0.1.1` | yes (`prepare`) | yes (first run) |
64
+ | local path | `add /abs/path/to/dsh-vault` | no (link to built source) | no |
65
+ | tarball | `add ./dsh-vault-0.1.1.tgz` | no (prebuilt `lib/`) | no |
51
66
 
52
- ### 方式一:从 GitHub 安装(推荐)
67
+ ### Option 1: Install from npm (easiest)
53
68
 
54
69
  ```sh
55
- dsh plugin --profile demo add github:Ox0400/dsh-vault
70
+ dsh plugin --profile demo add dsh-vault
56
71
  ```
57
72
 
58
- git 安装拉取的是**源码**,`prepare` 脚本会在安装时构建 `lib/`。pnpm ≥10 默认阻止 git 依赖执行构建脚本,首次 `add` 会失败并打印一个 `allowBuilds` 键——把**精确的键**(含仓库 URL 的那行)加入 profile `pnpm-workspace.yaml`,再重新 `add`:
73
+ npm packages ship **prebuilt `lib/` artifacts** no allowBuilds, no local compilation, install and go. Set the master password before launching:
59
74
 
60
- ```yaml
61
- # $DSH_HOME/profiles/<name>/pnpm-workspace.yaml
62
- allowBuilds:
63
- dsh-vault@https://codeload.github.com/Ox0400/dsh-vault/tar.gz/<sha>: true
75
+ ```sh
76
+ export DSH_VAULT_PASSWORD='your strong master password'
64
77
  ```
65
78
 
66
- 建议**锁定 commit** 再安装,避免上游推送改变安装时执行的代码:
79
+ ### Option 2: Install from GitHub (pin a tag or commit)
67
80
 
68
81
  ```sh
69
- dsh plugin --profile demo add github:Ox0400/dsh-vault#<sha>
82
+ dsh plugin --profile demo add github:Ox0400/dsh-vault#v0.1.1
70
83
  ```
71
84
 
72
- 允许构建 = 允许该包的代码在你的机器上于安装时执行;只对你信任的源码授予。
85
+ A git install fetches **sources, not built artifacts**, so the `prepare` script builds `lib/` at install time. pnpm ≥10 blocks git dependencies from running build scripts by default. The verified flow:
73
86
 
74
- ### 方式二:本地 clone 开发
87
+ 1. Run the `add` command — it fails with an `allowBuilds` error and prints the exact key to allow (the line containing the repo URL, including the resolved commit hash):
75
88
 
76
- ```sh
77
- git clone git@github.com:Ox0400/dsh-vault.git
78
- cd dsh-vault
79
- pnpm install # 安装 devDependencies(typescript/tsdown/vitest 等)
80
- pnpm build # 构建 host 侧 lib/*.js 与浏览器 bundle lib/client.js
81
- pnpm test # 运行 41 vitest 测试
82
- ```
89
+ ```text
90
+ allowBuilds:
91
+ dsh-vault@https://codeload.github.com/Ox0400/dsh-vault/tar.gz/<sha>: true
92
+ ```
93
+
94
+ 2. Append that exact key to the profile's `pnpm-workspace.yaml` (`$DSH_HOME/profiles/<name>/pnpm-workspace.yaml`):
83
95
 
84
- > 测试需要 harness 的 `dsh-llm`/`dsh-system-prompt` 等 peer 包,在 harness monorepo 内开发时由 workspace 链接提供。
96
+ ```yaml
97
+ packages:
98
+ - .
99
+ allowBuilds:
100
+ dsh-vault@https://codeload.github.com/Ox0400/dsh-vault/tar.gz/<sha>: true
101
+ ```
85
102
 
86
- ### 方式三:本地路径安装到 profile
103
+ 3. Re-run the `add` — pnpm now runs the `prepare` script, builds `lib/`, and installs.
104
+
105
+ **Pin a tag/commit** so a later upstream push cannot silently change what runs on install. Treat the allowance for what it is: permission to execute that package's code on your machine at install time — only grant it to sources you trust.
106
+
107
+ ### Option 3: Install from a local path
87
108
 
88
109
  ```sh
89
- dsh plugin --profile demo add /绝对/路径/to/dsh-vault
110
+ dsh plugin --profile demo add /absolute/path/to/dsh-vault
90
111
  ```
91
112
 
92
- 启动前设置主密码:
113
+ pnpm links the checkout into the profile; the bundle is recognized as long as `lib/` exists (run `pnpm build` in the checkout first if needed).
114
+
115
+ ### Option 4: Install from a tarball
93
116
 
94
117
  ```sh
95
- export DSH_VAULT_PASSWORD='你的强主密码'
118
+ npm pack && dsh plugin --profile demo add ./dsh-vault-0.1.1.tgz
96
119
  ```
97
120
 
98
- `dsh plugin --profile demo remove dsh-vault` 卸载(同时移除依赖与 layer)。
121
+ The tarball ships prebuilt `lib/` artifacts, so no build step or `allowBuilds` is required.
99
122
 
100
- ## 配置
123
+ `dsh plugin --profile demo remove dsh-vault` uninstalls (removes both the dependency and the layer).
101
124
 
102
- | 配置项 | 说明 |
125
+ ## Configuration
126
+
127
+ | Option | Description |
103
128
  |---|---|
104
- | `masterPassword` | 直接配置主密码(会出现在 cordis.yml 中,不推荐) |
105
- | `masterPasswordEnv` | 环境变量名,运行时从该变量读取主密码(推荐) |
106
- | `path` | 保险库文件路径,默认 `$DSH_HOME/vault/default.json` |
107
- | `name` | 保险库名,用于默认路径(如 `name: work` → `$DSH_HOME/vault/work.json`) |
129
+ | `masterPassword` | The master password inline (appears in cordis.yml; not recommended) |
130
+ | `masterPasswordEnv` | Environment variable name holding the master password (recommended) |
131
+ | `path` | Vault file path; defaults to `$DSH_HOME/vault/default.json` |
132
+ | `name` | Vault name for the default path (e.g. `name: work` → `$DSH_HOME/vault/work.json`) |
133
+
134
+ The vault is created automatically on first tool use; every launch re-unlocks with the master password. **Forgetting the master password = permanent data loss** (no backdoor — by design).
108
135
 
109
- 首次调用任一工具时自动创建保险库;之后每次启动用主密码重新解锁。**忘记主密码 = 数据永久丢失**(无后门,这是设计使然)。
136
+ ## Development
110
137
 
111
- ## 开发
138
+ Clone and develop locally:
112
139
 
113
140
  ```sh
114
- # 单元 + 集成测试(vitest,41 项)
115
- pnpm test # 或 npx vitest run
141
+ git clone git@github.com:Ox0400/dsh-vault.git
142
+ cd dsh-vault
143
+ pnpm install # installs devDependencies (typescript/tsdown/vitest, …)
144
+ pnpm build # builds host lib/*.js and the browser bundle lib/client.js
145
+ pnpm test # runs the 41 vitest tests
146
+ ```
116
147
 
117
- # 类型检查
118
- pnpm typecheck # tsc -p tsconfig.json --noEmit
148
+ > Tests need harness peer packages such as `dsh-llm`/`dsh-system-prompt`; inside the harness monorepo these resolve via workspace links.
119
149
 
120
- # 构建(host 侧 lib/*.js 与浏览器 bundle lib/client.js)
121
- pnpm build # = build:host (tsc) + build:client (tsdown)
150
+ Common commands:
122
151
 
123
- # 打包发布(可选:npm pack 产物可直接 `dsh plugin add ./dsh-vault-0.1.0.tgz`)
124
- npm pack
152
+ ```sh
153
+ pnpm test # unit + integration tests (vitest, 41)
154
+ pnpm typecheck # tsc -p tsconfig.json --noEmit
155
+ pnpm build # = build:host (tsc) + build:client (tsdown)
156
+ npm pack # optional: tarball for `dsh plugin add ./dsh-vault-0.1.1.tgz`
125
157
  ```
126
158
 
127
- 仓库内所有测试通过:41/41(crypto/TOTP/密码生成/store CRUD/网关/集成)。
159
+ All 41 tests pass (crypto / TOTP / password generation / store CRUD / gateway / integration).
128
160
 
129
- ## 打包与发布
161
+ ## Packaging & Publishing
130
162
 
131
- 本包是标准 npm bundle:
163
+ This package is a standard npm bundle:
132
164
 
133
- - `dsh.bundle.patch` → `cordis.patch.yml`(安装到 profile 后自动应用的 layer)
134
- - `dsh.client` → 浏览器端声明(`exports["./client"]` 指向 `lib/client.js`)
135
- - `prepare` 脚本 → git 安装时自包含构建(`tsc` host + `tsdown` client)
136
- - 运行时依赖全部走 `peerDependencies`(由宿主 harness 提供,避免重复实例)
165
+ - `dsh.bundle.patch` → `cordis.patch.yml` (the layer applied automatically when a profile lists this bundle)
166
+ - `dsh.client` → browser-side declaration (`exports["./client"]` points at `lib/client.js`)
167
+ - `prepare` scriptself-contained build on git install (`tsc` host + `tsdown` client)
168
+ - Runtime dependencies are all `peerDependencies` (provided by the host harness — no duplicate instances)
137
169
 
138
- 可选发布途径:
170
+ Distribution options:
139
171
 
140
172
  ```sh
141
- npm pack # 产出 tarball → dsh plugin add ./dsh-vault-0.1.0.tgz
142
- npm publish --access public # 发布 npm → dsh plugin add dsh-vault
173
+ npm pack # tarball → dsh plugin add ./dsh-vault-0.1.1.tgz
174
+ npm publish --access public # registry → dsh plugin add dsh-vault
143
175
  ```
144
176
 
145
- ## 安全边界与已知限制
177
+ ## Security Boundaries & Known Limitations
146
178
 
147
- - 主密码强度决定保险库强度;建议 ≥ 16 字符高熵。
148
- - scrypt 成本参数(N=32768, r=8, p=1)已持久化在文档中,可随版本提升,旧文档仍可解密。
149
- - 明文凭据仅存在于进程内存与 `vault_get` 显式读取期间;`vault_search`/`vault_update` 的输出均不含密码、密钥与令牌。`vault_get` 返回的秘密会进入该次工具调用结果(模型上下文),调用方应避免在对话中复述。
150
- - 本插件面向单机/个人部署;团队共享保险库不在范围内。
179
+ - Vault strength is bounded by master-password strength; use ≥ 16 characters of high entropy.
180
+ - scrypt cost parameters (N=32768, r=8, p=1) are persisted in the document and can be raised in future versions; old documents remain decryptable.
181
+ - Plaintext credentials exist only in process memory and during explicit `vault_get` reads; `vault_search`/`vault_update` outputs never contain passwords, keys, or tokens. Secrets returned by `vault_get` enter that tool call's result (model context) — callers should avoid repeating them in conversation.
182
+ - This plugin targets single-machine / personal deployments; team-shared vaults are out of scope.
package/lib/client.js CHANGED
@@ -17,28 +17,28 @@ window.__ModuleLoader__.load({
17
17
  document.head.appendChild(tag);
18
18
  }
19
19
  var VaultSection_module_css_default = {
20
- "toolbar": "t_j5va_toolbar",
21
- "empty": "t_j5va_empty",
22
- "intro": "t_j5va_intro",
23
- "editor": "t_j5va_editor",
24
- "rowMain": "t_j5va_rowMain",
25
- "editorBody": "t_j5va_editorBody",
26
- "field": "t_j5va_field",
27
- "title": "t_j5va_title",
28
- "row": "t_j5va_row",
29
- "error": "t_j5va_error",
30
- "saveButton": "t_j5va_saveButton",
31
- "editorActions": "t_j5va_editorActions",
20
+ "totp": "t_j5va_totp",
32
21
  "rowActions": "t_j5va_rowActions",
33
- "addButton": "t_j5va_addButton",
34
- "list": "t_j5va_list",
35
22
  "status": "t_j5va_status",
36
- "totp": "t_j5va_totp",
23
+ "error": "t_j5va_error",
24
+ "field": "t_j5va_field",
25
+ "editor": "t_j5va_editor",
26
+ "editorActions": "t_j5va_editorActions",
37
27
  "section": "t_j5va_section",
28
+ "empty": "t_j5va_empty",
29
+ "toolbar": "t_j5va_toolbar",
30
+ "editorBody": "t_j5va_editorBody",
31
+ "rowMain": "t_j5va_rowMain",
38
32
  "deleteButton": "t_j5va_deleteButton",
39
- "identity": "t_j5va_identity",
33
+ "addButton": "t_j5va_addButton",
34
+ "saveButton": "t_j5va_saveButton",
35
+ "intro": "t_j5va_intro",
40
36
  "copied": "t_j5va_copied",
41
- "searchBox": "t_j5va_searchBox"
37
+ "identity": "t_j5va_identity",
38
+ "searchBox": "t_j5va_searchBox",
39
+ "title": "t_j5va_title",
40
+ "row": "t_j5va_row",
41
+ "list": "t_j5va_list"
42
42
  };
43
43
  //#endregion
44
44
  //#region src/client/VaultSection.tsx
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-vault",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Encrypted credential vault for DeepSeek Harness: store and retrieve usernames, emails, phone numbers, passwords, TOTP secrets, SSH/API-key/OAuth developer credentials through model tools and a Settings UI page.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -38,6 +38,7 @@
38
38
  "lib",
39
39
  "cordis.patch.yml",
40
40
  "README.md",
41
+ "README-zh.md",
41
42
  "LICENSE"
42
43
  ],
43
44
  "engines": {
@@ -78,4 +79,4 @@
78
79
  "test": "vitest run",
79
80
  "typecheck": "tsc -p tsconfig.json --noEmit"
80
81
  }
81
- }
82
+ }