nx-sk 0.6.1 → 0.7.0
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/CHANGELOG.md +17 -0
- package/README.md +15 -8
- package/assets/nx-sk/references/30-export-backup.md +12 -4
- package/package.json +1 -1
- package/src/modules/backup/index.js +9 -4
- package/src/modules/backup/service.js +494 -49
- package/src/modules/backup/view.jsx +133 -22
- package/src/web/public/assets/{files-BNh48qeo.js → files-DcDiKjwc.js} +1 -1
- package/src/web/public/assets/{index-B7CtqgoG.js → index-BygHBMGo.js} +2 -2
- package/src/web/public/assets/{view-BAYyPWdU.js → view-B1Vx3EvJ.js} +1 -1
- package/src/web/public/assets/{view-1kwWQYbz.js → view-COgrD5Um.js} +1 -1
- package/src/web/public/assets/{view-Bu70Q6GO.js → view-Cct73k6i.js} +1 -1
- package/src/web/public/assets/{view-D5LfHr7W.js → view-CnZk33Lp.js} +1 -1
- package/src/web/public/assets/view-CoUwzqKQ.js +5 -0
- package/src/web/public/assets/{view-BIdVqIGe.js → view-h-QmH_sE.js} +1 -1
- package/src/web/public/index.html +1 -1
- package/src/web/public/assets/view-DXqI-4_F.js +0 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
本文件格式参考 [Keep a Changelog](https://keepachangelog.com/),中文正文。
|
|
4
4
|
|
|
5
|
+
## [0.7.0] - 2026-10-13
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **导入缺省「合并」:只增不减,不再整份替换**。`backup import` 旧行为是整份替换——跨源导入一个老结构的备份,本机栏目结构、条目、附件台账全被覆盖成备份的样子(原始事故:求职栏目的「附件资料」组消失)。现在缺省按「只增不减」合并:补缺失的栏目/条目/附件台账、补空字段、把备份多出的分组与字段只增补进已有栏目(复用 `mergeTemplate`);**两边都有值且不同 → 保留本地**、列入冲突清单交用户处理;本地已有数据与结构**永不删改**。KV 栏目按名称匹配(跨机器 id 不可靠),普通栏目按 id。导入完成输出完整报告(CLI 文本 / 面板弹窗):新增、补空、冲突、结构差异、附件统计、快照路径;`--dry-run` 可先看计划不落盘。`--replace` 保留旧的整份替换语义。敏感字段的补空值自动用本机 vaultKey 重新加密;报告里的值一律打码,密钥明文不进报告。
|
|
10
|
+
- **`backup export --with-files`:附件原件入包(压缩包式)**。附件台账随包携带升级为**恒定行为**(v3 格式——0.5.x–0.6.2 的包根本不含 `files`,任何一次导入都会把台账清零,本次一并根修并加了回归钉);`--with-files` 再把台账指向的原件读成 `{rel → {b64, sha256}}` 单块加密嵌入 `filesData`(与主数据同一把口令派生 key)。导入时自动落盘还原(sha256 校验;磁盘已有且内容不同以磁盘为准);v2 旧包继续可导,缺原件在报告里如实列出。
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- 面板「加密备份」:导出加「连附件原件一起打包」勾选;导入拆成「解密并导入(合并)」与「整份替换…」(danger 确认)两个动作;结果以报告弹窗呈现;超过 28MB 的包提示走 CLI(接口请求体上限 32MB)。
|
|
15
|
+
|
|
16
|
+
## [0.6.2] - 2026-10-12
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- **加密备份:跨机器恢复后 store.json 里 secret 字段仍是密文**。0.6.1 把 secret 字段解开成明文后直接落回 store.json——丢了本机「落盘密文」防护。回归到 0.5.1 的设计:导出时用本机 vaultKey **解开** secret 字段、整包口令加密入 `.nxskbak`;导入时解开整包后**用本机 vaultKey 重新加密** secret 字段再写回 store.json。两条安全边界各自独立:本地靠 vaultKey、传递靠口令。
|
|
21
|
+
|
|
5
22
|
## [0.6.1] - 2026-10-12
|
|
6
23
|
|
|
7
24
|
### Changed
|
package/README.md
CHANGED
|
@@ -124,8 +124,8 @@ CLI 与 API 同源,skill 驱动 agent**。落到具体功能上:
|
|
|
124
124
|
| `nx-sk file open <id>` | 用系统默认程序打开原件 |
|
|
125
125
|
| `nx-sk export run [--format json\|md\|both] [--section id] [--with-secrets] [--out DIR] [--dry-run]` | 整体导出 |
|
|
126
126
|
| `nx-sk export list` | 历次导出与目录内文件 |
|
|
127
|
-
| `nx-sk backup export [--password 口令] [--out DIR] [--dry-run]` | 口令对称加密整库,导出单个 `.nxskbak
|
|
128
|
-
| `nx-sk backup import --file <备份> [--password 口令] [--dry-run]` |
|
|
127
|
+
| `nx-sk backup export [--password 口令] [--out DIR] [--with-files] [--dry-run]` | 口令对称加密整库,导出单个 `.nxskbak`(口令不落盘;`--with-files` 连附件原件) |
|
|
128
|
+
| `nx-sk backup import --file <备份> [--password 口令] [--replace] [--dry-run]` | 解密导入:缺省「合并」(只增补、不覆盖已有值,冲突列清单),`--replace` 整份替换;动手前自动留安全快照 |
|
|
129
129
|
| `nx-sk setting get \| set` | 全局设置 |
|
|
130
130
|
| `nx-sk skill list \| install \| get` | 把内置 skill 装给 agent / 给外部 agent 取上下文 |
|
|
131
131
|
|
|
@@ -207,13 +207,20 @@ nx-sk export list
|
|
|
207
207
|
|
|
208
208
|
```bash
|
|
209
209
|
nx-sk backup export --password '你的备份口令' # 写成 ~/nx-sk/backup/*.nxskbak
|
|
210
|
-
nx-sk backup
|
|
211
|
-
nx-sk backup import --file ~/nx-sk/backup/xxx.nxskbak --password '你的备份口令'
|
|
210
|
+
nx-sk backup export --password '你的备份口令' --with-files # 连附件原件一起打包
|
|
211
|
+
nx-sk backup import --file ~/nx-sk/backup/xxx.nxskbak --password '你的备份口令' --dry-run # 先看合并计划
|
|
212
|
+
nx-sk backup import --file ~/nx-sk/backup/xxx.nxskbak --password '你的备份口令' # 缺省「合并」导入
|
|
213
|
+
nx-sk backup import --file ~/nx-sk/backup/xxx.nxskbak --password '你的备份口令' --replace # 才是整份替换
|
|
212
214
|
# 口令也可用环境变量 NX_SK_BACKUP_PASSWORD 提供
|
|
213
215
|
```
|
|
214
216
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
+
**导入缺省是「合并」**:只增补(补缺失的栏目/条目/附件、补空字段、结构只增不减),
|
|
218
|
+
不覆盖你已填过的值——两边都有值且不同时保留本地、列入冲突清单由你处理;
|
|
219
|
+
导入完成给出完整报告。`--replace` 才整份替换(灾难恢复 / 跨机器迁移用)。
|
|
220
|
+
两种方式都先自动留安全快照。
|
|
221
|
+
|
|
222
|
+
Web 面板的「加密备份」页同样支持:导出在浏览器下载 `.nxskbak`(可勾选连附件一起打包),
|
|
223
|
+
导入选择文件并输入口令、报告以弹窗呈现;口令错误或文件损坏会明确报错、不改动当前数据。
|
|
217
224
|
|
|
218
225
|
## 数据与安全
|
|
219
226
|
|
|
@@ -225,7 +232,7 @@ Web 面板的「加密备份」页同样支持:导出在浏览器下载 `.nxsk
|
|
|
225
232
|
| 快照 | 每次破坏性写入前整库备份到 `~/nx-sk/backup/`(最多 20 份),拷回即回滚 |
|
|
226
233
|
| 导出 | `~/nx-sk/export/`,默认不含凭据明文 |
|
|
227
234
|
| 附件 | `~/nx-sk/files/` 存二进制原件,元数据在 `store.json` 的 `files`(sha256 去重;条目 `file` 字段存附件 id 即建立链接;`file restore` 可逆) |
|
|
228
|
-
| 加密备份 | `.nxskbak`:整库经 scrypt(口令)+AES-256-GCM
|
|
235
|
+
| 加密备份 | `.nxskbak`:整库经 scrypt(口令)+AES-256-GCM 加密,口令不落盘;附件台账恒随包(`--with-files` 连原件);导入缺省「合并」只增不减,`--replace` 整份替换;动手前自动留安全快照 |
|
|
229
236
|
| 服务绑定 | 默认 `127.0.0.1`,不暴露到局域网;写操作校验 `Origin` |
|
|
230
237
|
| 数据损坏 | `store.json` 解析失败会先被改名为 `.corrupt-<时间戳>.json`,不会静默覆盖 |
|
|
231
238
|
|
|
@@ -258,7 +265,7 @@ nx-sk skill get nx-sk 10-sections-entries # 裸名 → references/10-sections-
|
|
|
258
265
|
## 开发
|
|
259
266
|
|
|
260
267
|
```bash
|
|
261
|
-
pnpm test # = lint + build + 冒烟(
|
|
268
|
+
pnpm test # = lint + build + 冒烟(99 项断言) + 单测(127 项)
|
|
262
269
|
```
|
|
263
270
|
|
|
264
271
|
| 目录 | 职责 |
|
|
@@ -82,15 +82,23 @@ cp ~/nx-sk/backup/20260924-144238-entry-remove-e_xxx.json ~/nx-sk/store.json
|
|
|
82
82
|
## 五、口令加密备份 / 恢复(导入导出)
|
|
83
83
|
|
|
84
84
|
整份数据用**口令派生密钥 + AES-256-GCM** 对称加密为单个 `.nxskbak` 文件;口令不落盘。
|
|
85
|
+
附件**台账**始终随包;`--with-files` 再把原件本体也嵌进包里(v3 格式)。
|
|
85
86
|
|
|
86
87
|
```bash
|
|
87
88
|
nx-sk backup export --password '备份口令' # → ~/nx-sk/backup/nx-sk-backup-<时间>.nxskbak
|
|
89
|
+
nx-sk backup export --password '备份口令' --with-files # 连附件原件一起打包(体积显著变大)
|
|
88
90
|
nx-sk backup export --password '备份口令' --out D:/备份 # 指定输出目录
|
|
89
|
-
|
|
90
|
-
nx-sk backup import --file <备份>.nxskbak --password '
|
|
91
|
+
|
|
92
|
+
nx-sk backup import --file <备份>.nxskbak --password '口令' --dry-run # 只解密 + 出合并计划,不改动
|
|
93
|
+
nx-sk backup import --file <备份>.nxskbak --password '口令' # 缺省「合并」导入
|
|
94
|
+
nx-sk backup import --file <备份>.nxskbak --password '口令' --replace # 整份替换(旧行为)
|
|
91
95
|
```
|
|
92
96
|
|
|
93
97
|
- 导出时文件内写入**随机盐**,密钥由 `scrypt(口令, 盐)` 派生;恢复时用同一口令派生同一把密钥。
|
|
94
98
|
- **口令错误 / 文件被篡改**:GCM 认证失败、明确报 BLOCKED,且不改动当前数据。
|
|
95
|
-
-
|
|
96
|
-
-
|
|
99
|
+
- **导入(缺省 = 合并)只增不减**:补缺失的栏目/条目/附件台账、补空字段、把备份多出的分组与字段补进已有栏目;**两边都有值且不同 → 保留本地**、列入冲突清单由你处理;本地已有数据与结构**永不删改**。报告会列出新增/补空/冲突/结构差异的完整明细。
|
|
100
|
+
- **`--replace` 才是整份替换**(灾难恢复 / 跨机器迁移用):当前数据被备份整体覆盖。
|
|
101
|
+
- 两种方式都会**先自动留安全快照**(`…-before-import.json` / `…-before-restore.json`),可回滚。
|
|
102
|
+
- 敏感字段在包内是明文(靠口令保护),导入时自动用**本机 vaultKey** 重新加密落盘——报告里的值一律打码,密钥明文不进报告。
|
|
103
|
+
- 带 `--with-files` 的包导入时自动还原附件原件(sha256 校验;磁盘已有且内容不同则以磁盘为准);v2 旧包可导入,但不含原件,报告会如实列出缺哪些文件。
|
|
104
|
+
- 口令也可用环境变量 `NX_SK_BACKUP_PASSWORD` 提供;Web「加密备份」页提供同样能力(浏览器下载 / 选择文件导入;超大包建议走 CLI)。
|
package/package.json
CHANGED
|
@@ -10,10 +10,11 @@ export default {
|
|
|
10
10
|
id: 'backup.export',
|
|
11
11
|
cli: ['backup', 'export'],
|
|
12
12
|
http: ['POST', '/api/backup'],
|
|
13
|
-
summary: '把整份数据用口令对称加密(AES-256-GCM
|
|
13
|
+
summary: '把整份数据用口令对称加密(AES-256-GCM)导出为单个备份文件;口令不落盘;--with-files 连附件原件一起打包',
|
|
14
14
|
flags: {
|
|
15
15
|
password: { type: 'string', hint: '备份口令(也可用环境变量 NX_SK_BACKUP_PASSWORD),恢复时需再次输入' },
|
|
16
16
|
out: { type: 'string', hint: '输出目录,缺省 ~/nx-sk/backup' },
|
|
17
|
+
'with-files': { type: 'boolean', hint: '把附件原件一并嵌进备份(体积显著变大;恢复时自动还原附件库)' },
|
|
17
18
|
'dry-run': { type: 'boolean', hint: '只演练:生成密文但不写文件、不下载' },
|
|
18
19
|
},
|
|
19
20
|
run: (ctx, meta) => (meta?.transport === 'http'
|
|
@@ -25,15 +26,19 @@ export default {
|
|
|
25
26
|
id: 'backup.import',
|
|
26
27
|
cli: ['backup', 'import'],
|
|
27
28
|
http: ['POST', '/api/backup/restore'],
|
|
28
|
-
summary: '
|
|
29
|
+
summary: '解密备份并导入:缺省合并进当前数据(只增补、不覆盖已有值,冲突列出待手动处理),--replace 才整份替换;两种方式都先留安全快照',
|
|
29
30
|
flags: {
|
|
30
31
|
password: { type: 'string', hint: '导出时设置的口令(也可用环境变量 NX_SK_BACKUP_PASSWORD)' },
|
|
31
32
|
file: { type: 'string', hint: '备份文件路径(CLI 用)' },
|
|
32
33
|
content: { type: 'string', hint: '备份文件内容(Web 上传时自动带)' },
|
|
33
|
-
|
|
34
|
+
replace: { type: 'boolean', hint: '整份替换(旧行为):当前数据被备份整体覆盖;缺省是合并' },
|
|
35
|
+
'dry-run': { type: 'boolean', hint: '只解密校验并出合并计划,不写数据、不留快照' },
|
|
34
36
|
},
|
|
35
37
|
run: (ctx) => (ctx.content !== undefined
|
|
36
|
-
? service.restoreBackup({
|
|
38
|
+
? service.restoreBackup({
|
|
39
|
+
content: ctx.content, password: ctx.password,
|
|
40
|
+
replace: ctx.replace === true, 'dry-run': ctx['dry-run'],
|
|
41
|
+
})
|
|
37
42
|
: service.importBackup(ctx)),
|
|
38
43
|
render: (d) => service.renderRestore(d),
|
|
39
44
|
},
|