dsh-retrace 0.3.0 → 0.4.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.md CHANGED
@@ -4,14 +4,15 @@
4
4
 
5
5
  **Retrace · 回溯** — Recall · Edit-and-resend · Regenerate, plus **in-conversation
6
6
  versioning**: a timeline of every rewind, artifact rollback, and a fork map of the
7
- paths your conversation explored. A Harness enhancement plugin for the
7
+ paths your conversation explored (roadmap). A Harness enhancement plugin for the
8
8
  [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) Web GUI and
9
9
  Desktop app (both share the same Web frontend).
10
10
 
11
11
  [![npm version](https://img.shields.io/npm/v/dsh-retrace)](https://www.npmjs.com/package/dsh-retrace)
12
- [![License: MIT](https://img.shields.io/npm/l/dsh-retrace)](https://github.com/azmavethy/dsh-retrace/blob/main/LICENSE)
12
+ [![npm downloads](https://img.shields.io/npm/dm/dsh-retrace)](https://www.npmjs.com/package/dsh-retrace)
13
+ [![License: MIT](https://img.shields.io/npm/l/dsh-retrace)](https://github.com/yamingmou/dsh-retrace/blob/main/LICENSE)
13
14
  [![DSH plugin](https://img.shields.io/badge/DSH-plugin-4A90D9)](https://github.com/topics/dsh-plugin)
14
- [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen)](https://github.com/azmavethy/dsh-retrace/pulls)
15
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen)](https://github.com/yamingmou/dsh-retrace/pulls)
15
16
 
16
17
  **English** · [简体中文](./README.zh.md)
17
18
 
@@ -33,11 +34,10 @@ of every rewind. On top of that trail, retrace records version boundaries, touch
33
34
  and (optionally) git state, and lets you roll back artifacts or jump back to any point
34
35
  in the conversation — all **inside the same session**, no session-switching.
35
36
 
36
- > 🚧 **Roadmap in progress** the **P0 version-data service is live** (version
37
- > boundaries, touched-file windows, content-addressed artifact snapshots,
38
- > `session/projection` push + HTTP query channels, config wiring). Timeline &
39
- > artifact rollback (P1) and the fork map (P2) are being built per [PLAN.md](./PLAN.md).
40
- > Recall / edit / regenerate are live today.
37
+ > **Timeline + artifact rollback are live (0.4.x)** recall / edit /
38
+ > regenerate, the version timeline, artifact rollback (git-first, snapshot
39
+ > fallback), jump-to-conversation and marker pre-write validation (three-layer
40
+ > contract guard) are all in. The fork map (P2) is in progress per [PLAN.md](./PLAN.md).
41
41
 
42
42
  ---
43
43
 
@@ -46,9 +46,16 @@ in the conversation — all **inside the same session**, no session-switching.
46
46
  | Action | Where | What happens |
47
47
  | --- | --- | --- |
48
48
  | **↩ 撤回** (recall) | hover any assistant reply, or the row under any user message | Removes the **whole exchange round** (the input **and** the agent's output, tool rows included) from both the model context and the conversation view; the input text is echoed into the composer so you can re-ask or re-edit immediately. A small transient notice marks the rewind and disappears once you keep typing. |
49
- | **✎ 编辑重发** (edit & re-send) | row under any user message | The old message and its reply are rewound and hidden. By default the conversation **starts fresh** (earlier messages are hidden too and excluded from context); the edited text is sent and the agent answers. A collapsed **"original input"** reference sits right under the new message — click to expand, configurable off. |
49
+ | **✎ 编辑重发** (edit & re-send) | row under any user message | The edited round is rewound and the new text is re-sent. By default **only the edited round** is replaced — earlier history stays visible; the optional "fresh conversation" setting rewinds the whole surface (earlier messages then leave the model context, and stay visible in the view as a marker notice by default). A collapsed **"original input"** reference sits right under the new message — click to expand, configurable off. |
50
50
  | **↻ 重新生成** (regenerate) | hover any assistant reply | The reply (and everything after it) is rewound and hidden, then the original prompt is re-sent so the agent answers again. |
51
51
 
52
+ **Versioning & rollback (live in 0.4.x)** — every rewind is also recorded as a **version**:
53
+
54
+ - 🕘 **Timeline** — a **Versions** tab in the conversation view (on par with the official 对话/轨迹 tabs, since 0.4.2): every version (type, time, message count, file-change badges, summary), pushed live via `session/projection` (no polling), windowed for long histories; event inspection reuses the official Trajectory ledger.
55
+ - ↩️ **Artifact rollback** — each version offers **context-only / artifacts-only / both** rollback with a dry-run preview; git-first (commit-free checkout of the listed paths) with content-addressed snapshot fallback. The rollback itself is recorded as a new version (`restore`) — rollback of a rollback.
56
+ - 🧭 **Jump-to-conversation** — one click from a version to that point in the conversation (auto-loads earlier history, anchor highlight).
57
+ - 🧹 **Bounded storage** — file snapshots keep the most recent N versions (default 50); a throttled background sweep prunes snapshots of truncated versions, keeping long sessions bounded.
58
+
52
59
  **Why it's different**
53
60
 
54
61
  - 🎯 **Whole-round recall** — one click removes the input *and* its output (including tool rows), not just a single bubble.
@@ -113,7 +120,7 @@ The same result with plain file edits and `pnpm` — exactly the steps
113
120
  ```json
114
121
  {
115
122
  "dependencies": {
116
- "dsh-retrace": "^0.2.0"
123
+ "dsh-retrace": "^0.4.0"
117
124
  },
118
125
  "dsh": {
119
126
  "profile": {
@@ -179,8 +186,12 @@ The dynamic host registers the same operations behind the package-private
179
186
 
180
187
  | Setting | Default | Description |
181
188
  | --- | --- | --- |
182
- | **编辑后显示原提问对照** | on | A collapsed "original input" reference under the re-sent message showing the **most recent** replaced text (reference only — never sent to the model). |
183
- | **编辑后从新对话开始** | on | After editing, hide earlier messages too so the conversation looks like a fresh start (the whole surface is rewound before re-sending). |
189
+ | **Show the original input after editing** | on | A collapsed "original input" reference under the re-sent message showing the **most recent** replaced text (reference only — never sent to the model). |
190
+ | **Start a fresh conversation after editing** | off | Hide earlier messages too, so the conversation looks like a fresh start (the whole surface is rewound before re-sending). Default off: only the edited round's context is replaced. |
191
+ | **Hide shadowed messages per marker** | on | On (default): recall/edit/regenerate hide the replaced round per their markers. Off: every message stays visible; markers only show the notice and reference (review the full history). A single marker that would hide more than 40% of the conversation degrades to notice-only (history never silently vanishes). |
192
+ | **Version & artifact snapshots** | on | On: every recall/edit records a version (messages and touched files) powering the timeline and artifact rollback. Off: only rewinds context — no version records, no artifact tracking (lightest). |
193
+ | **Git integration** | on | On: use git to record and roll back when the workspace is a repository (never auto-commits, never touches your branches); non-repo workspaces can enable git from the timeline. Off: built-in snapshots under `~/.dsh` only — the plugin never touches the workspace git state; features are equivalent. |
194
+ | **Version retention limit** | 50 | File snapshots are kept for the most recent N versions; older ones are pruned automatically (timeline records and the audit trail are always kept). |
184
195
 
185
196
  ---
186
197
 
@@ -188,14 +199,14 @@ The dynamic host registers the same operations behind the package-private
188
199
 
189
200
  ```
190
201
  durable transcript (append-only) model context & view
191
- ┌────────────────────────────────┐ ┌──────────────────┐
192
- ... target message │ … target message
193
- ↓ shadow span │ │ ↓ rewind
194
- [target … last surface node] │ ─────▶ │ (empty replace
195
- ↳ one replacement │ │ = context cut)
196
- assistant/message (empty)│ └──────────────────┘
197
- ↳ optional original-input │ agent.followup(new prompt)
198
- └────────────────────────────────┘ → next turn rebuilds request
202
+ ┌─────────────────────────────────┐ ┌────────────────────┐
203
+ target message │ … target message
204
+ ↓ shadow span │ │ ↓ rewind
205
+ [target … last surface node] │ ──▶│ (empty replace
206
+ ↳ one replacement │ │ = context cut)
207
+ assistant/message (empty)│ └────────────────────┘
208
+ ↳ optional original-input │ agent.followup(new prompt)
209
+ └─────────────────────────────────┘ → next turn rebuilds request
199
210
  ```
200
211
 
201
212
  1. **Host core** (`lib/host-core.js`, zero runtime imports) locates the target
@@ -215,7 +226,7 @@ The dynamic host registers the same operations behind the package-private
215
226
  sync), plus the optional original-input comparison block,
216
227
  - the `retrace` entry in the `conversation.chat.assistant-actions`
217
228
  strip (撤回 / 重新生成),
218
- - two preference toggles under Settings → General.
229
+ - preference toggles and the retention limit under Settings → General.
219
230
 
220
231
  > Two different layers are at play: the **durable transcript** (append-only; old
221
232
  > events are never rewritten or deleted) and the **model-visible surface** (rewound
@@ -247,11 +258,13 @@ The dynamic host registers the same operations behind the package-private
247
258
 
248
259
  Built per [PLAN.md](./PLAN.md):
249
260
 
250
- - **P1 — Timeline & artifact rollback**: an in-session version timeline (messages,
251
- thinking, touched files), artifact snapshots (git-first, snapshot-fallback, opt-in),
252
- rollback with dry-run preview, and jump-to-conversation navigation.
253
- - **P2 — Fork map**: a flow graph of the conversation's turns with fork points at every
254
- rewind, thinking flow per turn, branch-intent cards, and version comparison.
261
+ - **P1 — Timeline & artifact rollback** ✅ *shipped in 0.4.x*: an in-session version
262
+ timeline (messages, thinking, touched files), artifact snapshots (git-first,
263
+ snapshot-fallback, opt-in), rollback with dry-run preview, and jump-to-conversation
264
+ navigation.
265
+ - **P2 — Fork map** 🔨 *in progress*: a flow graph of the conversation's turns with fork
266
+ points at every rewind, thinking flow per turn, branch-intent cards, and version
267
+ comparison.
255
268
  - More locales beyond 简体中文 / English.
256
269
 
257
270
  ---
@@ -292,7 +305,7 @@ npm pack --dry-run # verify the published file list
292
305
  > `__setMessageEditorWire`.
293
306
 
294
307
  PRs and issues are welcome — see [CONTRIBUTING](./CONTRIBUTING.md) (coming soon)
295
- and the [issue tracker](https://github.com/azmavethy/dsh-retrace/issues).
308
+ and the [issue tracker](https://github.com/yamingmou/dsh-retrace/issues).
296
309
 
297
310
  ---
298
311
 
package/README.zh.md CHANGED
@@ -2,15 +2,16 @@
2
2
 
3
3
  # 🧭 dsh-retrace
4
4
 
5
- **Retrace · 回溯** —— 在 **撤回 · 编辑重发 · 重新生成** 之上,更进一步:
5
+ **Retrace · 回溯** —— 在 **撤回 · 编辑重发 · 重新生成** 之上,更进一步:
6
6
  为 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 对话提供
7
- **单会话内的版本化**——每一次回退的时间线、产物回退、以及对话走过的分叉路径图。
8
- 同时支持 **Web 端** 与 **桌面客户端**(两者共用同一套 Web 前端)。
7
+ **单会话内的版本化**——每一次回退的时间线、产物回退,以及对话走过的分叉路径图(路线图)。
8
+ 同时支持 **Web 端** 与 **桌面客户端**(两者共用同一套 Web 前端)。
9
9
 
10
10
  [![npm version](https://img.shields.io/npm/v/dsh-retrace)](https://www.npmjs.com/package/dsh-retrace)
11
- [![License: MIT](https://img.shields.io/npm/l/dsh-retrace)](https://github.com/azmavethy/dsh-retrace/blob/main/LICENSE)
11
+ [![npm downloads](https://img.shields.io/npm/dm/dsh-retrace)](https://www.npmjs.com/package/dsh-retrace)
12
+ [![License: MIT](https://img.shields.io/npm/l/dsh-retrace)](https://github.com/yamingmou/dsh-retrace/blob/main/LICENSE)
12
13
  [![DSH plugin](https://img.shields.io/badge/DSH-plugin-4A90D9)](https://github.com/topics/dsh-plugin)
13
- [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen)](https://github.com/azmavethy/dsh-retrace/pulls)
14
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen)](https://github.com/yamingmou/dsh-retrace/pulls)
14
15
 
15
16
  **简体中文** · [English](./README.md)
16
17
 
@@ -18,18 +19,17 @@
18
19
 
19
20
  DeepSeek Harness 的对话是「只追加(append-only)」的事件日志,本身没有撤销能力。
20
21
  `dsh-retrace` 先为对话补上聊天本该有的三个操作 —— **撤回**、**编辑重发**、
21
- **重新生成**;再往前一步:撤回只回退了**上下文**,而智能体已经改过的**产物文件**
22
+ **重新生成**;再往前一步:撤回只回退了**上下文**,而智能体已经改过的**产物文件**
22
23
  不会自动还原——retrace 把对话**和它的产物**放在一起做版本化。
23
24
 
24
- 撤回/编辑后,目标消息会**从对话视图和模型上下文中移除**——你看到的"删除"正是这个
25
+ 撤回/编辑后,目标消息会**从对话视图和模型上下文中移除**——你看到的「删除」正是这个
25
26
  效果。但底层的**持久化日志不会被改写或删除**:它始终保持只追加,旧事件原样保留,
26
27
  插件只是在日志末尾追加一条合法的替换事件(与内置压缩使用的 `replace` 原语一致)来
27
28
  回退对话表面,因此日志保留每一次回退的完整审计痕迹。在这条痕迹之上,retrace 记录
28
29
  版本边界、触碰文件与(可选的)git 状态,支持产物回退与跳转到对话任意位置——全部
29
30
  发生在**同一会话内**,不换会话。
30
31
 
31
- > 🚧 **路线图进行中** —— 时间线与产物回退(P1)、分叉图(P2)正在按
32
- > [PLAN.md](./PLAN.md) 开发;撤回/编辑/重新生成当前已可用。
32
+ > **时间线 + 产物回退已上线(0.4.x)** —— 撤回/编辑/重新生成、版本时间线、产物回退(git 优先 + 快照兜底)、跳转对话、marker 写前校验均已可用;分叉图(P2)按 [PLAN.md](./PLAN.md) 推进中。
33
33
 
34
34
  ---
35
35
 
@@ -38,9 +38,16 @@ DeepSeek Harness 的对话是「只追加(append-only)」的事件日志,
38
38
  | 操作 | 入口 | 效果 |
39
39
  | --- | --- | --- |
40
40
  | **↩ 撤回** | 悬停任意助手回复;或用户消息下方的操作行 | **移除整轮对话**(该条输入及其对应的输出、工具行一并消失),从模型上下文与对话视图中同步清除,并把输入原文**回显到输入框**方便立即修改后重发;一条短暂提示标记回退点,你继续输入后自动消失。 |
41
- | **✎ 编辑重发** | 用户消息下方的操作行 | 回退并隐藏旧消息及其回复。默认**从新对话开始**(此前的消息一并隐藏、不再进入上下文),发送修改后的文本让智能体作答;新消息下方有一个折叠的「原提问」对照,点击展开、可配置关闭。 |
41
+ | **✎ 编辑重发** | 用户消息下方的操作行 | 回退该条输入及其回复并重发修改后的文本。默认**只替换被编辑那一轮**(更早的历史保持可见);可在设置中开启「从新对话开始」让对话从新消息重新开始(此时此前的消息不再进入上下文,视图中也默认保持可见、仅显示标记提示)。新消息下方有一个折叠的「原提问」对照,点击展开、可配置关闭。 |
42
42
  | **↻ 重新生成** | 悬停任意助手回复 | 回退并隐藏该回复及其后内容,重新发送原提问,让智能体重新作答。 |
43
43
 
44
+ **版本化与回退(0.4.x 已上线)** —— 每次回退都会被记录为一个**版本**:
45
+
46
+ - 🕘 **时间线** —— 会话视图新增「版本」Tab(与官方「对话/轨迹」平级,0.4.2 起):展示每个版本(类型/时间/消息数/文件变更徽标/摘要),经 `session/projection` 推送帧实时更新(零轮询),大列表窗口化渲染;事件原文查看复用官方「轨迹」台账。
47
+ - ↩️ **产物回退** —— 每个版本支持 仅对话 / 仅产物 / 两者 三种回退范围,先干跑预览再执行;git 优先(commit-free checkout 清单路径)+ 内容寻址快照兜底。回退本身记录为新版本(`restore`),可以再回退。
48
+ - 🧭 **跳转对话** —— 从时间线一键跳转到对话对应位置(自动翻页加载更早历史 + 锚点高亮)。
49
+ - 🧹 **存储有界** —— 文件快照只保留最近 N 个版本(默认 50);节流后台扫掠回收被截断版本的快照,长会话不膨胀。
50
+
44
51
  **为什么与众不同**
45
52
 
46
53
  - 🎯 **整轮撤回** —— 一键移除输入 *和* 它的输出(含工具行),而不只是单条气泡。
@@ -100,7 +107,7 @@ dsh plugin --profile <name> add dsh-retrace
100
107
  ```json
101
108
  {
102
109
  "dependencies": {
103
- "dsh-retrace": "^0.2.0"
110
+ "dsh-retrace": "^0.4.0"
104
111
  },
105
112
  "dsh": {
106
113
  "profile": {
@@ -162,22 +169,26 @@ Client 半区会依据包内 `dsh.client` 元数据被自动打包进 Web 客户
162
169
  | 设置项 | 默认 | 说明 |
163
170
  | --- | --- | --- |
164
171
  | **编辑后显示原提问对照** | 开 | 重发消息下方的折叠「原输入」引用,显示**最近一次**被替换的原文(仅作对照,不会进入模型上下文)。 |
165
- | **编辑后从新对话开始** | | 编辑后连此前的消息也一并隐藏,让对话看起来像从新消息重新开始(重发前回退整个表面)。 |
172
+ | **编辑后从新对话开始** | | 编辑后连此前的消息也一并隐藏,让对话看起来像从新消息重新开始(重发前回退整个表面)。默认关:只替换被编辑那一轮的上下文。 |
173
+ | **按标记隐藏被编辑/撤回的消息** | 开 | 开(默认):撤回/编辑/重新生成按标记隐藏被替换的那一轮消息。关:所有消息保持可见,标记仅显示提示与对照(查看完整历史用)。单个 marker 要隐藏超过 40% 的对话时自动降级为不隐藏(历史永不静默消失)。 |
174
+ | **版本与产物快照** | 开 | 开:每次撤回/编辑记录一个版本(消息与触碰文件),提供时间线与产物回退;关:仅回退上下文,不记录版本、不追踪产物(最省资源)。 |
175
+ | **启用 git 集成** | 开 | 开:工作区是 git 仓库时用 git 记录与回退(不自动提交、不动你的分支),非仓库可在时间线里一键启用;关:一律用内置快照(存于 `~/.dsh`),不触碰工作区 git 状态,功能等价。 |
176
+ | **版本保留上限** | 50 | 文件快照只保留最近 N 个版本,超出自动清理最旧的;时间线记录与审计痕迹始终保留。 |
166
177
 
167
178
  ---
168
179
 
169
180
  ## 🧠 工作原理
170
181
 
171
182
  ```
172
- 持久化日志(只追加) 模型上下文与视图
173
- ┌────────────────────────────────┐ ┌──────────────────┐
174
- ... 目标消息 │ │ … 目标消息
175
- ↓ 阴影区间 │ ↓ 回退
176
- [目标 … 最后一个表面节点] ───▶│ (空 replace
177
- ↳ 追加一条替换型 │ = 上下文截断)
178
- assistant/message(空) └──────────────────┘
179
- ↳ 可选「原提问」对照 agent.followup(新提示)
180
- └────────────────────────────────┘ → 下一轮基于回退后的历史重建请求
183
+ 持久化日志(只追加) 模型上下文与视图
184
+ ┌────────────────────────────────┐ ┌────────────────────┐
185
+ 目标消息 │ │ … 目标消息
186
+ ↓ 阴影区间 │ ↓ 回退
187
+ [目标 … 最后一个表面节点] ──▶ (空 replace
188
+ ↳ 追加一条替换型 │ = 上下文截断)
189
+ assistant/message(空) agent.followup(新提示)
190
+ ↳ 可选「原提问」对照 → 下一轮基于回退后的历史重建请求
191
+ └────────────────────────────────┘ └────────────────────┘
181
192
  ```
182
193
 
183
194
  1. **Host 核心**(`lib/host-core.js`,零运行时依赖):在会话的活跃表面中定位目标
@@ -193,7 +204,7 @@ Client 半区会依据包内 `dsh.client` 元数据被自动打包进 Web 客户
193
204
  隐藏(视图与模型上下文保持同步),并可显示「原提问」对照块,
194
205
  - `conversation.chat.assistant-actions` 中的 `retrace` 入口
195
206
  (撤回/重新生成),
196
- - 设置 → 通用 中的两个偏好开关。
207
+ - 设置 → 通用 中的偏好开关与版本保留上限。
197
208
 
198
209
  > 这里有两个不同层面:**持久化日志**(只追加;旧事件从不被改写或删除)与
199
210
  > **模型可见表面**(由追加的替换事件回退)。因此旧事件作为审计痕迹留在记录中——
@@ -216,12 +227,10 @@ Client 半区会依据包内 `dsh.client` 元数据被自动打包进 Web 客户
216
227
 
217
228
  ## 🗺️ 路线图
218
229
 
219
- 按 [PLAN.md](./PLAN.md) 推进:
230
+ 按 [PLAN.md](./PLAN.md) 推进:
220
231
 
221
- - **P1 — 时间线与产物回退**:单会话内的版本时间线(消息、思考、触碰文件),产物快照
222
- (git 优先 + 快照兜底,可开关),带干跑预览的回退,以及跳转到对话位置。
223
- - **P2 — 分叉图**:对话回合的流程分叉图,每次回退都是分叉点,逐回合思考流,
224
- 分支意图卡,版本对比。
232
+ - **P1 — 时间线与产物回退** ✅ 已上线(0.4.x):单会话内的版本时间线(版本/消息/思考/工具节点),产物快照(git 优先 + 快照兜底,可开关),带干跑预览的回退,以及跳转到对话位置;marker 写前校验(三层契约)守护日志。
233
+ - **P2 分叉图** 🔨 推进中:对话回合的流程分叉图,每次回退都是分叉点,逐回合思考流,分支意图卡、版本对比。
225
234
  - 支持更多语言(当前:简体中文 / English)。
226
235
 
227
236
  ---
@@ -261,7 +270,7 @@ npm pack --dry-run # 校验发布文件清单
261
270
  > (`host.call` vs HTTP 路由)。
262
271
 
263
272
  欢迎提交 PR 与 issue —— 见 [CONTRIBUTING](./CONTRIBUTING.md)(筹备中)与
264
- [问题追踪](https://github.com/azmavethy/dsh-retrace/issues)。
273
+ [问题追踪](https://github.com/yamingmou/dsh-retrace/issues)。
265
274
 
266
275
  ---
267
276
 
@@ -41,6 +41,14 @@ const globalConfigSchema = z.object({
41
41
  gitEnabled: z.boolean(),
42
42
  })
43
43
 
44
+ /** One version's git facts, recorded at the boundary (P1 GitAdapter). */
45
+ const versionGitRecordSchema = z.object({
46
+ /** HEAD at the version boundary (null = not a repository then). */
47
+ headHash: z.string().nullable(),
48
+ /** Working tree dirty at the boundary. */
49
+ dirty: z.boolean(),
50
+ })
51
+
44
52
  /**
45
53
  * The `retrace` domain spec — open via `ctx.storageDomain.open(retraceDomainSpec)`.
46
54
  * The web composition's `storage-json` backend lands it at
@@ -53,6 +61,7 @@ export const retraceDomainSpec = defineDomain({
53
61
  // UNIT_NAME_RE is lowercase-only; `refcounts` is the official-safe spelling
54
62
  // of the plan's `refCounts` table.
55
63
  refcounts: domainTable(refCountRecordSchema),
64
+ versiongit: domainTable(versionGitRecordSchema),
56
65
  },
57
66
  global: {
58
67
  schema: globalConfigSchema,