@ch4acko3/dsh-turn-fold 0.6.2 → 0.6.4

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
@@ -34,10 +34,17 @@ short open/close transition that unmounts the activity after it closes.
34
34
 
35
35
  ## How it works
36
36
 
37
+ On DSH versions with native message folding, Turn Fold takes over: it removes
38
+ the native process disclosure and disables native node folding, leaving the
39
+ plugin's turn summary and activity groups in control. Support is detected from
40
+ the chat renderer's `compactTranscript` or `usePresentation` prop rather than the CLI version.
41
+ DSH still renders reasoning, tools, and context. Saved native display preferences
42
+ are unchanged, so disabling the plugin restores native folding.
43
+
37
44
  Three shape-guarded Source Patches run in memory against the compiled browser
38
45
  bundle. For DSH `0.1.0-rc.8` through `0.1.1-rc.2`, they target
39
46
  `@deepseek-ai/dsh-client-ui-conversation`; for DSH `0.1.2-alpha.5` through the
40
- `0.1.6` line (including prereleases), they follow the renderer into `@deepseek-ai/dsh-client-ui-chat`.
47
+ `0.1.7` line (including prereleases), they follow the renderer into `@deepseek-ai/dsh-client-ui-chat`.
41
48
  Installed DSH files are never modified. Every selector must still match exactly
42
49
  once, so an incompatible compiled shape fails closed instead of modifying an
43
50
  uncertain target.
@@ -90,4 +97,6 @@ npm version patch
90
97
  git push --follow-tags
91
98
  ```
92
99
 
93
- Compatibility checks cover the real `0.1.5-rc.2` and `0.1.6-alpha.2` bundles. Run `npm test` with `DSH_TURN_FOLD_UPSTREAM_ROOT` pointing to an isolated DSH installation to exercise that chat bundle. Exact selector counts remain required.
100
+ Compatibility checks cover the real `0.1.5-rc.2`, `0.1.6-alpha.2`, and `0.1.7-rc.2` bundles. Run `npm test` with `DSH_TURN_FOLD_UPSTREAM_ROOT` pointing to an isolated DSH installation to exercise that chat bundle. Exact selector counts remain required.
101
+
102
+ DSH `0.2.0-rc.2` is also supported explicitly. Its runtime uses `configForms`, a Plugins settings tab, live configuration fields, and the renamed native icons. Turn Fold reads the timeline through the native chat hook when the renderer has no local timeline binding, and accepts the native duration formatter's numeric/unit segments. Windows browser checks cover combined startup with Bites, editing metrics, persistence across a Host restart, and replaying a synthetic two-turn session written through native session persistence. Seeking back hides later turns, playback disables input, and exiting restores input. This does not cover real model calls or browser interactions on macOS/Linux. The `0.2` range is limited to this tested release.
package/README.zh-CN.md CHANGED
@@ -16,7 +16,9 @@ https://github.com/user-attachments/assets/3c9dfdcf-a454-4750-9edf-76771ed5a9a6
16
16
 
17
17
  ## 工作原理
18
18
 
19
- 三个带形状校验的 Source Patch 会在内存中修改编译后的浏览器包:DSH `0.1.0-rc.8` 至 `0.1.1-rc.2` 使用 `@deepseek-ai/dsh-client-ui-conversation`,DSH `0.1.2-alpha.5` 至 `0.1.6` 版本线(含预发布版)则跟随渲染器迁移到 `@deepseek-ai/dsh-client-ui-chat`。它们不会修改已安装的 DSH 文件。每条选择器仍必须恰好命中一次,因此遇到不兼容的编译形状时会停止应用,而不会修改不确定的目标。
19
+ 在带原生消息折叠的新版 DSH 中,Turn Fold 会接管折叠:移除原生执行过程折叠栏,关闭节点内部的原生折叠,只保留插件的回合摘要和活动分组。按聊天渲染器是否提供 `compactTranscript` 或 `usePresentation` 判断能力,不依赖 CLI 版本号。原生思考、工具和上下文内容仍由 DSH 渲染,已保存的原生显示偏好不变;停用插件后恢复原生折叠。
20
+
21
+ 三个带形状校验的 Source Patch 会在内存中修改编译后的浏览器包:DSH `0.1.0-rc.8` 至 `0.1.1-rc.2` 使用 `@deepseek-ai/dsh-client-ui-conversation`,DSH `0.1.2-alpha.5` 至 `0.1.7` 版本线(含预发布版)则跟随渲染器迁移到 `@deepseek-ai/dsh-client-ui-chat`。它们不会修改已安装的 DSH 文件。每条选择器仍必须恰好命中一次,因此遇到不兼容的编译形状时会停止应用,而不会修改不确定的目标。
20
22
 
21
23
  | Patch | 选择器(预期命中 1 次) | 作用 |
22
24
  | --- | --- | --- |
@@ -61,4 +63,6 @@ npm version patch
61
63
  git push --follow-tags
62
64
  ```
63
65
 
64
- 已使用真实 `0.1.5-rc.2` 和 `0.1.6-alpha.2` 包验证。设置 `DSH_TURN_FOLD_UPSTREAM_ROOT` 指向隔离的 DSH 安装后运行 `npm test`,可对该版本的聊天包执行测试。选择器仍要求精确命中。
66
+ 已使用真实 `0.1.5-rc.2`、`0.1.6-alpha.2` 和 `0.1.7-rc.2` 包验证。设置 `DSH_TURN_FOLD_UPSTREAM_ROOT` 指向隔离的 DSH 安装后运行 `npm test`,可对该版本的聊天包执行测试。选择器仍要求精确命中。
67
+
68
+ 另明确支持 DSH `0.2.0-rc.2`:该版本使用 `configForms`、插件设置标签页、可实时修改的配置字段及新版原生图标。渲染器没有局部时间线变量时,Turn Fold 通过原生聊天 hook 读取时间线,并适配原生时长格式化函数返回的数字与单位分段。Windows 浏览器检查覆盖与 Bites 组合启动、编辑摘要指标、Host 重启后设置持久化,以及通过原生会话持久化写入的两轮合成历史回放:回退时隐藏后续轮次,回放期间禁用输入,退出后恢复输入。尚未覆盖真实模型调用或 macOS/Linux 浏览器交互。`0.2` 的兼容范围仅包含这个已验证版本。
package/index.cjs CHANGED
@@ -1,12 +1,18 @@
1
1
  'use strict'
2
2
 
3
3
  // Host entry for the @ch4acko3/dsh-turn-fold Harmony provider.
4
- const { Config, SETTINGS_NAMESPACE, createSettingsSchema } = require('./settings.cjs')
4
+ const { SETTINGS_NAMESPACE, createConfigSchema, createSettingsSchema } = require('./settings.cjs')
5
5
 
6
- exports.Config = Config
6
+ // Resolve the schema after the Host has finished importing its ESM graph.
7
+ Object.defineProperty(exports, 'Config', { enumerable: true, get: createConfigSchema })
7
8
  exports.inject = ['harmony']
8
9
  exports.apply = (ctx, config) => {
9
10
  ctx.inject(['settings'], (settingsCtx) => {
10
- settingsCtx.settings.register(SETTINGS_NAMESPACE, createSettingsSchema(), { base: config })
11
+ if (typeof settingsCtx.settings.configure === 'function') {
12
+ settingsCtx.effect(() => settingsCtx.settings.configure({ auto: false }, ctx.fiber))
13
+ } else {
14
+ const summaryFields = typeof config.summaryFields.get === 'function' ? config.summaryFields.get() : config.summaryFields
15
+ settingsCtx.settings.register(SETTINGS_NAMESPACE, createSettingsSchema(), { base: { ...config, summaryFields } })
16
+ }
11
17
  })
12
18
  }
package/index.mjs ADDED
@@ -0,0 +1,8 @@
1
+ // Let Node settle the schema's ESM dependencies before the CommonJS helper
2
+ // constructs the live Config schema.
3
+ import '@deepseek-ai/schemastery'
4
+ import provider from './index.cjs'
5
+
6
+ export const Config = provider.Config
7
+ export const inject = provider.inject
8
+ export const apply = provider.apply
package/inline-source.cjs CHANGED
@@ -138,7 +138,10 @@ function __ch4acko3DshTurnFoldPublishSettings(fields) {
138
138
  function __ch4acko3DshTurnFoldInstall(ctx) {
139
139
  ctx.effect(function () { return ctx.locale.register(__ch4acko3DshTurnFoldLocaleNamespace, __ch4acko3DshTurnFoldDictionaries); }, "@ch4acko3/dsh-turn-fold: dictionaries");
140
140
  __ch4acko3DshTurnFoldTranslate = ctx.locale.bind(__ch4acko3DshTurnFoldLocaleNamespace);
141
- var scope = ctx.settingsScope.bind({ namespace: __ch4acko3DshTurnFoldSettingsNamespace, decode: __ch4acko3DshTurnFoldDecodeSettings });
141
+ var modern = typeof ctx.configForms !== "undefined";
142
+ var scope = modern
143
+ ? ctx.configForms.get("ch4acko3-dsh-turn-fold")
144
+ : ctx.settingsScope.bind({ namespace: __ch4acko3DshTurnFoldSettingsNamespace, decode: __ch4acko3DshTurnFoldDecodeSettings });
142
145
  __ch4acko3DshTurnFoldSettingsScope = scope;
143
146
  function publish() {
144
147
  var snapshot = scope.getSnapshot();
@@ -146,10 +149,11 @@ function __ch4acko3DshTurnFoldInstall(ctx) {
146
149
  }
147
150
  ctx.effect(function () { return scope.subscribe(publish); }, "@ch4acko3/dsh-turn-fold: settings");
148
151
  publish();
149
- ctx.slots.inject("settings.plugin.item", function () {
152
+ var slot = modern ? "settings.plugins.tab" : "settings.plugin.item";
153
+ ctx.slots.inject(slot, function () {
150
154
  return ctx.slots.register({
151
- name: "settings.plugin.item",
152
- key: __ch4acko3DshTurnFoldSettingsNamespace
155
+ name: slot,
156
+ ...(modern ? { id: __ch4acko3DshTurnFoldSettingsNamespace, label: function () { return __ch4acko3DshTurnFoldText("settings.title"); } } : { key: __ch4acko3DshTurnFoldSettingsNamespace })
153
157
  }, __ch4acko3DshTurnFoldSettingsCard);
154
158
  });
155
159
  }
@@ -468,8 +472,9 @@ function __ch4acko3DshTurnFoldSettingsCard() {
468
472
  if (next.length === fields.length && next.every(function (field, index) { return field === fields[index]; })) return;
469
473
  setPending(true);
470
474
  setFailed(false);
471
- scope.set("summaryFields", next).then(function () {
475
+ scope.set("summaryFields", next).then(function (accepted) {
472
476
  setPending(false);
477
+ if (accepted === false) setFailed(true);
473
478
  }, function () {
474
479
  setPending(false);
475
480
  setFailed(true);
@@ -714,6 +719,12 @@ function __ch4acko3DshTurnFoldLiveDuration(metrics, running) {
714
719
  return metrics.durationMs;
715
720
  }
716
721
  function __ch4acko3DshTurnFoldSpacedDuration(value) {
722
+ // rc.2 exposes numeric/unit segments; earlier hosts return one string.
723
+ if (Array.isArray(value)) value = value.map(function (part) {
724
+ if (part === null || typeof part !== "object" || typeof part.text !== "string") throw new Error("@ch4acko3/dsh-turn-fold: unsupported native duration segment");
725
+ return part.text;
726
+ }).join("");
727
+ if (typeof value !== "string") throw new Error("@ch4acko3/dsh-turn-fold: unsupported native duration format");
717
728
  return value.replace(/(\d)(?=(?:小时|分钟|秒|分|时))/g, "$1 ").replace(/(小时|分钟|秒|分|时)(?=\d)/g, "$1 ");
718
729
  }
719
730
  function __ch4acko3DshTurnFoldAnimatedPart(field, key, parameter, display, animationKey, qualifier) {
@@ -761,7 +772,7 @@ function __ch4acko3DshTurnFoldSummaryParts(metrics, running, settled, completed,
761
772
  } else if (field === "tokensPerSecond") {
762
773
  if (typeof value === "number") parts.push({ field: field, text: __ch4acko3DshTurnFoldText("summary.tokensPerSecond", { count: value >= 10 ? Math.round(value) : Math.round(value * 10) / 10 }) });
763
774
  } else if (typeof value === "number") {
764
- parts.push(__ch4acko3DshTurnFoldCountPart(field, "summary." + field, value, formatTokens(value), metrics.tokenUsagePartial && settled ? "≥ " : ""));
775
+ parts.push(__ch4acko3DshTurnFoldCountPart(field, "summary." + field, value, formatTokens(value, durationT), metrics.tokenUsagePartial && settled ? "≥ " : ""));
765
776
  }
766
777
  }
767
778
  return parts.length === 0 ? [{ field: "activity", text: __ch4acko3DshTurnFoldText("summary.activity") }] : parts;
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@ch4acko3/dsh-turn-fold",
3
- "version": "0.6.2",
3
+ "version": "0.6.4",
4
4
  "description": "Codex-style turn folding for the DSH WebUI conversation, implemented as a dsh-harmony provider.",
5
- "main": "./index.cjs",
5
+ "main": "./index.mjs",
6
6
  "engines": {
7
7
  "node": "^22.22.3 || >=24.11.1"
8
8
  },
@@ -11,6 +11,7 @@
11
11
  "README.zh-CN.md",
12
12
  "harmony.patch.yml",
13
13
  "index.cjs",
14
+ "index.mjs",
14
15
  "inline-source.cjs",
15
16
  "locales.cjs",
16
17
  "locales/*.json",
@@ -52,12 +53,12 @@
52
53
  "check": "node test/run.cjs"
53
54
  },
54
55
  "dependencies": {
55
- "@deepseek-ai/schemastery": "^3.18.1"
56
+ "@deepseek-ai/schemastery": "^3.18.4"
56
57
  },
57
58
  "peerDependencies": {
58
- "@deepseek-ai/dsh-client-ui-chat": ">=0.1.2-alpha.5 <0.1.3-0 || >=0.1.3-0 <0.1.4-0 || >=0.1.4-0 <0.1.5-0 || >=0.1.5-0 <0.1.6-0 || >=0.1.6-0 <0.1.7-0",
59
- "@deepseek-ai/dsh-client-ui-conversation": ">=0.1.0-rc.8 <=0.1.1-rc.2 || >=0.1.2-alpha.5 <0.1.3-0 || >=0.1.3-0 <0.1.4-0 || >=0.1.4-0 <0.1.5-0 || >=0.1.5-0 <0.1.6-0 || >=0.1.6-0 <0.1.7-0",
60
- "@deepseek-ai/dsh-settings": ">=0.1.0-rc.8 <=0.1.1-rc.2 || >=0.1.2-alpha.5 <0.1.3-0 || >=0.1.3-0 <0.1.4-0 || >=0.1.4-0 <0.1.5-0 || >=0.1.5-0 <0.1.6-0 || >=0.1.6-0 <0.1.7-0",
59
+ "@deepseek-ai/dsh-client-ui-chat": ">=0.1.2-alpha.5 <0.1.3-0 || >=0.1.3-0 <0.1.4-0 || >=0.1.4-0 <0.1.5-0 || >=0.1.5-0 <0.1.6-0 || >=0.1.6-0 <0.1.7-0 || >=0.1.7-0 <0.1.8-0 || 0.2.0-rc.2 || 0.2.1-alpha.2",
60
+ "@deepseek-ai/dsh-client-ui-conversation": ">=0.1.0-rc.8 <=0.1.1-rc.2 || >=0.1.2-alpha.5 <0.1.3-0 || >=0.1.3-0 <0.1.4-0 || >=0.1.4-0 <0.1.5-0 || >=0.1.5-0 <0.1.6-0 || >=0.1.6-0 <0.1.7-0 || >=0.1.7-0 <0.1.8-0 || 0.2.0-rc.2 || 0.2.1-alpha.2",
61
+ "@deepseek-ai/dsh-settings": ">=0.1.0-rc.8 <=0.1.1-rc.2 || >=0.1.2-alpha.5 <0.1.3-0 || >=0.1.3-0 <0.1.4-0 || >=0.1.4-0 <0.1.5-0 || >=0.1.5-0 <0.1.6-0 || >=0.1.6-0 <0.1.7-0 || >=0.1.7-0 <0.1.8-0 || 0.2.0-rc.2 || 0.2.1-alpha.2",
61
62
  "dsh-harmony": "^0.8.11"
62
63
  },
63
64
  "peerDependenciesMeta": {
package/patch.cjs CHANGED
@@ -11,7 +11,7 @@ const { pathToFileURL } = require('node:url')
11
11
  const INLINE = require('./inline-source.cjs')
12
12
 
13
13
  const LEGACY_RANGE = '>=0.1.0-rc.8 <=0.1.1-rc.2'
14
- const DSH_MODERN_RANGE = '>=0.1.2-alpha.5 <0.1.7-0'
14
+ const DSH_MODERN_RANGE = '>=0.1.2-alpha.5 <0.1.8-0 || 0.2.0-rc.2'
15
15
 
16
16
  function manifestVersion(filename) {
17
17
  return JSON.parse(fs.readFileSync(filename, 'utf8')).version
@@ -45,7 +45,27 @@ function target(packageName, version) {
45
45
  return { package: packageName, version, file: 'lib/client.js' }
46
46
  }
47
47
 
48
- function commonPatches(targetSpec, rewrite) {
48
+ function runtimeSource(version) {
49
+ const [major, minor, patch] = version.split('.').map(part => Number.parseInt(part, 10))
50
+ const modern = major > 0 || minor > 1 || (minor === 1 && patch >= 7)
51
+ let source = INLINE.replace('var modern = typeof ctx.configForms !== "undefined";', `var modern = ${modern};`)
52
+ if (modern) source = source
53
+ .replaceAll('IconApiOutline14', 'IconApiOutlineRegular')
54
+ .replaceAll('IconChevronDownOutline14', 'IconChevronDownOutlineRegular')
55
+ if (minor >= 2 || major > 0) source = `function __ch4acko3DshTurnFoldReasoningRow(props) {
56
+ return react_jsx_runtime.jsx(ReasoningRow, {
57
+ ...props,
58
+ useDisclosure,
59
+ usePresentation: (select) => select({ settledReasoningPreview: false }),
60
+ renderSlot: (_name, content) => react_jsx_runtime.jsx(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, {
61
+ text: content.text, streaming: content.running, labels: markdownLabels(props.t), variant: "compact"
62
+ })
63
+ });
64
+ }\n` + source.replaceAll('react_jsx_runtime.jsx(ReasoningRow,', 'react_jsx_runtime.jsx(__ch4acko3DshTurnFoldReasoningRow,')
65
+ return source
66
+ }
67
+
68
+ function commonPatches(targetSpec, rewrite, inline = INLINE) {
49
69
  return [
50
70
  {
51
71
  id: 'inject-turn-fold-runtime',
@@ -54,7 +74,7 @@ function commonPatches(targetSpec, rewrite) {
54
74
  select: 'FunctionDeclaration[name.name="ChatView"], VariableStatement:has(VariableDeclaration[name.name="ChatView"])',
55
75
  expect: 1,
56
76
  apply({ node, sourceFile, edit }) {
57
- edit.prependLeft(node.getStart(sourceFile), INLINE + '\n\n')
77
+ edit.prependLeft(node.getStart(sourceFile), inline + '\n\n')
58
78
  },
59
79
  },
60
80
  {
@@ -95,7 +115,7 @@ function legacyPatches() {
95
115
  })
96
116
  }
97
117
 
98
- function dsh012Patches() {
118
+ function dsh012Patches(version) {
99
119
  return commonPatches(target('@deepseek-ai/dsh-client-ui-chat', DSH_MODERN_RANGE), {
100
120
  select: 'CallExpression[arguments.0.name="ChatNodeList"]',
101
121
  apply({ node, sourceFile, edit }) {
@@ -103,17 +123,51 @@ function dsh012Patches() {
103
123
  if (props === undefined) throw new Error('@ch4acko3/dsh-turn-fold: ChatNodeList props are missing')
104
124
  const jsx = sourceFile.text.slice(node.expression.getStart(sourceFile), node.expression.getEnd())
105
125
  const nativeProps = sourceFile.text.slice(props.getStart(sourceFile), props.getEnd())
126
+ let chatView = node.parent
127
+ while (chatView && !(chatView.name?.getText(sourceFile) === 'ChatView' && chatView.body)) chatView = chatView.parent
128
+ if (!chatView) throw new Error('@ch4acko3/dsh-turn-fold: ChatNodeList is outside ChatView')
129
+ const hasTimeline = chatView.body.statements.some(statement => statement.declarationList?.declarations.some(declaration => declaration.name.getText(sourceFile) === 'timeline'))
130
+ const timeline = hasTimeline ? 'timeline' : '__ch4acko3DshTurnFoldTimeline'
131
+ if (!hasTimeline) edit.prependLeft(chatView.body.getStart(sourceFile) + 1, '\nconst __ch4acko3DshTurnFoldTimeline = useChat((snapshot) => snapshot.timeline);\n')
132
+ // Newer ChatNodeSeat hides process nodes independently of Turn Fold.
133
+ // Take over both its visibility flag and its synthetic disclosure row.
134
+ const hasPresentation = props.properties.some((property) => property.name?.getText(sourceFile) === 'usePresentation')
135
+ const hasNativeFolding = hasPresentation || props.properties.some((property) => property.name?.getText(sourceFile) === 'compactTranscript')
136
+ const order = hasNativeFolding ? 'order: order.filter((key) => nodeStore.get(key)?.kind !== "turn-process")' : 'order'
137
+ const foldingProps = hasPresentation
138
+ ? 'usePresentation: (select) => usePresentation((policy) => select({ ...policy, foldCompletedTurns: false })), '
139
+ : hasNativeFolding ? 'compactTranscript: false, ' : ''
106
140
  edit.overwrite(
107
141
  node.getStart(sourceFile),
108
142
  node.getEnd(),
109
- `__ch4acko3DshTurnFoldRender({ order, nodeStore, timeline, sessionId, renderNode: (nodeKey) => ${jsx}(ChatNodeSeat, { ...(${nativeProps}), nodeKey }, nodeKey), t })`
143
+ `__ch4acko3DshTurnFoldRender({ ${order}, nodeStore, timeline: ${timeline}, sessionId, renderNode: (nodeKey) => ${jsx}(ChatNodeSeat, { ...(${nativeProps}), ${foldingProps}nodeKey }, nodeKey), t })`
110
144
  )
111
145
  },
112
- })
146
+ }, runtimeSource(version))
113
147
  }
114
148
 
115
149
  function createPatches(version) {
116
- return usesUiChat(version) ? dsh012Patches() : legacyPatches()
150
+ if (/^0\.2\.1-/.test(version)) return dsh021Patches(version)
151
+ return usesUiChat(version) ? dsh012Patches(version) : legacyPatches()
152
+ }
153
+
154
+ function dsh021Patches(version) {
155
+ return commonPatches(target('@deepseek-ai/dsh-client-ui-chat', '0.2.1-alpha.2'), {
156
+ select: 'FunctionExpression[name.name="ChatFlow"]',
157
+ apply({ node, sourceFile, edit, query }) {
158
+ const rows = query('CallExpression[expression.name.name="map"][expression.expression.name="entries"]', node)
159
+ const flow = query('CallExpression').filter(call => call.expression.getText(sourceFile) === 'renderSlot' && call.arguments[0]?.getText(sourceFile) === '"conversation.chat.flow"')
160
+ if (rows.length !== 1 || flow.length !== 1) throw new Error('@ch4acko3/dsh-turn-fold: expected one ChatFlow render loop and slot')
161
+ const parameters = node.parameters[0].name
162
+ edit.prependLeft(parameters.getStart(sourceFile) + 1, 'sessionId, ')
163
+ edit.prependLeft(flow[0].arguments[1].getStart(sourceFile) + 1, 'sessionId, ')
164
+ edit.prependLeft(node.body.getStart(sourceFile) + 1, '\nconst order = useChat((snapshot) => snapshot.order);\nconst timeline = useChat((snapshot) => snapshot.timeline);\n')
165
+ const pending = query('CallExpression', node).find(call => call.expression.getText(sourceFile) === 'rows.splice')
166
+ if (!pending) throw new Error('@ch4acko3/dsh-turn-fold: pending input insertion is missing')
167
+ edit.overwrite(pending.arguments[0].getStart(sourceFile), pending.arguments[0].getEnd(), 'rows.length')
168
+ edit.overwrite(rows[0].getStart(sourceFile), rows[0].getEnd(), `__ch4acko3DshTurnFoldRender({ order: order.filter((key) => nodeStore.get(key)?.kind !== "turn-process"), nodeStore, timeline, sessionId, renderNode: (nodeKey) => (0, react.createElement)(ChatNodeSeat, { ...seatProps, usePresentation: (select) => usePresentation((policy) => select({ ...policy, foldCompletedTurns: false })), nodeKey, key: nodeKey }), t })`)
169
+ },
170
+ }, runtimeSource(version))
117
171
  }
118
172
 
119
173
  const patches = createPatches(activeDshVersion())
@@ -122,6 +176,7 @@ Object.defineProperties(patches, {
122
176
  activeDshVersion: { value: activeDshVersion },
123
177
  LEGACY_RANGE: { value: LEGACY_RANGE },
124
178
  DSH_MODERN_RANGE: { value: DSH_MODERN_RANGE },
179
+ runtimeSource: { value: runtimeSource },
125
180
  })
126
181
 
127
182
  module.exports = patches
package/settings.cjs CHANGED
@@ -52,6 +52,15 @@ Object.defineProperty(Config, '~standard', {
52
52
  })
53
53
 
54
54
  let settingsSchema
55
+ let configSchema
56
+ function createConfigSchema() {
57
+ if (configSchema !== undefined) return configSchema
58
+ const z = require('@deepseek-ai/schemastery')
59
+ configSchema = z.object({
60
+ summaryFields: z.array(z.union(SUMMARY_FIELDS)).default(DEFAULT_SUMMARY_FIELDS).volatile(),
61
+ })
62
+ return configSchema
63
+ }
55
64
  function createSettingsSchema() {
56
65
  if (settingsSchema !== undefined) return settingsSchema
57
66
  // The Host loads CommonJS providers alongside the ESM settings graph. Defer
@@ -66,6 +75,7 @@ function createSettingsSchema() {
66
75
  module.exports = {
67
76
  Config,
68
77
  createSettingsSchema,
78
+ createConfigSchema,
69
79
  DEFAULT_SUMMARY_FIELDS,
70
80
  SETTINGS_NAMESPACE,
71
81
  SUMMARY_FIELDS,