nx-sk 0.18.0 → 0.23.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 +250 -0
- package/README.md +101 -5
- package/assets/nx-sk/SKILL.md +68 -16
- package/assets/nx-sk/references/00-design.md +3 -3
- package/assets/nx-sk/references/10-sections-entries.md +128 -12
- package/assets/nx-sk/references/15-special-fields.md +197 -0
- package/assets/nx-sk/references/40-files.md +44 -8
- package/assets/nx-sk/references/60-transfer.md +10 -4
- package/assets/sk-needdo/SKILL.md +2 -0
- package/assets/sk-source/SKILL.md +11 -1
- package/assets/sk-source/references/20-intake.md +3 -0
- package/package.json +15 -4
- package/src/core/attachments.js +51 -5
- package/src/core/fields.js +138 -13
- package/src/core/paths.js +11 -0
- package/src/core/render.js +71 -4
- package/src/core/source.js +47 -7
- package/src/core/store.js +56 -6
- package/src/core/vault.js +33 -8
- package/src/modules/entries/aiPending.js +303 -0
- package/src/modules/entries/blockPanel.jsx +239 -0
- package/src/modules/entries/boardView.jsx +136 -0
- package/src/modules/entries/entriesTable.jsx +119 -0
- package/src/modules/entries/index.js +174 -0
- package/src/modules/entries/service.js +875 -27
- package/src/modules/entries/view.jsx +136 -6
- package/src/modules/sections/index.js +94 -1
- package/src/modules/sections/service.js +643 -11
- package/src/modules/sections/view.jsx +770 -79
- package/src/modules/settings/service.js +90 -7
- package/src/modules/system/service.js +19 -3
- package/src/modules/transfer/service.js +165 -4
- package/src/shared/blocks.js +400 -0
- package/src/shared/navTree.js +252 -0
- package/src/shared/table.js +884 -0
- package/src/shared/views.js +221 -0
- package/src/web/frontend/App.jsx +200 -234
- package/src/web/frontend/activeView.js +56 -0
- package/src/web/frontend/blocks/registry.jsx +304 -0
- package/src/web/frontend/components/aiBar.jsx +192 -0
- package/src/web/frontend/components/blockDnd.jsx +69 -0
- package/src/web/frontend/components/fieldEditor.jsx +24 -4
- package/src/web/frontend/components/listDrag.jsx +82 -0
- package/src/web/frontend/components/sidebar.jsx +354 -0
- package/src/web/frontend/components/sourcePanel.jsx +179 -22
- package/src/web/frontend/components/tableField.jsx +477 -0
- package/src/web/frontend/components/viewChips.jsx +43 -0
- package/src/web/frontend/listSort.js +18 -0
- package/src/web/frontend/main.jsx +4 -0
- package/src/web/frontend/panels.jsx +75 -0
- package/src/web/frontend/store.jsx +4 -1
- package/src/web/frontend/styles.css +536 -0
- package/src/web/frontend/workspace.js +253 -0
- package/src/web/public/assets/{files--aIy09Sp.js → files-BoJqTGyZ.js} +1 -1
- package/src/web/public/assets/index-DDcA8xZc.js +64 -0
- package/src/web/public/assets/index-FDvbnX_f.css +1 -0
- package/src/web/public/assets/{view-0jlrnuBr.js → view-B04bzsph.js} +1 -1
- package/src/web/public/assets/view-CvJr_elT.js +42 -0
- package/src/web/public/assets/{view-Bt7O8gS_.js → view-DNT9of0L.js} +1 -1
- package/src/web/public/assets/view-tNIpJ3PQ.js +1 -0
- package/src/web/public/assets/view-xwEy1P7C.js +3 -0
- package/src/web/public/index.html +2 -2
- package/src/web/public/assets/index-BWIrglCf.js +0 -41
- package/src/web/public/assets/index-CEIiV0jA.css +0 -1
- package/src/web/public/assets/view-1SYBZ3dg.js +0 -1
- package/src/web/public/assets/view-Bt8MZAtu.js +0 -1
- package/src/web/public/assets/view-CjX_ywS7.js +0 -36
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,256 @@
|
|
|
2
2
|
|
|
3
3
|
本文件格式参考 [Keep a Changelog](https://keepachangelog.com/),中文正文。
|
|
4
4
|
|
|
5
|
+
## 0.23.0 (2026-10-31)
|
|
6
|
+
|
|
7
|
+
**应用壳换成可停靠的工作区(Notion 式目录树 + FlexLayout);看板视图落地;条目有了块级 AI 的「提议 → 审 → 应用/拒绝」流;栏目结构在面板里可自己搭。**
|
|
8
|
+
|
|
9
|
+
壳是「面板的布局由你自己摆」:栏目只从目录树进,布局跨会话恢复。
|
|
10
|
+
AI **不自带大模型**——提议由调用方(agent 或外部模型)交进来,人只做评审。
|
|
11
|
+
**栏目结构**(分组 + 字段)过去只有命令行能改:面板连建一个分组都要回 CLI 或换模板——
|
|
12
|
+
于是「这个栏目长什么样」这件事面板说了不算。这次把四个分组操作与两个字段操作做成
|
|
13
|
+
action(面板与 CLI 同一份),面板「编辑栏目」里直接可改。
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **Notion 式工作区壳**:
|
|
18
|
+
- 顶栏只留全局动作(品牌 / 存储 / 打码 / +面板 / 撤销重做 / 设置 / 刷新);
|
|
19
|
+
**栏目 tab 从顶栏移除**——栏目只从目录树进,两处入口必然分叉。
|
|
20
|
+
- 目录树:栏目 + 分组 + 条目子节点;**拖拽重排与嵌套**(第一次拖动把「从旧导航配置
|
|
21
|
+
推断出的树」固化成显式 `settings.navTree`,之前始终只读推断、不写回);
|
|
22
|
+
隐藏的栏目收在树底(一键恢复,数据不动)。
|
|
23
|
+
- 布局 = FlexLayout 模型:面板可拖到任意一边拆分、弹出成浮窗;布局存
|
|
24
|
+
localStorage(`nx-sk-ui.workspace`),跨会话恢复;撤销/重做按「整段拖拽 = 一步」。
|
|
25
|
+
- 深链升级为两段:`#/栏目` 开该栏目的数据库面板,`#/栏目/条目` 再定位到条目;
|
|
26
|
+
栏目 / 条目缺失时明确提示是哪一级没了。
|
|
27
|
+
- 正文块支持拖拽排序(块头把手);数据库面板即工作区里的一块面板,可与其他面板并列。
|
|
28
|
+
- **看板视图**:列 = select 字段的候选值;**拖卡 = 写操作**,等于 `entry update --set 字段=值`;
|
|
29
|
+
空值与候选外的值落「未分组」列,不静默丢,「未分组」不是落点。
|
|
30
|
+
- **块级 AI(提议 → 审 → 应用/拒绝)**:
|
|
31
|
+
- CLI:`entry ai list | suggest | apply | reject`(HTTP 同名路由)。
|
|
32
|
+
`suggest` 收 `--from @proposal.json`(AI 给出的**最终正文**)与 `--prompt`(指令留痕),
|
|
33
|
+
只落一条 pending;`apply` 才写 store;`reject` 只删文件。
|
|
34
|
+
- **pending 落 `~/nx-sk/pending/`(运行态)**:不进 `store.json`、不进导出包、不进迁移副本
|
|
35
|
+
——里面对 secret 块是明文,落进数据面就等于写进备份与导出面。删目录即清空。
|
|
36
|
+
- diff 是**字符级**的:`same / del / ins` 三段,面板上红删绿增;容器块的改动由子块表达
|
|
37
|
+
(不把父块一起报成改动);secret 块只报「变了」,明文不经面板接口。
|
|
38
|
+
- **冲突检测**:pending 记每块应用前的 `baseHash`(服务端算),块被改过 → `CONFLICT`,
|
|
39
|
+
一个字都不写;`--force` 才覆盖。没有差异的提议返回 `noop`,不留空的待审。
|
|
40
|
+
- secret 块的差异按**明文**比对(store 里是密文、提议里是明文),否则一个没动的密钥
|
|
41
|
+
会被报成「密文块已变更」。
|
|
42
|
+
- **表格 / 清单:行与列都能拖**(Notion 那种手感):拖**表头**搬列、拖行尾的 ⠿ 搬行,
|
|
43
|
+
松手前一条**插入线**告诉你落在哪(只高亮整行说不清「会插到哪」)。排序算法单独一个
|
|
44
|
+
`reorderAt`(插入位语义,有单测)——差一的表现是「拖到第二行结果跑到第三行」。
|
|
45
|
+
整行不做 `draggable`:那会跟单元格里选文本打架,把手是唯一的拖拽入口。
|
|
46
|
+
↑↓ / ←→ 保留但**悬停才浮出**,行内操作键统一收成 16px 小图标键(密集表里的按钮
|
|
47
|
+
不该抢内容的注意力);entrylist 那颗「正常大小的删除按钮」也换成了小图标键。
|
|
48
|
+
- **降级运行的主动提示**:store 由更新版本写入时,`bootstrap` 与 `health`(CLI 输出与 JSON)
|
|
49
|
+
会明确说明「磁盘版本 > 当前版本,写入会被拒」——不等用户改一次被 BLOCKED 才知道。
|
|
50
|
+
- **栏目结构在面板里可自己搭**:分组能增删改序,字段能改名 / 换组 / 换类型 / 换位置。
|
|
51
|
+
- **分组骨架**:`section update --add-group / --rename-group / --move-group / --remove-group`。
|
|
52
|
+
改名可以**连 id 一起换**(组里字段的 `group` 引用跟着改,不会整组从表单里消失)。
|
|
53
|
+
三条规矩全是**拦下来**而不是悄悄做:id 重复报 `CONFLICT`(不覆盖同名分组)、
|
|
54
|
+
**非空分组不给删**(报 `BLOCKED` 并列出是哪几个字段)、内置「原始资料」分组不给删。
|
|
55
|
+
- **字段级改动**:`section update --set-field`(标签 / 类型 / 分组 / 提示 / 必填策略)
|
|
56
|
+
与 `--move-field`(在自己分组内上下挪)。**key 不可改**——值按 key 存在条目里,
|
|
57
|
+
改 key 等于让已有值读不出来;要换就新增字段再搬值。
|
|
58
|
+
- **面板**:「编辑栏目」弹窗里两块——「分组」(id / 名字就地改、↑↓ 换序、空组才能删)
|
|
59
|
+
与「字段字典」(每行可改标签 / 类型 / 分组 / 提示 / 必填策略,组内 ↑↓,删除)。
|
|
60
|
+
一次改动一次落盘(每次改动都要过后端校验,出错时知道是哪一步),改完立刻回读。
|
|
61
|
+
清单类字段(`entrylist` / `table`)的**类型置灰**:列是字段自己的结构,
|
|
62
|
+
就地换类型等于换一个字段——要建就在「新增字段」里连列一起建。
|
|
63
|
+
- 每次改动都把**新旧值**打进输出(`字段 phone:分组 contact → reach`),
|
|
64
|
+
不再只说「已更新栏目 job:fields」——那种输出改错了没法回溯。
|
|
65
|
+
|
|
66
|
+
### Fixed
|
|
67
|
+
|
|
68
|
+
- **导入会把打码的密钥块加密存盘**(与 0.19 字段路径同类缺陷):导入包里的 `******`
|
|
69
|
+
占位会被当成真密钥加密落盘。现在值清空待重填,并在预览里计数与警告;
|
|
70
|
+
导出预览的掩码统计同步扩到块。
|
|
71
|
+
- **表格/看板视图把详情列挤成一条竖缝**(S2 起的老缺陷,列多的栏目才暴露):
|
|
72
|
+
表格列的 flex 基准用的是内容宽度(75 列 ≈ 7300px),行溢出时按基准比例收缩,
|
|
73
|
+
详情列被抽走全部溢出量。现在表格列 basis 为 0(「拿剩余空间」),
|
|
74
|
+
横向滚动交给表格与看板自己的 overflow。
|
|
75
|
+
- **布局里的空面板组自愈**:拖动/关闭面板可能留下空 tabset,FlexLayout 会把它原样
|
|
76
|
+
存盘、恢复时渲染成一块白板。现在存盘与恢复两端都剪掉空面板组——
|
|
77
|
+
已经存坏的布局**刷新即自愈**,不用点「重置布局」。
|
|
78
|
+
|
|
79
|
+
## 0.22.0 (2026-10-31)
|
|
80
|
+
|
|
81
|
+
**原始资料的 text 底层改为 markdown:图片内嵌在正文里,图文不再分家。**
|
|
82
|
+
|
|
83
|
+
聊天记录是图文混排的——把文字存成一条、图存成另一个附件条目,等于把一段话拆得没头没尾。
|
|
84
|
+
所以 `text` 直接以 markdown 为底层:`` 内嵌附件库的图、`` 直接外链,
|
|
85
|
+
正文照旧原样存(面板上的修改是人显式点了「编辑」)。
|
|
86
|
+
|
|
87
|
+
### Added
|
|
88
|
+
|
|
89
|
+
- **抽屉收集即排版**:粘贴框变成 markdown 收集器——图片直接 **Ctrl+V** 或**拖进编辑器**(自动上传
|
|
90
|
+
附件库并在光标处插入引用)、「插入图片」按钮选文件;图片内嵌显示,其它文件以可点链接内嵌。
|
|
91
|
+
拖拽两条路语义不同:拖**编辑器** = 插进正文,拖**左栏清单** = 入袋成附件条目。
|
|
92
|
+
- **text 条目可显式编辑**:正文面板加「编辑 / 保存修改」(就地更新——是人点的保存,
|
|
93
|
+
「原文不改写」的纪律不破);正文渲染走与 md 字段同一台机器(图片解析 / 外链 / 点击放大 / 任务勾选)。
|
|
94
|
+
- 导出/导入:资料袋正文里内嵌的图片引用计入**引用扫描**(随包带走)并在导入时**重映射**到新库 id
|
|
95
|
+
(`sourceImageIds` 一处实现,打包与完整性检查共用)。
|
|
96
|
+
- CLI:`source get` 的 text 用 `rewriteMdImages` 还原成 `[图片: 说明] 本地路径`(外链标注「外链」);
|
|
97
|
+
标题推断与摘要压掉图片语法(`` 不再当标题、摘要里是 `[图: 说明]`)。
|
|
98
|
+
|
|
99
|
+
### Compatibility
|
|
100
|
+
|
|
101
|
+
- **老数据不用迁移**:普通文字本来就是合法 markdown(段落 + 换行),渲染层无缝接管;
|
|
102
|
+
`--set source='随手记'`、`source add --text` 的用法全部不变。
|
|
103
|
+
|
|
104
|
+
## 0.21.0 (2026-10-30)
|
|
105
|
+
|
|
106
|
+
**条目有了块正文(`entry.body`);栏目有了数据库视图(`section.views`)。**
|
|
107
|
+
|
|
108
|
+
块是「递归的内容单元」,视图是「同一批数据的多种投影」。两者都**只加可选键**,
|
|
109
|
+
老 store 一个字节不用改;反方向的降级被显式拦住(见 Changed)。
|
|
110
|
+
|
|
111
|
+
### Added
|
|
112
|
+
|
|
113
|
+
- **块正文**:`entry.body: Block[]`,七种叶块(段落 / 标题 / 图文 / 表格 / 清单 / 附件 / 密钥)
|
|
114
|
+
与两种容器块(内嵌栏目 `section` / 分栏 `column`,容器块的编辑随下一版)。
|
|
115
|
+
- CLI:`entry block add | update | move | remove | remove-many`、`entry body <ref> [--mask]`;
|
|
116
|
+
HTTP 同名路由,**一条 action 双端**(面板与 CLI 走同一份 service)。
|
|
117
|
+
- 详细页下半部分是块面板:双击编辑文本块、表格块复用表格字段的同一台机器(公式/统计照旧)、
|
|
118
|
+
密钥块与 secret 字段同一条 AES-256-GCM 路径,打码态**只读**(把星号写回去等于把星号存成密钥)。
|
|
119
|
+
- 块随导出包往返;file 块里的附件 id 计入引用扫描(`file cleanup` 不会误删);
|
|
120
|
+
md 块里的贴图随包重映射。
|
|
121
|
+
- **数据库视图**:`section.views` / `section.defaultView`。
|
|
122
|
+
- CLI:`section view list | add | update | remove | set-default`(HTTP 同名路由)。
|
|
123
|
+
- **缺省视图是推断的、不落盘**:非 KV 栏目给「表格 / 精简 / 看板」,KV 栏目给「KV」;
|
|
124
|
+
第一次改视图才固化(并把当时生效的那套一起写进去,chips 不会凭空消失)。
|
|
125
|
+
- 投影只存 `key/width/hidden`,标签与类型回查字段字典;引用的字段被删 → 列还在,
|
|
126
|
+
表头写「已删字段」、单元格「—」(不炸、也不静默消失)。
|
|
127
|
+
- 面板:栏目页顶部视图 chips + 表格视图(横向投影,密文列在表格里一律打码)。
|
|
128
|
+
看板**渲染**随下一版(配置与 action 已可用)。
|
|
129
|
+
- **Notion 式工作区壳**(S3):
|
|
130
|
+
- 顶栏只留全局动作(品牌 / 存储 / 打码 / +面板 / 撤销重做 / 设置 / 刷新);
|
|
131
|
+
**栏目 tab 从顶栏移除**——栏目只从目录树进,两处入口必然分叉。
|
|
132
|
+
- 目录树:栏目 + 分组 + 条目子节点;**拖拽重排与嵌套**(第一次拖动把「从旧导航配置
|
|
133
|
+
推断出的树」固化成显式 `settings.navTree`,之前始终只读推断、不写回);
|
|
134
|
+
隐藏的栏目收在树底(一键恢复,数据不动)。
|
|
135
|
+
- 布局 = FlexLayout 模型:面板可拖到任意一边拆分、弹出成浮窗;布局存
|
|
136
|
+
localStorage(`nx-sk-ui.workspace`),跨会话恢复;撤销/重做按「整段拖拽 = 一步」。
|
|
137
|
+
- 深链升级为两段:`#/栏目` 开该栏目的数据库面板,`#/栏目/条目` 再定位到条目;
|
|
138
|
+
栏目 / 条目缺失时明确提示是哪一级没了。
|
|
139
|
+
- 正文块支持拖拽排序(块头把手);数据库面板即工作区里的一块面板,可与其他面板并列。
|
|
140
|
+
- **块级 AI(提议 → 审 → 应用/拒绝)**(S4):
|
|
141
|
+
- CLI:`entry ai list | suggest | apply | reject`(HTTP 同名路由)。
|
|
142
|
+
`suggest` 收 `--from @proposal.json`(AI 给出的**最终正文**)与 `--prompt`(指令留痕),
|
|
143
|
+
只落一条 pending;`apply` 才写 store;`reject` 只删文件。
|
|
144
|
+
- **nx-sk 不自带大模型**:提议由调用方(agent 或外部模型)产出后交进来。这样
|
|
145
|
+
「agent 走 CLI」与「人在面板上审同一条 pending」是同一套语义,不需要第二个 AI 入口。
|
|
146
|
+
- **pending 落 `~/nx-sk/pending/`(运行态)**:不进 `store.json`、不进导出包、不进迁移副本
|
|
147
|
+
——里面对 secret 块是明文,落进数据面就等于写进备份与导出面。删目录即清空。
|
|
148
|
+
- diff 是**字符级**的:`same / del / ins` 三段,面板上红删绿增;容器块的改动由子块表达
|
|
149
|
+
(不把父块一起报成改动);secret 块只报「变了」,明文不经面板接口。
|
|
150
|
+
- **冲突检测**:pending 记每块应用前的 `baseHash`(服务端算),块被改过 → `CONFLICT`,
|
|
151
|
+
一个字都不写;`--force` 才覆盖。没有差异的提议返回 `noop`,不留空的待审。
|
|
152
|
+
- secret 块的差异按**明文**比对(store 里是密文、提议里是明文),否则一个没动的密钥
|
|
153
|
+
会被报成「密文块已变更」。
|
|
154
|
+
|
|
155
|
+
### Changed
|
|
156
|
+
|
|
157
|
+
- **`STORE_VERSION` 3 → 4**。只加可选键、无迁移函数;但**老版本读 v4 store 后写入会被拒**
|
|
158
|
+
(`BLOCKED`:「store 由更新版本的 nx-sk 写入」)。不拦的话,老版本的白名单归一会把
|
|
159
|
+
`body` / `views` 静默抹掉,且版本号相同、无从警告。
|
|
160
|
+
- **导出包 `formatVersion` 1 → 2**(包里多了 `entries[].body` 与 `section.views`)。
|
|
161
|
+
老版本读到新包会明确报「版本过新,请先升级」,而不是把两个键静默丢掉。
|
|
162
|
+
导入时视图只在「新建栏目」或「目标没配过视图」时应用——目标已有视图说明用户自己配过,不覆盖。
|
|
163
|
+
|
|
164
|
+
### Fixed
|
|
165
|
+
|
|
166
|
+
- **表格字段的敏感列导出为明文**(0.19 起的老缺陷):`plainValues` 没有 table 分支,
|
|
167
|
+
导出包里是密文 blob,跨机器导入永远解不开。现在与其它敏感字段同一口径(包里明文,保护靠口令)。
|
|
168
|
+
- 块面板在 `bootstrap` 后渲染崩溃(注释与函数声明粘连导致 TDZ)。
|
|
169
|
+
|
|
170
|
+
## 0.20.0 (2026-10-30)
|
|
171
|
+
|
|
172
|
+
**栏目管理重构成树;初始化不再播种一堆场景栏目,改播一个「字段样例」说明书。**
|
|
173
|
+
|
|
174
|
+
### Added
|
|
175
|
+
|
|
176
|
+
- **栏目管理 = 栏目 → 条目的树**(`section tree`,HTTP `GET /api/sections/tree`):
|
|
177
|
+
可展开/收起(展开态记在面板设置里)、**多选 / 全选**(勾栏目 = 连条目一起,条目可单独勾)、
|
|
178
|
+
**批量删除**(`section remove-many` / `entry remove-many`,HTTP 同名 POST 路由)——
|
|
179
|
+
精确到条目,删栏目等同删文件夹(连带条目,需显式确认);找不到的跳过并报告(status: partial),
|
|
180
|
+
一个都找不到才报错。栏目多时的搜索:栏目命中整棵留下,只有条目命中时只留命中的并临时展开。
|
|
181
|
+
- **初始化只播种一个「字段样例」栏目**(`demo` 模板,连一条示例条目一起):
|
|
182
|
+
标量字段(文本/数字/是否/下拉/日期/标签)、组合字段(结构清单 + 表格:计算列与表尾统计)、
|
|
183
|
+
富内容(图文 / 附件 / 密钥)各来一份,外加自带的「原始资料」袋——
|
|
184
|
+
第一屏是说明书,不是别人的表格。求职 / 密钥 / 项目那 6 个场景模板仍是模板(`section add --template`)。
|
|
185
|
+
- **没有 KV 栏目时第一次 `key set` 自动补建**(与 `section add secret --template secret` 同形状;
|
|
186
|
+
读命令不建)。播种不再自带密钥栏目后,`key set` 的「我要存」不该被「先建栏目」挡住。
|
|
187
|
+
|
|
188
|
+
### Changed
|
|
189
|
+
|
|
190
|
+
- `settings.defaultSection` 缺省从 `job` 改为 `demo`(指向播种的那个栏目)。
|
|
191
|
+
- 面板「栏目」页整页重构:平铺列表 → 树 + 批量条 + 搜索;存量用户的 store 不受影响
|
|
192
|
+
(播种只发生在「store 文件不存在」时,文件在、栏目为空依旧不复活)。
|
|
193
|
+
|
|
194
|
+
## 0.19.0 (2026-10-30)
|
|
195
|
+
|
|
196
|
+
**新字段类型 `table`:结构写在数据里的表单表格。**
|
|
197
|
+
|
|
198
|
+
`entrylist` 是「变长的几列文本」;`table` 是它的进阶形态——每格有类型(勾选 / 下拉 / 数字 /
|
|
199
|
+
日期),带**计算列**与**表尾统计**。关键差别不在功能多少,在**结构归谁**:
|
|
200
|
+
`table` 的列定义、行、公式、统计配置全部存在**条目值里**,不在栏目字典里。
|
|
201
|
+
因此「这一条想多一列」不必改 schema,也不会波及同栏目的其它条目;
|
|
202
|
+
面板上直接加列 / 改类型 / 写公式,改完就是这份数据的一部分。
|
|
203
|
+
|
|
204
|
+
### Added
|
|
205
|
+
|
|
206
|
+
- **`type: 'table'` 表格字段**(`src/shared/table.js` 为计算内核,前后端同一份实现):
|
|
207
|
+
- 值是一份**自描述文档**:`{v, columns, rows, totals?, summary?}`。三种输入都认——
|
|
208
|
+
行数组(列取字段的「初始列」或从行推断)、文档本身、以及它们的 JSON 串。
|
|
209
|
+
- 列有类型:`text / textarea / number / bool / select / date / month / tags`;
|
|
210
|
+
给 `formula` 就是**计算列**(不落盘,读时现算);`sensitive: true` 的列密文落盘。
|
|
211
|
+
- 公式是 **JS 表达式**(不发明语法),只包成 `return ( … )`:列 key 与**中文列名**
|
|
212
|
+
都能当变量,`row` 取原值、`rows` 取整表、`col("列名")` 取一列;
|
|
213
|
+
`sum / avg / min / max / count / countTrue / distinct / median / pct / round / isBlank …`
|
|
214
|
+
与 `Math`、`JSON` 等内建可用。求值作用域用 `with` + Proxy 封死,`window / process / fetch` 取不到。
|
|
215
|
+
- **统计两层**:列上的 `total` 决定表尾那一格(数字默认求和、勾选默认计是,
|
|
216
|
+
多种统计方式自动分组成「合计 / 平均…」多行);整表表达式写在数据的 `totals` 里
|
|
217
|
+
(如完成率 `pct(countTrue(col("done")), n)`)。统计不落盘,读时现算。
|
|
218
|
+
- 错误停在能看懂的那一层:「不存在的名字『qty』,可用的名字:a、b…」、
|
|
219
|
+
「计算列只能引用它前面的列」、「结果不是有限数字(除以 0)」——不吐 NaN。
|
|
220
|
+
- 新命令 `nx-sk entry table <条目> --field <表格字段>`(HTTP `GET /api/tables/:ref`):
|
|
221
|
+
只读地印出表头 / 数据 / 计算列 / 合计 / 公式报错。
|
|
222
|
+
- 面板:`tableField.jsx` 的表格控件——勾选框 / 下拉框 / 数字 / 日期就地编辑,
|
|
223
|
+
回车换下一行、Alt+↑↓ 跳上下格、行可上下移与删除;「列设置」里加列 / 改类型 /
|
|
224
|
+
写公式 / 指定统计方式 / 默认值 / 左右移 / 删列(连值一起删,改 key 会搬值)。
|
|
225
|
+
栏目编辑页新增字段时可直接配初始列。
|
|
226
|
+
- **写入即体检**:每条公式在保存前用一行空值当探针跑一遍,只拦**与数据无关**的错
|
|
227
|
+
(语法错 / 名字解析不到 / 结果不是单值),除零这类「这条数据不巧」留到渲染时逐格报。
|
|
228
|
+
列、行、默认值、下拉候选、`total`、`totals` 全走同一条校验,面板与 CLI 共用。
|
|
229
|
+
- 列可以带 `default`(新增行时的初值,按类型强转;`0` / `false` 都合法)。
|
|
230
|
+
- 新 reference `assets/nx-sk/references/15-special-fields.md`:值不是标量的字段
|
|
231
|
+
(`table` / `entrylist` / `md` / `file` / `source` / `secret`)的形状、规矩、
|
|
232
|
+
公式与统计口径、错误对照表;`10-sections-entries` 里那份表格说明改为指向它(不留两份)。
|
|
233
|
+
|
|
234
|
+
### Changed
|
|
235
|
+
|
|
236
|
+
- **空表现在是合法的**:`--set 表=` / `[]` / `{}` / `{"columns":[],"rows":[]}` 都能把表清空
|
|
237
|
+
(值存 `null`);有初始列时 `[]` 留下「列在、行空」的骨架;只有「有行却没列」才报错。
|
|
238
|
+
原先「必须给列」的硬校验会把「只想清空」和「新建一张空表」一起挡掉。
|
|
239
|
+
- `isBlank` 与 `isStoredEmpty` 分开了:前者判完整度(有列没行的表算没填),
|
|
240
|
+
后者判「值要不要输出」(骨架必须带出去,否则面板拿不到列,搭好的结构一保存就"消失")。
|
|
241
|
+
- `serializeEntry` 对表格字段永远输出**自描述文档**(列跟着数据走),
|
|
242
|
+
所以 `entry get` / `section dump` / 导出拿到的东西不需要再回查栏目字典。
|
|
243
|
+
- `sensitiveViewer` 现在也认表格的密文列(原先只探 entrylist 的 `fields`),
|
|
244
|
+
并且列存在数据里时按「任一格是密文」判定,不会再退化成「需要密钥才能解密」。
|
|
245
|
+
- **短值的打码占位现在也认得出**:`maskValue` 对 ≤10 字符的值返回全星(`***`),
|
|
246
|
+
而老判断只认「连续 6 个星」,于是 3 位密码的打码值会被当成新密码加密存进去(无声数据损坏)。
|
|
247
|
+
- 空表算「未填」:`isBlank` 认 `{rows: []}`,完整度不会被一张没有行的表撑满。
|
|
248
|
+
|
|
249
|
+
### Fixed
|
|
250
|
+
|
|
251
|
+
- 表格的密文列在**打码显示**时保存:打码占位优先按打码值反查原密文(行被拖动过也能认对),
|
|
252
|
+
认不出来才退回行号兜底;已知限制(两格打码值一模一样又拖了行)写进文档。
|
|
253
|
+
- `sections` 的「新增字段」表单里 `toast` 未定义(校验失败时会抛 ReferenceError),现按 props 传入。
|
|
254
|
+
|
|
5
255
|
## 0.18.0 (2026-10-28)
|
|
6
256
|
|
|
7
257
|
**拖拽不再闪,悬浮不再乱弹;「原始资料」袋对每个栏目都成立。**
|
package/README.md
CHANGED
|
@@ -102,22 +102,35 @@ ln -s "$(pwd)/assets/nx-sk" "$HOME/.workbuddy/skills/nx-sk"
|
|
|
102
102
|
一个「本机工具类」项目的标准骨架实现(server-cli-web):**serve 驱动 CLI 与 Web,
|
|
103
103
|
CLI 与 API 同源,skill 驱动 agent**。落到具体功能上:
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
**首次运行只播种一个「字段样例」栏目**(`demo`),连一条示例条目一起——把能力直接摆给你看:
|
|
106
|
+
|
|
107
|
+
| 组 | 字段 |
|
|
108
|
+
| --- | --- |
|
|
109
|
+
| 基本字段(标量) | 单行文本 / 多行文本 / 数字 / 是否 / 下拉框 / 日期 / 月份 / 标签 |
|
|
110
|
+
| 组合字段(值有形状) | **结构清单**(变长行 + 密文列)、**表格**(列在数据里 + 计算列 + 表尾合计/平均/计数) |
|
|
111
|
+
| 富内容 | **图文**(markdown + 贴图 + 待办)、**附件**、**密钥**(AES-256-GCM 密文) |
|
|
112
|
+
|
|
113
|
+
外加每个栏目自带的「原始资料」袋。示例条目把这些都填好了——打开面板就能试,
|
|
114
|
+
改坏了自己删(`section remove demo`),或整栏重建(`section add demo --template demo`)。
|
|
115
|
+
|
|
116
|
+
**其它 8 个模板不再自动播种**,要用时建(模板只是**建议清单**,`--set 任意键=值` 直接写):
|
|
117
|
+
|
|
118
|
+
| 模板 | id | 内容 |
|
|
106
119
|
| --- | --- | --- |
|
|
107
|
-
| 求职 | `job` | 求职用的个人信息档案:10 个分组 / 80
|
|
120
|
+
| 求职 | `job` | 求职用的个人信息档案:10 个分组 / 80 个字段(姓名、学历、联系方式、求职意向、紧急联系人…) |
|
|
108
121
|
| 项目经历 | `projects` | 一个项目一个条目:名称 / 角色 / 时间 / 技术栈 / 职责与亮点 |
|
|
109
122
|
| 实习/工作经历 | `internships` | 一段经历一个条目:公司 / 岗位 / 时间 / 职责 |
|
|
110
123
|
| 校内职务/实践 | `campus` | 一条职务或实践一个条目:职务 / 组织 / 时间 / 职责 |
|
|
111
|
-
| 密钥 | `secret` | **一张 KV 表**(`kv: true`):面板上就是两列表格(名称 / 值),一行一个键。落盘是 **AES-256-GCM** 密文,读出来默认是原文(`--mask`
|
|
124
|
+
| 密钥 | `secret` | **一张 KV 表**(`kv: true`):面板上就是两列表格(名称 / 值),一行一个键。落盘是 **AES-256-GCM** 密文,读出来默认是原文(`--mask` 才打码)。第一次 `key set` 没有它时会自动补建 |
|
|
112
125
|
| 部署配置 | `deploy` | **一份配置文件一个条目**(Dockerfile / docker-compose / k8s 清单):正文即文件原文,外加「放哪 / 哪些值要替换 / **这个场景自己的凭据清单** / 何时用」,好让它在别的项目里照着用 |
|
|
113
126
|
|
|
114
|
-
|
|
127
|
+
栏目不是写死的——
|
|
115
128
|
字段字典是**数据**,加字段(`section update --add-field`,或 `entry update --set 任意键=值` 自动登记)、
|
|
116
129
|
加栏目(`section add`,不给模板就是空栏目全自定义)、删栏目都不用改代码。
|
|
117
130
|
模板在实例化时被**深拷贝**,此后各栏目独立演化;模板后来的新增用 `section sync` 补(只增不改不删,
|
|
118
131
|
有差异时会把「模板已改、栏目保留原值」的字段列出来提示)。
|
|
119
132
|
|
|
120
|
-
内置模板共 **
|
|
133
|
+
内置模板共 **9 个**——除 `demo` 与上面 6 个外还有 `platform`(容器平台:控制台链接 / 账号 / 密码 / 镜像)
|
|
121
134
|
与 `thesis`(毕业论文规范字段化),需要时 `section add <id> --template platform|thesis` 建。
|
|
122
135
|
|
|
123
136
|
## 三条核心不变量
|
|
@@ -150,10 +163,29 @@ CLI 与 API 同源,skill 驱动 agent**。落到具体功能上:
|
|
|
150
163
|
| `nx-sk routes [--module M] [--http "POST /api/entries"]` | 命令 ↔ 路由双向对照 |
|
|
151
164
|
| `nx-sk section list \| get \| add \| update \| remove` | 栏目 CRUD |
|
|
152
165
|
| `nx-sk section dump <id> [--mask]` | **一个栏目的全部信息**:字段台账 + 全部条目 + 每个条目的未填清单 |
|
|
166
|
+
| `nx-sk section tree` | **栏目树**:每个栏目 + 它的条目索引(名称 / 完整度)——面板「栏目管理」一次拿齐,不必逐个 dump |
|
|
167
|
+
| `nx-sk section remove-many <ids> [--force]` | 批量删栏目(等同删文件夹,连带条目;有非空栏目必须 `--force`)。找不到的跳过并报告 |
|
|
168
|
+
| `nx-sk entry remove-many <ids>` | 批量删条目(ids 逗号分隔);找不到的跳过并报告,一个都找不到才报错 |
|
|
153
169
|
| `nx-sk section templates` | 内置模板(job / secret / projects / internships / campus / deploy / platform / thesis) |
|
|
154
170
|
| `nx-sk section sync <id> [--dry-run]` | 按模板**补齐**本栏目缺的分组与字段(只增不改不删)——模板演进后让老栏目追上 |
|
|
171
|
+
| `nx-sk section update <id> --add-group / --rename-group / --move-group / --remove-group` | 改**分组骨架**:新增 / 改名(可换 id,字段引用跟着改)/ 上下挪 / 删(空的才让删) |
|
|
172
|
+
| `nx-sk section update <id> --set-field / --move-field` | 改**字段**:改标签 / 类型 / 分组 / 提示 / 必填策略,组内上下挪(key 不可改)。面板「编辑栏目」同源 |
|
|
155
173
|
| `nx-sk entry list \| get \| add \| update \| remove` | 条目 CRUD(PATCH 语义) |
|
|
156
174
|
| `nx-sk entry fields [--section job]` | 字段字典 —— 填之前先看这个,别猜字段名 |
|
|
175
|
+
| `nx-sk entry block add <ref> --type <段落\\|标题\\|图文\\|表格\\|清单\\|附件\\|密钥> [--data @x.json] [--after <块id>]` | 追加**块正文**(`entry.body`,可选键);详细页下半部分同源 |
|
|
176
|
+
| `nx-sk entry block update <ref> <块id> [--data @x.json]` | 改块(PATCH 语义);密钥块在打码态下写回会被拒(星号不能存成密钥) |
|
|
177
|
+
| `nx-sk entry block move <ref> <块id> --to <index>` | 移动块(拖拽落点 = 一次 move) |
|
|
178
|
+
| `nx-sk entry block remove \\| remove-many <ref> <块id…>` | 删块;批量时找不到的跳过并报告 |
|
|
179
|
+
| `nx-sk entry body <ref> [--mask]` | 读块正文(人读渲染;`--mask` 只作用于密钥块) |
|
|
180
|
+
| `nx-sk entry ai suggest <ref> --prompt "改短一点" --from @proposal.json [--block <块id>]` | 生成一条**AI 提议**:只落 pending,不写 store。`--from` 是 AI 给出的最终正文(nx-sk 不自带大模型) |
|
|
181
|
+
| `nx-sk entry ai list <ref>` | 看待审提议(新的在前)。pending 是运行态,不进 store、不进导出包 |
|
|
182
|
+
| `nx-sk entry ai apply <pendingId> [--block <块id>] [--force]` | 应用提议(**唯一会写 store 的一步**);块被改过 → `CONFLICT`,`--force` 才覆盖 |
|
|
183
|
+
| `nx-sk entry ai reject <pendingId>` | 拒绝提议:删掉 pending 文件,数据一个字不动 |
|
|
184
|
+
| `nx-sk section view list <id>` | 列视图配置;**没配过时给缺省推断**(表格/精简/看板,标 provisional,不落盘) |
|
|
185
|
+
| `nx-sk section view add <id> --type table\\|board\\|kv [--title 名] [--columns 姓名,状态] [--groupby 字段] [--sort 字段:desc]` | 新增视图(第一次 add 把当前生效的推断视图一起固化,chips 不会凭空消失) |
|
|
186
|
+
| `nx-sk section view update <id> <viewId> [--title] [--columns] [--sort] [--set col.字段.width=120]` | 改视图;列宽拖拽结束 = 一次 update |
|
|
187
|
+
| `nx-sk section view remove <id> <viewId>` | 删视图;删光回到缺省推断态(`defaultView` 一并清掉) |
|
|
188
|
+
| `nx-sk section view set-default <id> <viewId>` | 设缺省视图(写 `section.defaultView` —— 是数据,不是面板设置) |
|
|
157
189
|
| `nx-sk file list \| get \| add \| update \| remove` | 附件 CRUD(原件在 `~/nx-sk/files/`,同内容去重) |
|
|
158
190
|
| `nx-sk file add --path <文件> [--copy] [--category C]` | 导入附件:**默认移动原件**,`--copy` 仅复制 |
|
|
159
191
|
| `nx-sk file list [--section <栏目\|none>] [--q 关键字]` | 列附件:按「哪些栏目在引用」筛选(`none` = 未引用);返回栏目汇总与存储目录 |
|
|
@@ -293,6 +325,70 @@ nx-sk setting set --set 'navGroups=[]' # 清空 = 全部栏目恢复平铺
|
|
|
293
325
|
|
|
294
326
|
分组只是**显示配置**(存在 `settings.navGroups`):不动栏目与条目的数据,删掉栏目时头部自动略过。
|
|
295
327
|
|
|
328
|
+
### 表格字段(table):结构在**数据里**的表单表格
|
|
329
|
+
|
|
330
|
+
`entrylist`(结构清单)是「变长的几列文本」。**表格字段**再往前一步:每格有类型
|
|
331
|
+
(勾选 / 下拉 / 数字 / 日期),还能有**计算列**和**表尾统计**——但**列定义、行、公式、
|
|
332
|
+
统计配置全在条目数据里**,不在栏目字典里。所以「这条想多一列」不必改 schema,
|
|
333
|
+
也不会影响同一栏目下的其它条目。
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
# 建字段:只给类型 + **初始列**(新建条目时表格长什么样;初始列也可以不写)
|
|
337
|
+
nx-sk section update mysec --add-field '{"key":"tasks","label":"任务表","type":"table","group":"main","columns":[
|
|
338
|
+
{"key":"task","label":"任务"},
|
|
339
|
+
{"key":"done","label":"已办","type":"bool"},
|
|
340
|
+
{"key":"hours","label":"工时","type":"number","total":"sum"},
|
|
341
|
+
{"key":"rate","label":"单价","type":"number","total":"none"},
|
|
342
|
+
{"key":"cost","label":"费用","formula":"hours * rate","unit":"元"}]}'
|
|
343
|
+
|
|
344
|
+
# 写入:值是一份自描述文档(列 + 行)。计算列不用给值——给了也不落盘,读的时候现算
|
|
345
|
+
nx-sk entry update 周报 --data '{"任务表":{"columns":[…],"rows":[
|
|
346
|
+
{"task":"写文档","done":true,"hours":2,"rate":100},
|
|
347
|
+
{"task":"评审","done":false,"hours":3,"rate":100}]}}'
|
|
348
|
+
|
|
349
|
+
# 只看这张表:表头 + 数据 + 合计 + 公式报错(只读,现算)
|
|
350
|
+
nx-sk entry table 周报 --field 任务表
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
```
|
|
354
|
+
任务 已办 工时 单价 费用(算)
|
|
355
|
+
------ ---- ---- ---- --------
|
|
356
|
+
写文档 是 2 100 200 元
|
|
357
|
+
评审 否 3 100 300 元
|
|
358
|
+
合计 1/2 5 500 元
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
**公式就是 JS 表达式**(不发明语法),只包成 `return ( … )`,所以 `for` / `var` 这类语句写不进来:
|
|
362
|
+
|
|
363
|
+
| 想写什么 | 怎么写 |
|
|
364
|
+
| --- | --- |
|
|
365
|
+
| 同行计算 | `hours * rate` `工时 * 单价`(**列 key 与中文列名都能当变量**) |
|
|
366
|
+
| 取原值 / 整表 | `row.hours`(空格子是 null) `rows` / `表`(整张表) `i` 行号 `n` 行数 |
|
|
367
|
+
| 取一列 | `col("单价")` `sum(col("单价"))` |
|
|
368
|
+
| 聚合 | `sum / avg / min / max / count / countTrue / countFalse / distinct / median / first / last / join` |
|
|
369
|
+
| 数值 | `round / floor / ceil / abs / pct / ratio / clamp` 外加 `Math`、`Number`、`JSON`… |
|
|
370
|
+
| 判空 | `isBlank(row.hours)` `ifEmpty(x, 0)` `toNum(x)` |
|
|
371
|
+
|
|
372
|
+
- **计算列按声明顺序算**:只能引用排在它前面的列,天然不循环。算错会给出能照着改的话
|
|
373
|
+
(「公式里用了不存在的名字『qty』,可用的名字:a、b…」)。
|
|
374
|
+
- **空格子当 0 / false / ''**(`hours * rate` 不会因为空格子变 NaN);要判「到底填没填」用 `isBlank(row.x)`。
|
|
375
|
+
- **统计两层**:列上的 `total`(`sum|avg|min|max|count|countTrue|countFalse|distinct|median|none`,
|
|
376
|
+
不写就按类型默认:数字求和、勾选计是)决定表尾那一格;整表表达式写在数据的 `totals` 里
|
|
377
|
+
(`{"label":"完成率","expr":"pct(countTrue(col(\"done\")), n)","unit":"%"}`),`summary: false` 关掉表尾。
|
|
378
|
+
统计**不落盘**,每次读现算——不会出现「存下来的合计和现在的数据对不上」。
|
|
379
|
+
- 面板上直接**加行 / 加列**、改列类型与公式(「列设置」),改完就是这条数据的一部分。
|
|
380
|
+
敏感列(`sensitive: true`)与顶层敏感字段同一条边界:密文落盘、默认原文、`--mask` 打码。
|
|
381
|
+
- **写入即体检**:每条公式在保存前拿一行空值当探针跑一遍,只拦**与数据无关**的错
|
|
382
|
+
(语法错 / 列名解析不到 / 结果不是单值),除零这类「这条数据不巧」留到渲染时逐格报。
|
|
383
|
+
跑不起来就不保存 —— 定义阶段的错误停在定义阶段。
|
|
384
|
+
- **空与默认**:`--set 表=` / `[]` / `{}` 都能清空(有初始列时 `[]` 留下「列在、行空」的骨架);
|
|
385
|
+
列可以带 `default`(新增行时的初值,`0` / `false` 都算数);数字列默认求和、勾选列默认计是。
|
|
386
|
+
- 求值作用域用 `with` + Proxy 封死:`window` / `document` / `process` / `fetch` 都取不到。
|
|
387
|
+
这不是安全沙箱(公式是数据所有者自己写的),而是**把写错的边界前移**。
|
|
388
|
+
|
|
389
|
+
形状、列的每个键、公式内建表、错误对照表:`nx-sk skill get nx-sk 15-special-fields`
|
|
390
|
+
(同一篇也讲了 `entrylist` / `md` / `file` / `source` / `secret` 这几种「值不是标量」的字段)。
|
|
391
|
+
|
|
296
392
|
### 全局导出 / 导入(多栏目)
|
|
297
393
|
|
|
298
394
|
**项目里只有一个导出导入模块,没有独立的「备份」模块。** 导出的包就是唯一回退手段:
|
package/assets/nx-sk/SKILL.md
CHANGED
|
@@ -7,20 +7,25 @@ description: 本机个人资源管理器——栏目化存储个人信息、场
|
|
|
7
7
|
一句话:**把「你的信息」按栏目存起来,凭据就放在它该在的地方,CLI 与 Web 面板是同一套业务。**
|
|
8
8
|
|
|
9
9
|
数据落在 `~/nx-sk/`(可用环境变量 `NX_SK_HOME` / `NX_SK_STORE` 覆盖),**永远在仓库之外**。
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
21
|
-
|
|
10
|
+
首次运行**只播种一个「字段样例」栏目**(`demo`,连一条示例条目一起)——
|
|
11
|
+
把「能存什么、能算到哪」直接摆出来:标量字段(文本/数字/是否/下拉/日期/标签)、
|
|
12
|
+
组合字段(**结构清单** + **表格**:列在数据里、带计算列与表尾统计)、富内容(**图文** / **附件** / **密钥**),
|
|
13
|
+
外加每个栏目自带的「原始资料」袋。看完或改完可以整栏删掉。
|
|
14
|
+
|
|
15
|
+
**不再播种**求职 / 密钥 / 项目那一堆场景栏目——它们仍是模板,用时建:
|
|
16
|
+
|
|
17
|
+
| 模板 | id | 内容 |
|
|
18
|
+
| --------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
19
|
+
| 求职 | `job` | 求职用的个人信息档案(姓名/学历/联系方式/求职意向/简历头像成绩单附件…约 80 个字段) |
|
|
20
|
+
| 项目经历 | `projects` | 一个项目一个条目:名称 / 角色 / 时间 / 技术栈 / 职责与亮点 |
|
|
21
|
+
| 实习/工作经历 | `internships` | 一段经历一个条目:公司 / 岗位 / 时间 / 职责 |
|
|
22
|
+
| 校内职务/实践 | `campus` | 一条职务或实践一个条目 |
|
|
23
|
+
| 密钥 | `secret` | **一张 KV 表**(`kv: true`):一行一个键值对。**只放跨场景通用的 key**;播种不带它,第一次 `key set` 会自动补建 |
|
|
24
|
+
| 部署配置 | `deploy` | **一份配置文件一个条目**(Dockerfile / compose / k8s 清单):正文即文件原文 + 放哪 + 哪些值要替换 + **这个场景自己的凭据清单** + 何时用。详见 [[50-deploy]] |
|
|
25
|
+
|
|
26
|
+
**这些只是模板,不是固定清单**:栏目可以新建(`section add`,不给模板就是空栏目全自定义)、
|
|
22
27
|
可以加/删字段(`section update --add-field`,或直接 `entry update --set 任意键=值` 自动登记)、
|
|
23
|
-
也可以删掉整个栏目。内置模板共 **
|
|
28
|
+
也可以删掉整个栏目。内置模板共 **9 个**——除 `demo` 与上面 6 个外还有
|
|
24
29
|
`platform`(容器平台:控制台链接 / 账号 / 密码 / 镜像,一个平台一个条目)与
|
|
25
30
|
`thesis`(毕业论文规范字段化),`section templates` 列出它们;
|
|
26
31
|
模板在栏目实例化时被**深拷贝**,此后各自独立演化,
|
|
@@ -219,7 +224,8 @@ nx-sk file get f_bbb # 反查「被引用:求职
|
|
|
219
224
|
|
|
220
225
|
- **只认附件 id 与 http(s) 外链**:本地路径、`file://`、相对路径都渲染不出来(也会传不走)。
|
|
221
226
|
- 图片会**自动算作已引用**:`nx-sk file list` 里它们的 `usedBy` 指向引用它的栏目 / 条目 / 字段,
|
|
222
|
-
|
|
227
|
+
不会因为「只出现在正文里」被列进「未引用」。`file` 字段挂的与**资料袋里的**同理——
|
|
228
|
+
三种正式引用(file 字段 / md 正文 / source 袋)判同一套,cleanup 只删三种都没有的真孤儿。
|
|
223
229
|
- 面板里支持 Ctrl+V、拖拽、附件库插图;插入光标处即时预览。
|
|
224
230
|
- 可勾选待办:`- [ ] 步骤` 在预览里就是勾选框,点一下写回正文。
|
|
225
231
|
|
|
@@ -237,11 +243,31 @@ nx-sk entry update 张三 --data '{"账号清单":[{"链接":"https://…","密
|
|
|
237
243
|
|
|
238
244
|
面板渲染成密集迷你表(直接增删行);`entry get` 里清单一行一条、带列标签。口径见 [[10-sections-entries]]。
|
|
239
245
|
|
|
246
|
+
表格字段(`type: 'table'`)——**结构写在数据里**的表单表格:列有类型(勾选 / 下拉 / 数字 / 日期),
|
|
247
|
+
可带**计算列**(JS 表达式)与**表尾统计**。列、行、公式、统计配置全在条目值里
|
|
248
|
+
(`{v, columns, rows, totals?, summary?}`),字段定义里的 `columns` 只是「新建时的初始列」——
|
|
249
|
+
所以「这一条想多一列」不必改 schema,面板「列设置」里加就行。
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
# 建字段:只给类型(初始列可省,省了就在数据里定)
|
|
253
|
+
nx-sk section update <栏目> --add-field '{"key":"tasks","label":"任务表","type":"table"}'
|
|
254
|
+
# 写入:值 = 文档(列 + 行)。计算列不用给值(给了也不落盘,读时现算)
|
|
255
|
+
nx-sk entry update 周报 --data '{"任务表":{"columns":[{"key":"task","label":"任务"},{"key":"hours","label":"工时","type":"number"},{"key":"rate","label":"单价","type":"number"},{"key":"cost","label":"费用","formula":"hours*rate"}],"rows":[{"task":"写文档","hours":2,"rate":100}]}}'
|
|
256
|
+
# 看现值(表头 + 数据 + 合计 + 公式报错),只读
|
|
257
|
+
nx-sk entry table 周报 --field 任务表
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
写入即体检:公式的**语法 / 列名 / 是否单值**在保存前就校验,跑不起来不许存;
|
|
261
|
+
空值(`--set 表=`、`[]`、`{}`)与默认值都有明确语义。形状、公式作用域、统计口径、
|
|
262
|
+
错误对照表见 [[15-special-fields]]。
|
|
263
|
+
|
|
240
264
|
原始资料袋(`type: 'source'`)——**每个栏目都自带一个**的「乱入区」。值 = 一组资料条目
|
|
241
265
|
(`{id, kind, name, text|fileId|url, addedAt, note, mapped}`;kind = text / file / url)。
|
|
242
|
-
|
|
266
|
+
杂乱资料(邮件、聊天记录、截图、PDF 摘录)先**原样**丢进袋里,之后由 agent 或人
|
|
243
267
|
按栏目字段字典整理进上面的字段——「先乱入、后整理」因此成立:没有这个袋子,
|
|
244
268
|
用户只有两个坏选择:把乱数据硬塞进结构化字段(把结构搞脏),或干脆不存(信息丢了)。
|
|
269
|
+
**text 的底层是 markdown**:聊天记录图文混排,图片直接写进正文
|
|
270
|
+
(`` / 外链 ``),图和文不分家——形状见 [[15-special-fields]]。
|
|
245
271
|
|
|
246
272
|
```bash
|
|
247
273
|
nx-sk source list # 各栏目的袋概况
|
|
@@ -257,6 +283,29 @@ nx-sk source ensure # 给老栏目补上这个字段(模板
|
|
|
257
283
|
三条纪律:**原文不改写**、**不确定就留空**、**敏感内容不进袋**(袋是明文的;
|
|
258
284
|
密码走场景栏目的密文字段,不进袋)。
|
|
259
285
|
|
|
286
|
+
### 来源是文件:先挂原件,再写字段(溯源 SOP)
|
|
287
|
+
|
|
288
|
+
**「保存这个文件里的 xx 信息」——第一步不是抄内容,是把原件收进库、挂到条目上。**
|
|
289
|
+
信息会过时,但「这条字段值是从哪份原件来的」必须永远能反查回去——这是把 nx-sk
|
|
290
|
+
当可信源用的前提。顺序反了(先抄字段、原件随手一放),原件一被移动或删除,
|
|
291
|
+
字段就成了无源之水,错了都不知道该拿什么对。
|
|
292
|
+
|
|
293
|
+
| 情形 | 落点 | 动作 |
|
|
294
|
+
| --- | --- | --- |
|
|
295
|
+
| 该条目有贴切的 `file` 字段(简历 → `resumeFile`、部署清单 → `deployYaml`…) | `file` 字段 | `nx-sk file add --path <文件>` 拿 id → `entry update --set <字段>=<id>` |
|
|
296
|
+
| 只确定条目、字段不好区分 / 以后再整理 | `source` 袋 | `nx-sk source add <条目> --file <路径>` —— 复制进附件库、原样入袋,可信源的输入口本来就是干这个的 |
|
|
297
|
+
| 连条目都没定 | 先问,或建占位条目再入袋 | 别让原件只在对话里漂着——丢一次就真丢了 |
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
nx-sk source add 张三 --file "D:\扫描\成绩单.pdf" --name "教务处成绩单" # ① 原件进库、入袋
|
|
301
|
+
nx-sk entry update 张三 --set 成绩单=f_xxx # ② 提取信息写进字段(栏目有该字段时)
|
|
302
|
+
nx-sk source update 张三 --id s_xxx --mapped transcript # ③ 留痕:这条已整理到哪个字段
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
挂好的原件受三重保护:**cleanup 不会删**(袋里的文件算「已引用」)、**导出随包走**
|
|
306
|
+
(transfer 认袋里的引用)、`file get` 能反查「被哪个栏目/条目/字段引用」。
|
|
307
|
+
绕过这一步直接抄字段,这三重保护就都不存在。详细流程见 [[40-files]]。
|
|
308
|
+
|
|
260
309
|
**把袋子里的东西整理成字段**(agent 侧)有配套 skill:
|
|
261
310
|
|
|
262
311
|
```bash
|
|
@@ -298,6 +347,7 @@ nx-sk setting set --set 'navGroups=[]' # 清空 = 全部栏目恢复平铺
|
|
|
298
347
|
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
299
348
|
| `00-design` | 想搞懂**心智模型**时——栏目=结构、条目=数据、内置字段是什么、动态栏目 + 动态条目怎么用、四个聚合点在哪儿、密文边界,以及**东西该往哪儿放** |
|
|
300
349
|
| `10-sections-entries` | **动手填/改信息时必读**——栏目与条目的完整命令、AI 补全个人信息的推荐流程、字段字典怎么扩、读命令与写命令的参数陷阱 |
|
|
350
|
+
| `15-special-fields` | **值不是标量的字段怎么读怎么写**——`table`(结构在数据里 / 公式 / 统计 / 写入即体检 / 空与默认)、`entrylist`、`md`、`file`、`source`、`secret` 的形状、规矩与常见错对照表 |
|
|
301
351
|
| `20-secrets` | 密文机制、密钥从哪来(环境变量 vs 本机密钥文件)、KV 表的语义、什么时候会解不开 |
|
|
302
352
|
| `30-credentials` | **做凭据自动化时读**——凭据归属哪个栏目、多组账号怎么建清单、跨栏目台账、把凭据渲染成 compose / k8s / .env 的完整流程与安全边界 |
|
|
303
353
|
| `40-files` | **传/换简历头像成绩单等二进制原件时读**——附件库台账、导入(默认移动)与还原、`file` 字段怎么和条目建立链接、附件中心为什么由栏目驱动、看不到上传字段怎么办 |
|
|
@@ -309,6 +359,7 @@ nx-sk setting set --set 'navGroups=[]' # 清空 = 全部栏目恢复平铺
|
|
|
309
359
|
```bash
|
|
310
360
|
nx-sk skill get nx-sk # SKILL.md 全文
|
|
311
361
|
nx-sk skill get nx-sk 10-sections-entries # 裸名 → references/10-sections-entries.md
|
|
362
|
+
nx-sk skill get nx-sk 15-special-fields # 表格 / 清单 / 图文 / 附件:值不是标量的字段
|
|
312
363
|
nx-sk skill get nx-sk 30-credentials # 凭据自动化:归属 / 台账 / 渲染配置
|
|
313
364
|
nx-sk skill get nx-sk 40-files # 附件库:导入 / 链接 / 还原
|
|
314
365
|
nx-sk skill get nx-sk 50-deploy # 部署配置:存 / 找 / 复用
|
|
@@ -321,7 +372,8 @@ nx-sk skill get nx-sk --json # 四元 JSON:{skillName, ref,
|
|
|
321
372
|
|
|
322
373
|
- 用户只是随口问一句、不需要落盘 —— 别动数据。
|
|
323
374
|
- 用户只是**要读一份 PDF 的内容**(问"这文档讲了啥")—— 直接读就行,别建栏目、
|
|
324
|
-
|
|
375
|
+
别上传附件。先问一句要不要沉淀。但用户说「**保存**这份文件里的 xx」时是反例:
|
|
376
|
+
先挂原件再写字段(见「来源是文件」一节),不能只抄内容。
|
|
325
377
|
- 用户给的是**扫描件**(无文字层)—— 先 OCR,别对着图片猜正文(容易编造内容)。
|
|
326
378
|
- 想找「面板上的 skill 页」—— 没有:**skill 只走 CLI**(`nx-sk skill install` / `nx-sk skill get`),
|
|
327
379
|
面板里不呈现它。
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
模板再变也不会偷偷改你的栏目。模板后来新增的字段用 `nx-sk section sync <栏目>` 补进来
|
|
34
34
|
(**只增不改不删**;面板上是「栏目 → 编辑 → 同步模板字段」)。
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
首次运行只**播种 1 个「字段样例」栏目**(demo,连示例条目一起:每种字段一格、表格带公式与统计),
|
|
37
|
+
其余模板(job / projects / … / platform / thesis)需要时自己建。
|
|
38
38
|
|
|
39
39
|
## 三、动态栏目 + 动态条目:任何东西都能存
|
|
40
40
|
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
| --- | --- | --- |
|
|
63
63
|
| 标量字段 | 一个值 | 文本 / 数字 / 日期 / 是否 / 多值标签 |
|
|
64
64
|
| **结构清单** `entrylist` | 一个条目挂**多组**结构(多组账号、多条链接) | 行数组,列在字段定义里声明;密码列标 `sensitive` 即密文落盘 |
|
|
65
|
-
| **原始资料袋** `source` | 还没整理的杂乱资料(邮件 / 截图 /
|
|
65
|
+
| **原始资料袋** `source` | 还没整理的杂乱资料(邮件 / 截图 / 摘录);**字段值的溯源锚点** | 一袋资料条目,**先乱入、后整理**;袋里的文件算正式引用(cleanup 不删、导出随包走) |
|
|
66
66
|
| **附件** `file` | 二进制原件(简历 / 头像 / 证书) | 附件 id 列表,原件在 `~/nx-sk/files/` |
|
|
67
67
|
|
|
68
68
|
「先乱入、后整理」是刻意留的:真实数据几乎不是一次填对的,没有这个袋子,
|