dsh-ptc-plus 0.2.4 → 0.3.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.en.md +177 -0
- package/README.md +85 -69
- package/assets/ptc-plus-bindings-en.png +0 -0
- package/assets/ptc-plus-bindings-zh.png +0 -0
- package/assets/ptc-plus-repair-en.png +0 -0
- package/assets/ptc-plus-settings-en.png +0 -0
- package/assets/ptc-plus-settings-zh.png +0 -0
- package/client.js +1168 -144
- package/docs/adr/0006-rewrite-module-syntax-with-an-ast.md +1 -1
- package/docs/adr/0007-separate-worker-transport-from-session-semantics.md +15 -3
- package/docs/adr/0013-isolate-repl-redeclaration-convenience.md +7 -3
- package/docs/adr/0014-persist-cell-rewrite-policy.md +7 -5
- package/docs/adr/0019-plugin-settings-and-kill-switch.md +19 -4
- package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
- package/docs/adr/0021-separate-host-bootstrap-from-session-runtime.md +5 -3
- package/docs/adr/0022-stage-npm-releases-with-oidc.md +2 -2
- package/docs/architecture.md +23 -14
- package/docs/client-ui.md +29 -11
- package/docs/durability-design.md +42 -20
- package/docs/installation.md +11 -3
- package/docs/program-data-plane.md +6 -0
- package/docs/runtime-reference.md +27 -14
- package/docs/value-wire.md +1 -1
- package/index.js +38 -4
- package/internal/cell-analysis.js +89 -12
- package/internal/cell-rewriter.js +162 -4
- package/internal/config-spec.js +192 -117
- package/internal/direct-surface-owner.js +56 -5
- package/internal/edit-transport-owner.js +11 -2
- package/internal/failure-reporting.js +15 -0
- package/internal/kernel-worker.js +11 -0
- package/internal/rejected-cell-editor.js +21 -12
- package/internal/repl-convenience.js +94 -6
- package/internal/repl-memory-projection.js +277 -0
- package/internal/repl-rewrite-contract.js +15 -0
- package/internal/run-code-description.js +34 -0
- package/internal/runtime-bridge-owner.js +63 -15
- package/internal/runtime-config.js +3 -0
- package/internal/session-cell-executor.js +74 -14
- package/internal/session-events.js +7 -0
- package/internal/session-journal.js +331 -63
- package/internal/session-log-view.js +2 -1
- package/internal/session-runtime.js +110 -9
- package/internal/session-state.js +116 -4
- package/package.json +10 -7
- package/src/client-activity.js +501 -0
- package/src/client.js +456 -20
- package/README.zh.md +0 -161
- /package/assets/{ptc-plus-repair.png → ptc-plus-repair-zh.png} +0 -0
|
@@ -2,19 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
## 状态
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
本文拥有 `dsh-ptc-plus` 的 journal、两阶段确认和冷恢复契约;`internal/session-journal.js` 与 `internal/session-runtime.js` 提供实现证据。
|
|
6
6
|
|
|
7
7
|
## 恢复承诺
|
|
8
8
|
|
|
9
9
|
PTC Plus 的正确承诺是:
|
|
10
10
|
|
|
11
|
-
>
|
|
11
|
+
> **只把可证明状态称为已恢复;历史最差可收缩到空 REPL,但当前合法 cell 仍可继续。**
|
|
12
12
|
|
|
13
13
|
- durable cell 的源码、tool transcript、结算顺序和 completion 足以精确重放;
|
|
14
14
|
- volatile cell 可使用 policy 允许但无法 journal 的 Node 能力,只保证当前 worker 生命周期内延续;
|
|
15
15
|
- 一旦进入 volatile,整个 live 后缀保持 volatile;
|
|
16
16
|
- restore 命名的 durable 状态可以显式丢弃 volatile 后缀;
|
|
17
|
-
- abort、timeout、worker exit、OOM
|
|
17
|
+
- abort、timeout、worker exit、OOM、进程恢复和损坏的历史 PTC metadata 都收缩到最大可证明 frontier;没有非空 frontier 时从空 REPL 执行当前 cell;
|
|
18
|
+
- 历史恢复拒绝不可信状态证据,不因这项插件自有历史损坏而永久拒绝后续 `run_code`;当前请求自身的 DSH validation、policy、authority、approval 和 cancellation 仍可拒绝执行;
|
|
19
|
+
- 收缩不重新 dispatch、撤销或验证历史 effect;丢失的 binding 由一次 `PTC-R002` 明确提示模型按需重建;
|
|
20
|
+
- 可重建不是默认暴露 binding 的充分条件:恢复 frontier 还必须让 binding 的精确 provenance 保留在生成当前调用的模型可见 surface 中,或由显式选择的有界、模型可见结构化投影公开;不能只为延长隐藏状态而默认注入该投影,raw log 与 UI-only inventory 也不满足这项条件;
|
|
18
21
|
- `durableReplay: false` 时,新 kernel 从空状态开始且所有已执行 live cell 都是 volatile,作为
|
|
19
22
|
用户怀疑恢复正确性时的显式逃生模式;
|
|
20
23
|
- 被跳过的源码仍保存在原始 `tool/call` 中。
|
|
@@ -27,13 +30,19 @@ PTC Plus 的正确承诺是:
|
|
|
27
30
|
|
|
28
31
|
```ts
|
|
29
32
|
{
|
|
30
|
-
version:
|
|
31
|
-
|
|
33
|
+
version: 4,
|
|
34
|
+
bindingPolicy: {
|
|
35
|
+
variableRedeclarations: boolean,
|
|
36
|
+
functionClassRedeclarations: boolean
|
|
37
|
+
},
|
|
32
38
|
rewritePolicy: {
|
|
33
39
|
autoRewriteImports: boolean,
|
|
34
40
|
autoStripExports: boolean,
|
|
35
41
|
autoSplitRedeclarations: boolean
|
|
36
42
|
},
|
|
43
|
+
moduleSemantics: {
|
|
44
|
+
defaultExportBinding: "legacy-variable" | "live-readonly"
|
|
45
|
+
},
|
|
37
46
|
status: "durable" | "volatile" | "discarded" | "noop",
|
|
38
47
|
calls: CapabilityCall[],
|
|
39
48
|
operations: StateOperation[],
|
|
@@ -50,8 +59,9 @@ PTC Plus 的正确承诺是:
|
|
|
50
59
|
字段含义:
|
|
51
60
|
|
|
52
61
|
- `durable`:创建可重放 node,推进 `durableHead`;
|
|
53
|
-
- `
|
|
62
|
+
- `bindingPolicy`:记录该 cell 实际采用的变量重声明和 function/class 重声明语义;冷重放读取每个 node 的完整记录值,并用它重建 binding 可写性,不读取恢复时的 profile 配置;
|
|
54
63
|
- `rewritePolicy`:记录该 cell 解析和 lowering 时使用的三个 AST rewrite 开关;冷重放读取每个 node 的记录值,不读取恢复时的 profile 配置;
|
|
64
|
+
- `moduleSemantics`:记录不可由 profile 选择的源码 lowering 代际;当前 cell 固定写入 `live-readonly`,冷重放按记录值恢复 `export default` 的公开 binding 模型;
|
|
55
65
|
- `volatile`:只推进 live heap,不推进 `durableHead`;
|
|
56
66
|
- `discarded`:基础设施失败,calls 和 operations 必须为空;若中止时仍有未结算的 program binding call,则以首个 `global.member` 保留 `volatileReason`,恢复时不能把这个 possible-effect boundary 折叠为 no-op;
|
|
57
67
|
- `noop`:程序未执行,calls 和 operations 必须为空;
|
|
@@ -69,7 +79,7 @@ SessionRuntime 创建 kernel 时完全忽略历史 nodes、head、checkpoints
|
|
|
69
79
|
|
|
70
80
|
journal、diagnostic、source、cause、call、operation、completion 和 completion error 都使用封闭字段集合;未知、symbol 或非枚举自有字段会使 journal 无效。capability-call `args`/`value` 与 return completion `value` 都是封闭、规范化的 `ptc-value-graph/v1` envelope。诊断结构、source frame 依赖和稳定代码见[架构说明](architecture.md#journal-与恢复)。
|
|
71
81
|
|
|
72
|
-
|
|
82
|
+
当前实现只写入 `version: 4` schema。v1-v3 作为封闭 predecessor 输入规范化为 v4:旧 `bindingMode` 精确映射到 `bindingPolicy.variableRedeclarations`,而 `functionClassRedeclarations` 固定为 `false`,因为旧 pipeline 不具备该语义;`moduleSemantics.defaultExportBinding` 固定迁移为 `legacy-variable`,使 loose 历史保留旧的可写生成 binding、strict 历史保留旧的 const 行为。v1 仍使用三个 rewrite 开关全关的历史默认值,并只在 session log 唯一证明 call identity 时迁移字符串 confirmation;v2/v3 保留自身 `rewritePolicy`,无法表示为非负 event sequence 的 confirmation 必须形成 unknown boundary 并触发状态收缩。包括 `bindingPolicy`、`rewritePolicy`、`moduleSemantics`、`diagnostics` 在内的必需字段缺失时 journal 必须失效,否则会削弱最终持久值与 tentative journal 的严格一致性确认;失效 journal 不证明旧 binding,但也不单独成为后续当前调用的 availability gate。profile 后续切换任一 binding 或 AST rewrite 开关只影响新 cell,历史 node 始终按自身记录的 policy 和 module semantics 重放。
|
|
73
83
|
|
|
74
84
|
## Capability Call Transcript
|
|
75
85
|
|
|
@@ -117,9 +127,9 @@ pre-execute -> tools/execute -> post-execute
|
|
|
117
127
|
| 观察 | Live 行为 | 冷恢复行为 |
|
|
118
128
|
| --- | --- | --- |
|
|
119
129
|
| valid journal | 按 status 提交 | 按 journal 折叠 |
|
|
120
|
-
| 已执行,最终 journal 被删除 | cell 与后缀 volatile |
|
|
130
|
+
| 已执行,最终 journal 被删除 | cell 与后缀 volatile | 收缩到此前可证明 frontier,继续当前 cell |
|
|
121
131
|
| 未进入 runtime | pending no-op | 后续 `confirms` 存在时忽略 |
|
|
122
|
-
| 无法判断且未被确认 | 保守处理 |
|
|
132
|
+
| 无法判断且未被确认 | 保守处理 | 拒绝其状态证据;必要时空 REPL,继续当前 cell |
|
|
123
133
|
|
|
124
134
|
比较先严格规范化 journal,再使用 PTC value graph 的扁平 wire 表示,不对深层参数做递归遍历。额外无关 metadata 不影响确认,但 `dshPtcPlus` 自身任何可观察差异都拒绝确认。
|
|
125
135
|
|
|
@@ -133,20 +143,32 @@ pre-execute -> tools/execute -> post-execute
|
|
|
133
143
|
|
|
134
144
|
## 日志折叠
|
|
135
145
|
|
|
136
|
-
|
|
146
|
+
恢复以当前请求需要的 head 为目标,沿可证明 parent 关系向更早 frontier 收缩;实现可以前向折叠 event 建图,但不得把 unknown boundary 两侧的日志位置当作状态依赖证据。恢复入口先把当前 call id 解析为持久化 `tool/call.seq`,再把该序号作为 live boundary 传入折叠器;对应的在途 call event 不属于历史。每个 `edit_run_code` 在其 call event 处,根据此前已经结算的调用确定并固定可编辑目标;之后出现的 result 只影响随后发起的 edit:
|
|
137
147
|
|
|
138
148
|
1. 用 `sourceEventSeqs[0]` 关联 `tool/result` 与 `tool/call`;
|
|
139
149
|
2. 预收集 valid journal 中的 `confirms`;
|
|
140
150
|
3. 排除与 live boundary 序号相同的在途 call,并让已确认 no-op 的无 journal call 不改变状态;
|
|
141
|
-
4. 缺失源码、缺失/损坏 journal
|
|
151
|
+
4. 缺失源码、缺失/损坏 journal 或无法验证的 call/result/prune 关联建立 untrusted boundary,不作为旧 binding 的证据;
|
|
142
152
|
5. `noop` 与不含 `volatileReason` 的 `discarded` 不改变语言状态;带 `volatileReason` 的 `discarded` 表示 heap 已回滚但外部 effect 未知,进入 untrusted suffix;
|
|
143
153
|
6. `volatile` 进入 untrusted suffix,只应用可独立持久的 delete/restore 操作;
|
|
144
154
|
7. `restore` 命名状态重新建立 trusted durable head;
|
|
145
|
-
8.
|
|
155
|
+
8. 只有 ancestry 或独立性有插件自有机械证据的 post-boundary durable 记录才可保留;否则整个受影响 cell 与依赖后缀收缩;
|
|
146
156
|
9. durable node 保存 parent link,命名状态保存 node index;
|
|
147
|
-
10. `meta.dshPtcPlusRecoveryBoundaries` 在 `tool/result` event sequence
|
|
157
|
+
10. `meta.dshPtcPlusRecoveryBoundaries` 在 `tool/result` event sequence 参与排序前完成规范化;损坏 boundary 被拒绝为状态证据并建立保守收缩点,合法 boundary 通过失败 call seq 选择 node,并要求记录的 frontier 恰好是该 node 的 parent;
|
|
158
|
+
11. 折叠器剪除不可证明的 node、binding 与依赖后代,按剩余记录重算 checkpoints;runtime 重置 worker 并验证候选 frontier,逐级收缩到最大可重放 frontier,必要时到空 REPL;
|
|
159
|
+
12. 当前 cell 只在 worker 实际拥有该 frontier 后执行,成为它的新 child 或空 REPL 的新 root;当前结果持久记录本次收缩并投影一次恢复诊断。
|
|
160
|
+
|
|
161
|
+
当前 journal 没有完整的逐 binding 读写与传递依赖图。源码存在、重放未抛错或 completion 相同,都不足以证明闭包捕获、属性 mutation、动态名称访问或运行时值与原执行一致。因此恢复不能任意挑选 unknown boundary 后看似独立的 binding;缺少机械证明时以 cell 为原子并丢弃受影响后缀。将来若要保留更细粒度状态,必须通过版本化、owner-owned 的依赖证据扩展契约,不能从名称或成功重放猜测。
|
|
162
|
+
|
|
163
|
+
第 12 步是可用性与真实性共同的不变量:旧 unknown 调用不能被伪装成已恢复 heap,也不能在每次重启时永久吞掉所有后续 `run_code`。当前 cell 是在已经实际物化的 frontier 上重新执行,所以它可以安全建立持久新分支;这不表示被剪除 cell 的外部 effect 没有发生。
|
|
164
|
+
|
|
165
|
+
## 模型可知状态
|
|
166
|
+
|
|
167
|
+
DSH session 同时提供两个不同投影:append-only event log 保存审计、journal 与 replay evidence;ordered surface/derived request history 是模型请求实际可见的消息历史。PTC Plus 的默认状态 frontier 是“结构可重建”和“模型可知”的交集,不能用 raw log 的存在替代 surface evidence。模型可知只采用外部可验证事实,不猜模型内部记忆:精确声明源码仍在当前 request surface,或插件/宿主通过有界结构把准确 binding identity 与 provenance 放入模型上下文。
|
|
168
|
+
|
|
169
|
+
surface replacement 是否删除状态取决于模型失去了什么,而不取决于是否出现 `compaction/prune` 这个名字。只替换过长 tool result、仍保留 assistant `run_code`/`edit_run_code` 调用及源码时,模型仍知道该 cell,可继续使用其 journal。若 replacement 或 summary 遮蔽了声明 provenance,raw journal 即使完整也不能让 binding 默认继续存在;自然语言 summary 不解析为依赖或 binding 证明。当前没有模型可见的完整 binding inventory,因此缺少精确 provenance 时按 cell 与依赖后缀收缩。
|
|
148
170
|
|
|
149
|
-
|
|
171
|
+
该规则也约束 live worker。runtime 在下一 cell 前观察 DSH public surface generation;发生 replacement 后,若现存 binding 超出模型可知 frontier,先重置 worker、重建交集 frontier,再执行当前 cell。Client header card 的 `dshPtcPlusBindings` 只帮助用户检查,不进入模型上下文,也不延长 binding 生命周期;相同 contraction 应让 UI inventory 进入不可确认状态。未来若新增模型可见状态投影,它必须由用户、模型或明确配置选择,有固定 schema、硬预算、append-only runtime-context 证据和明确清除条件,不能仅为延长隐藏状态而默认注入,也不能污染稳定 prompt prefix。
|
|
150
172
|
|
|
151
173
|
## Completion 校验
|
|
152
174
|
|
|
@@ -164,7 +186,7 @@ pre-execute -> tools/execute -> post-execute
|
|
|
164
186
|
- recovery divergence;
|
|
165
187
|
- durable replay 触发 volatile capability。
|
|
166
188
|
|
|
167
|
-
基础设施失败会终止当前 worker,并把 log-only recovery boundary 放入当前已结算 `tool/result` 的私有 metadata。kernel 从失败 node 的 parent 重新重放;若该 frontier 仍失败则继续向 parent
|
|
189
|
+
基础设施失败会终止当前 worker,并把 log-only recovery boundary 放入当前已结算 `tool/result` 的私有 metadata。kernel 从失败 node 的 parent 重新重放;若该 frontier 仍失败则继续向 parent 收缩,直到最大可验证 frontier 或空 REPL。触发恢复的当前 `run_code` 在候选 frontier 验证成功前不执行,验证后在同一次请求中继续。boundary 无效或历史本身无法完整折叠时,相关记录和可能依赖它的状态不得进入 frontier;这类历史 PTC metadata 损坏本身不返回永久 recovery error,而是继续收缩,最差用空 worker 执行当前 cell,并在其最终 result 持久表达新 ancestry。已经写入旧版自定义 boundary event 的日志必须先通过显式、非破坏迁移转换为 DSH 可加载的 metadata;迁移失败时不得覆盖原始日志。
|
|
168
190
|
|
|
169
191
|
## State Operations
|
|
170
192
|
|
|
@@ -206,7 +228,7 @@ worker 不继承 Electron 的工作目录语义。插件通过现有 `tools/exec
|
|
|
206
228
|
|
|
207
229
|
## 恢复通知
|
|
208
230
|
|
|
209
|
-
构造 kernel 时若折叠结果含 volatile/unknown
|
|
231
|
+
构造 kernel 时若折叠结果含 volatile/unknown boundary、模型可见 surface 收缩,或本次重放产生 recovery contraction,第一次实际执行的 `run_code` 记录并投影 `PTC-R002`。它只统计当前 call 之前实际未恢复的历史 cell,并明确旧 binding 可能需要重新声明:
|
|
210
232
|
|
|
211
233
|
```text
|
|
212
234
|
warning[PTC-R002]: restored the durable head and skipped N unreconstructable historical cells
|
|
@@ -215,7 +237,7 @@ state: ...
|
|
|
215
237
|
help: ...
|
|
216
238
|
```
|
|
217
239
|
|
|
218
|
-
通知进入正常 CodeRuntime logs,结构化值进入当前 journal,因此成功结果和错误结果都能呈现并从 session log
|
|
240
|
+
通知进入正常 CodeRuntime logs,结构化值进入当前 journal,因此成功结果和错误结果都能呈现并从 session log 重建。收缩边界随当前 result 持久化,后续 cold start 从新分支恢复,不重复撞击同一损坏历史;每个 kernel 只发送一次,避免污染后续上下文。
|
|
219
241
|
|
|
220
242
|
live kernel 首次进入 volatile 只更新 journal 的 `status` / `volatileReason` 和 `repl.state(list)`,不向模型投影 warning/note。该转换不要求当前任务采取行动;只有 cold recovery 已实际跳过 volatile、unknown 或 replay-abandoned 历史时才发送 `PTC-R002`。worker 在首次观察到直接 Node/OS 边界时立即通知主线程,因此后续 hard abort、timeout 或 worker exit 仍能把原因写入 discarded journal。
|
|
221
243
|
|
|
@@ -244,7 +266,7 @@ live kernel 首次进入 volatile 只更新 journal 的 `status` / `volatileReas
|
|
|
244
266
|
|
|
245
267
|
以上是当前已实现的 PTC journal 协议。native `tools.*` 保持 owner contract;cell program binding 不得变成新的模型 transport。
|
|
246
268
|
|
|
247
|
-
任何公共扩展面无法持久确认的状态都必须收缩为 volatile/unknown
|
|
269
|
+
任何公共扩展面无法持久确认的状态都必须收缩为 volatile/unknown 边界,但边界否定的是旧状态证明,不是当前合法调用的可用性;最大可证明 frontier 为空时,插件仍应让当前 cell 从空 REPL 建立新分支。修改或 fork DSH、patch 私有
|
|
248
270
|
scheduler、复制 policy/event protocol 或伪造事件不属于本协议。若上游以后提供 owner-declared
|
|
249
271
|
typed binding,它可以使用 DSH nested dispatch,但不得伪装成 journal confirmation,也不得绕过
|
|
250
272
|
scope、policy 或 settlement。
|
|
@@ -256,10 +278,10 @@ scope、policy 或 settlement。
|
|
|
256
278
|
- volatile live continuation、冷恢复跳过和 durable 重基;
|
|
257
279
|
- post-execute metadata 删除与 pre-dispatch no-op 确认;
|
|
258
280
|
- hard abort、冷 worker 启动取消和未结算 program binding 的 possible-effect boundary;
|
|
259
|
-
- replay timeout
|
|
281
|
+
- replay timeout 逐级收缩到可验证 frontier;
|
|
260
282
|
- Math intrinsic、局部 ambient 名称、CWD 相关 `node:path`;
|
|
261
283
|
- 命名状态 save/restore/delete 与 volatile restore;
|
|
262
284
|
- 深层 graph value、own `__proto__` key、`undefined`、special number、BigInt、hole、alias 与 cycle;
|
|
263
|
-
-
|
|
285
|
+
- 独立的变量与 function/class 重声明 policy、不可写目标 preflight、声明位置替换及 cold replay;
|
|
264
286
|
- runtime throw、invalid output 和真实 recovery 的结构化诊断与模型可见投影;普通 volatile transition 保持安静;
|
|
265
287
|
- 未修改 DSH 的真实公共扩展面,并在全新 session runtime 中从日志恢复。
|
package/docs/installation.md
CHANGED
|
@@ -23,7 +23,7 @@ The optional `cordisToolsEnabled` integration requires the current DSH installat
|
|
|
23
23
|
Use this form after the selected version is available from the npm registry:
|
|
24
24
|
|
|
25
25
|
```sh
|
|
26
|
-
dsh plugin --profile <profile> add dsh-ptc-plus@0.
|
|
26
|
+
dsh plugin --profile <profile> add dsh-ptc-plus@0.3.1
|
|
27
27
|
dsh --profile <profile> --dump-config
|
|
28
28
|
```
|
|
29
29
|
|
|
@@ -60,7 +60,7 @@ pnpm dsh --profile <profile> --dump-config
|
|
|
60
60
|
|
|
61
61
|
```sh
|
|
62
62
|
npm pack
|
|
63
|
-
dsh plugin --profile <profile> add /absolute/path/to/dsh-ptc-plus-0.
|
|
63
|
+
dsh plugin --profile <profile> add /absolute/path/to/dsh-ptc-plus-0.3.1.tgz
|
|
64
64
|
dsh --profile <profile> --dump-config
|
|
65
65
|
```
|
|
66
66
|
|
|
@@ -70,6 +70,14 @@ Windows development checkouts can create and install an immutable content-addres
|
|
|
70
70
|
scripts\install-dev.cmd <profile>
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
## Isolated latest-DSH development launcher
|
|
74
|
+
|
|
75
|
+
To test this checkout in a separate DSH installation, double-click `scripts\run-dev-dsh.cmd`. It resolves the current `@deepseek-ai/dsh@alpha` dist-tag, installs that exact version only when the cached version changes, creates the shipped `web` profile inside an isolated `DSH_HOME`, installs this checkout, and starts DSH. If no port is supplied, it selects a free loopback port automatically, so another DSH on port 3080 does not block the test instance. The launcher does not modify the repository or your normal DSH home.
|
|
76
|
+
|
|
77
|
+
The default cache is `%LOCALAPPDATA%\dsh-ptc-plus-dev`. It contains the isolated `DSH_HOME`, DSH installations, immutable plugin snapshots, and a pnpm store. Only the newest three DSH versions and plugin snapshots are retained, and the dedicated pnpm store is pruned after each install. Set `DSH_DEV_CACHE` to move the cache, `DSH_DEV_PROFILE` to change the profile name, `DSH_DEV_VERSION` to select another npm dist-tag or version, `DSH_DEV_PORT` to choose a fixed Web port, or `DSH_DEV_MAX_VERSIONS` to change the retention count (1-10).
|
|
78
|
+
|
|
79
|
+
The Windows launchers normalize the process, machine, and user `PATH` values in memory, remove duplicate entries, and add the Node/cache directories they need. They do not create drive mappings, junction trees, or persistent environment changes. If a genuinely unique PATH is still too long for `cmd.exe`, the launcher stops before npm or DSH runs and asks you to shorten the relevant PATH value.
|
|
80
|
+
|
|
73
81
|
## DSH Desktop
|
|
74
82
|
|
|
75
83
|
On Windows or macOS, choose **Open DSH Terminal** from the Desktop tray. Bare commands in that terminal target the active profile:
|
|
@@ -79,4 +87,4 @@ dsh plugin add github:muyuanjin/dsh-ptc-plus#main
|
|
|
79
87
|
dsh --dump-config
|
|
80
88
|
```
|
|
81
89
|
|
|
82
|
-
After an npm release, the package spec may instead be `dsh-ptc-plus@0.
|
|
90
|
+
After an npm release, the package spec may instead be `dsh-ptc-plus@0.3.1`. For a local package, use its absolute tarball path. Restart DSH Desktop after installation. Linux Desktop is not a current DSH Desktop release target; use DSH CLI/Web on Linux.
|
|
@@ -49,6 +49,12 @@ return source.length
|
|
|
49
49
|
|
|
50
50
|
普通已知程序优先 argv spawn;只有命令本身需要 shell 语义时才使用 shell。shell 不是权限系统,也不是 REPL 前置条件;PTY/ConPTY 只用于交互进程。Windows、WSL 与 POSIX 环境的 executable、路径、resolver、signal 和 TTY 必须分别探查,不能由一个 execution world 推断另一个。
|
|
51
51
|
|
|
52
|
+
## Stateful visibility
|
|
53
|
+
|
|
54
|
+
journal 值、模型请求和 Client 展示是三种不同的数据面。append-only session log 中存在完整 journal,只能证明插件有材料尝试重建;DSH ordered surface/derived request history 才证明生成当前调用的模型看到过哪些声明。Client 的 `meta.dshPtcPlusBindings` inventory 只对用户展示,不进入模型上下文;当前 `repl.state(list)` 只描述命名 checkpoint 与 durability mode,也不让隐藏 binding 自动变成模型可知状态。
|
|
55
|
+
|
|
56
|
+
因此默认 REPL frontier 必须同时可重建且模型可知。result-only 剪裁若仍保留带精确源码的 assistant call,不改变该 cell 的模型 provenance;若 compaction 遮蔽了声明 call,raw journal 不足以继续暴露其 binding。插件不解析自然语言 summary 推断名称、值或依赖,而是收缩相关 cell 与依赖后缀,必要时从空 REPL 继续当前 cell。未来可以用显式选择、有界、结构化的 model-visible state projection 保留被压缩的状态,但它必须从 session log 重建、进入实际 request context,并遵守稳定 prompt prefix;不能仅为延长隐藏状态而默认注入,UI metadata 也不能替代它。
|
|
57
|
+
|
|
52
58
|
## Metadata boundaries
|
|
53
59
|
|
|
54
60
|
能力 explorer 分别报告:
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Each top-level `run_code` input is parsed as an async function body using modern JavaScript and erasable TypeScript syntax. Top-level bindings survive across cells, block scope and top-level `await` work normally, and only explicit `return` or printed values appear in the result. Static `import` and `export` declarations are adapted when their corresponding `auto*` options are enabled; named and default imports remain live, read-only bindings across later cells. Otherwise use dynamic `import()` or `require()` and omit module declarations.
|
|
6
6
|
|
|
7
|
-
The default
|
|
7
|
+
The default variable policy lets a complete top-level `const` or `let` declarator replace existing names. New declarators create bindings. With `autoSplitRedeclarations` enabled, mixed new/existing destructuring is split while preserving its assignment semantics; disabling either option rejects the corresponding variable form before execution. The independent `looseTopLevelFunctionClassRedeclarations` option defaults to `false`. When enabled, a later named top-level function or class declaration replaces an existing binding only when its recorded source provenance proves it writable. Replacement commits at the declaration position, so earlier statements see the old function/class and later statements see the new one; it is not native function hoisting. Imports, reserved/private names, source `const` bindings not lowered by the variable policy, and unknown-provenance targets are rejected before execution. Same-cell and block-scope rules remain native JavaScript/TypeScript rules.
|
|
8
8
|
|
|
9
9
|
Every capability namespace is leased to one cell. Captured `tools`, `capabilities`, `repl`, `code`, or member functions expire when that cell ends.
|
|
10
10
|
|
|
@@ -45,28 +45,35 @@ For commands, prefer project-declared scripts and use an available typed tool. W
|
|
|
45
45
|
|
|
46
46
|
The configuration uses `ptc-plus` as the DSH plugin ID and `dsh-ptc-plus` as the package name. The distinction is intentional: the former is the runtime/settings identity, while the latter is the repository and npm package identity.
|
|
47
47
|
|
|
48
|
+
`enhancedToolView` defaults to `true` and controls only the browser presentation of `run_code` and `edit_run_code`. Turning it off unregisters PTC Plus's keyed tool views so DSH's native generic row renders the calls; turning it on restores the compatibility renderer without changing execution, prompt, or session behavior.
|
|
49
|
+
|
|
50
|
+
`autoDescribeRunCode` defaults to `true` and appears as “Allow run_code execution without a summary.” When enabled, a call that omits the outer `run_code.description` uses derived arguments for local DSH validation, and the fallback summary enters presentation metadata only. When disabled, DSH validates the original arguments. Both states expose byte-identical model requests with the required `description` declaration; original call arguments, existing summaries, cell source, and nested native-tool JSON remain unchanged.
|
|
51
|
+
|
|
48
52
|
```yaml
|
|
49
53
|
- id: ptc-plus
|
|
50
54
|
name: dsh-ptc-plus
|
|
51
55
|
config:
|
|
52
56
|
enabled: true
|
|
57
|
+
enhancedToolView: true
|
|
58
|
+
canonicalizeToolCalls: true
|
|
59
|
+
autoDescribeRunCode: true
|
|
60
|
+
looseTopLevelRedeclarations: true
|
|
61
|
+
looseTopLevelFunctionClassRedeclarations: false
|
|
62
|
+
autoRewriteImports: true
|
|
63
|
+
autoStripExports: true
|
|
64
|
+
autoSplitRedeclarations: true
|
|
65
|
+
durableReplay: true
|
|
66
|
+
tipsEnabled: true
|
|
53
67
|
cordisToolsEnabled: false
|
|
54
68
|
computeMs: 60000
|
|
55
69
|
maxWallMs: 600000
|
|
56
|
-
maxOutputBytes: 67108864
|
|
57
70
|
maxOldGenerationSizeMb: 512
|
|
71
|
+
maxNestedRunCodeDepth: 8
|
|
72
|
+
maxOutputBytes: 67108864
|
|
58
73
|
maxValueNodes: 100000
|
|
59
74
|
maxValueEdges: 1000000
|
|
60
75
|
maxValueArrayLength: 1000000
|
|
61
76
|
maxValueBigIntDigits: 100000
|
|
62
|
-
maxNestedRunCodeDepth: 8
|
|
63
|
-
canonicalizeToolCalls: true
|
|
64
|
-
looseTopLevelRedeclarations: true
|
|
65
|
-
durableReplay: true
|
|
66
|
-
autoRewriteImports: true
|
|
67
|
-
autoStripExports: true
|
|
68
|
-
autoSplitRedeclarations: true
|
|
69
|
-
tipsEnabled: true
|
|
70
77
|
tipCooldownMessages: 3
|
|
71
78
|
tipEscalationFailures: 2
|
|
72
79
|
```
|
|
@@ -77,16 +84,22 @@ The configuration uses `ptc-plus` as the DSH plugin ID and `dsh-ptc-plus` as the
|
|
|
77
84
|
|
|
78
85
|
Keep large Cordis host or client source in a top-level binding before calling a Cordis tool. A parse or validation rejection is a runtime failure, so bindings assigned before it remain live for a short retry cell; reuse the binding instead of resending the source.
|
|
79
86
|
|
|
80
|
-
Cordis Plugins and Runs are process-local. On a resumed agent or after Cordis is re-enabled, normalized journal calls can restore their recorded return values but do not prove that prior IDs, approvals, Runs, or Inspect observations are live. The fixed `tools:ptc-plus-cordis-recovery` context remains present until a new successful `cordis_inspect*` call is settled. Use that live read-only inspection before a stateful Cordis decision; do not rerun a mutating
|
|
87
|
+
Cordis Plugins and Runs are process-local. On a resumed agent or after Cordis is re-enabled, normalized journal calls can restore their recorded return values but do not prove that prior IDs, approvals, Runs, or Inspect observations are live. The fixed `tools:ptc-plus-cordis-recovery` context remains present until a new successful `cordis_inspect*` call is settled. Use that live read-only inspection before a stateful Cordis decision; do not rerun a recorded mutating call merely to rebuild state.
|
|
88
|
+
|
|
89
|
+
`durableReplay: false` starts new kernels without recorded REPL state while preserving live bindings in the current process. It does not delete session logs.
|
|
90
|
+
|
|
91
|
+
With `durableReplay: true`, recovery claims only bindings backed by both verified journal ancestry and exact provenance available to the model that produced the current call. DSH's append-only event log proves reconstructability; its ordered model-visible surface proves awareness. Raw events shadowed from that surface and UI-only `dshPtcPlusBindings` metadata do not make a binding model-knowable. A result-only replacement may retain a cell when the assistant call containing its source remains visible. If compaction shadows that call, the live worker and cold recovery contract the affected state unless an explicitly selected bounded structured projection exposes the exact bindings in model context. Such a projection is not injected by default merely to retain hidden state. Natural-language summaries are not parsed as state evidence.
|
|
92
|
+
|
|
93
|
+
An invalid historical association, prune replacement, or recovery boundary is also rejected as evidence for its bindings; it is not by itself a reason to reject every later valid `run_code`. Recovery takes the intersection of the model-knowable and structurally verified frontiers, then discards cells and bindings that may depend on an unknown boundary. Because the current journal does not contain a complete per-binding dependency graph, the conservative unit is an affected cell and suffix unless stronger owned evidence exists. If no non-empty frontier is provable, the worker starts from an empty REPL and executes the current cell as a new root.
|
|
81
94
|
|
|
82
|
-
|
|
95
|
+
The first continued cell reports `PTC-R002` once so the model can redeclare any missing bindings, and its result persists the contraction for later cold starts. Recovery never redispatches, reverses, or certifies effects from discarded history. This availability fallback applies only to historical PTC Plus recovery data; validation, policy, authority, approval, cancellation, and other failures of the current request retain their normal DSH behavior.
|
|
83
96
|
|
|
84
97
|
Recovery tips are disabled with `tipsEnabled: false`. When enabled, a bounded runtime context in the reserved `tools:ptc-plus-tip/<trigger>/<ordinal>` name family may appear after a repeated binding failure or a diagnostic that identifies an executable, shell, or path problem in the current execution world. The trigger and per-trigger ordinal are reconstructed from canonical named system-prompt snapshots; repeated aggregate copies and visible wording do not advance the history. A tip is subject to `tipCooldownMessages` and becomes detailed only after `tipEscalationFailures` unresolved matches; it never changes the code-only direct-tool list or schema. `edit_run_code` does not emit a runtime context because its real call and result already carry the relevant fact.
|
|
85
98
|
|
|
86
99
|
The three `auto*` toggles control text-level AST rewriting applied before cell wrapping, all on by default:
|
|
87
100
|
|
|
88
101
|
- `autoRewriteImports` adapts static `import` declarations (`import x from 'm'`, named, namespace, side-effect, mixed, and type-only forms) through worker-preloaded module namespaces. Static and dynamic imports use Node's ESM resolver from the session cwd, or the worker process cwd when the session has no recorded cwd; relative project files, bare packages, conditional exports, URL imports, and import attributes retain Node semantics. Modules resolve in source order before the cell body is compiled, and a missing requested export fails during linking before that target module evaluates. Named and default aliases keep live reads and reject assignment; a later explicit loose-mode declaration may replace an alias for future cells while closures compiled earlier retain the import. Unsupported destructuring, loop, and delete writes are rejected before execution. Direct `eval` and `with` are unavailable while value import aliases are active because their dynamic name resolution cannot be preserved by alias rewriting; rejection occurs before module preload. Indirect or locally shadowed eval, `with` without active value aliases, and cells containing only type imports retain ordinary JavaScript behavior.
|
|
89
|
-
- `autoStripExports` strips top-level `export` modifiers: declarations survive without the keyword, `export default` becomes a
|
|
102
|
+
- `autoStripExports` strips top-level `export` modifiers: declarations survive without the keyword, `export default` becomes a live read-only `__default` alias updated at the declaration position, re-exports become side-effect imports, and type-only exports are erased. A cell that separately declares the fixed public name `__default` and also has a default export is rejected before execution. A default function or class whose own name is `__default` keeps that inner name for recursion or class self-reference while the public alias still uses the same private, commit-gated slot as every other default export.
|
|
90
103
|
- `autoSplitRedeclarations` allows a top-level destructuring declaration to mix existing and new names. The original pattern runs under native JavaScript initialization semantics, then existing names are committed and fresh names remain available to later cells.
|
|
91
104
|
|
|
92
105
|
Rewrites are recorded as `meta.dshPtcPlusRewrites` on the tool result (parallel to the journal, a closed schema). Successful rewrites do not emit runtime context. If the rewritten cell fails or has no valid journal, `tools:ptc-plus-rewrite-info` describes the recovery boundary in the next model request.
|
|
@@ -102,7 +115,7 @@ Rewrites are recorded as `meta.dshPtcPlusRewrites` on the tool result (parallel
|
|
|
102
115
|
| `PTC-N001` | Top-level binding conflict | Not executed; REPL unchanged |
|
|
103
116
|
| `PTC-O001` | Unsupported or over-budget output | Cell executed; earlier mutations may exist |
|
|
104
117
|
| `PTC-X001` | Uncaught runtime exception, located at the cell source line | Mutations before the throw may exist |
|
|
105
|
-
| `PTC-R002` | Cold recovery
|
|
118
|
+
| `PTC-R002` | Cold recovery discarded volatile, unconfirmed, damaged, or replay-abandoned history | Continued from the greatest verified frontier, possibly an empty REPL; missing bindings may need redeclaration |
|
|
106
119
|
| `PTC-W001` | The same cell failed 3 consecutive times with an identical binding error | One-shot binding-recovery warning appended to the failing cell's logs; no state change |
|
|
107
120
|
| `PTC-W002` | The same cell failed 3 consecutive times with another identical error | One-shot cause-specific warning appended to the failing cell's logs; no state change |
|
|
108
121
|
|
package/docs/value-wire.md
CHANGED
|
@@ -52,7 +52,7 @@ DSH 的公共 `CodeRuntime`/tool output 只接受 JSON-safe structured value。
|
|
|
52
52
|
- renderer 只是模型展示,不参与 hydrate;需要继续计算时应保留 live REPL binding;
|
|
53
53
|
- journal 保存 canonical graph envelope,不保存 renderer 反解析结果,也不把 decoded rich value 交给外层 `JSON.stringify`。
|
|
54
54
|
|
|
55
|
-
unsupported value
|
|
55
|
+
unsupported value 或预算超限使用 `PTC-O001`,帮助文本只要求返回受支持的 PTC value 或缩小结果;`undefined` 属于受支持值,不要求模型用 `null` 替换。
|
|
56
56
|
|
|
57
57
|
cell program binding 的参数和结果经过同一 graph IPC,因此 owner-provided binding 可以接收和返回
|
|
58
58
|
完整 `PTCValueV1` 支持域,包括 `undefined`、special number、BigInt、hole、shared identity 与 cycle。
|
package/index.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import Schema from '@deepseek-ai/schemastery'
|
|
10
|
+
import { randomUUID } from 'node:crypto'
|
|
10
11
|
import { createDirectSurfaceOwner } from './internal/direct-surface-owner.js'
|
|
11
12
|
import { createCordisToolsOwner } from './internal/cordis-tools-owner.js'
|
|
12
13
|
import { createEditTransportOwner, EDIT_RUN_CODE } from './internal/edit-transport-owner.js'
|
|
@@ -17,6 +18,7 @@ import {
|
|
|
17
18
|
SETTINGS_NAMESPACE,
|
|
18
19
|
} from './internal/config-spec.js'
|
|
19
20
|
import { installSettingsSectionCompat } from './internal/settings-compat.js'
|
|
21
|
+
import { createReplMemoryProjection } from './internal/repl-memory-projection.js'
|
|
20
22
|
import * as dshSettings from '@deepseek-ai/dsh-settings'
|
|
21
23
|
|
|
22
24
|
const INSTALL_CLEANUP = Symbol('ptc-plus install cleanup')
|
|
@@ -41,15 +43,19 @@ export const inject = ['tools', 'codeRuntime', 'systemPrompt', 'agents', 'llm']
|
|
|
41
43
|
|
|
42
44
|
function replGuidance(
|
|
43
45
|
looseTopLevelRedeclarations,
|
|
46
|
+
looseTopLevelFunctionClassRedeclarations,
|
|
44
47
|
durableReplay,
|
|
45
48
|
autoRewriteImports,
|
|
46
49
|
autoStripExports,
|
|
47
50
|
autoSplitRedeclarations,
|
|
48
51
|
cordisToolsEnabled,
|
|
49
52
|
) {
|
|
50
|
-
const
|
|
53
|
+
const variableRedeclaration = looseTopLevelRedeclarations
|
|
51
54
|
? 'Repeated top-level `const`/`let` declarations replace existing bindings.'
|
|
52
|
-
: '
|
|
55
|
+
: 'Repeated top-level variable declarations fail before execution, so reuse existing bindings or place one-off declarations inside a block.'
|
|
56
|
+
const functionClassRedeclaration = looseTopLevelFunctionClassRedeclarations
|
|
57
|
+
? 'Repeated top-level named `function`/`class` declarations replace existing writable bindings at their declaration position. Do not rely on function hoisting or class TDZ; define a replacement before using that name in the cell.'
|
|
58
|
+
: 'Repeated top-level `function`/`class` declarations remain unsupported; assign a function or class expression to an existing writable binding, or place one-off declarations inside a block.'
|
|
53
59
|
const moduleSyntax = autoRewriteImports && autoStripExports
|
|
54
60
|
? 'static `import` declarations are adapted with live, read-only bindings and top-level `export` modifiers are stripped automatically.'
|
|
55
61
|
: autoRewriteImports
|
|
@@ -71,7 +77,7 @@ function replGuidance(
|
|
|
71
77
|
The host may append a bounded recovery context after a qualifying failure. Treat that context as a session-log-derived diagnostic: use \`edit_run_code\` only when it explicitly proves a complete-cell rerun is safe; otherwise inspect live state in a new short \`run_code\` cell.
|
|
72
78
|
|
|
73
79
|
## Cell conventions
|
|
74
|
-
Expressions that are neither returned nor printed produce no output. Keep large inspection results in bindings or reduce them to targeted excerpts: \`tools.read\` is bounded inspection, not a lossless whole-file reader. Cells are async function bodies; ${moduleSyntax} Use dynamic import or require explicitly when static module syntax is unsupported. ${
|
|
80
|
+
Expressions that are neither returned nor printed produce no output. Keep large inspection results in bindings or reduce them to targeted excerpts: \`tools.read\` is bounded inspection, not a lossless whole-file reader. Cells are async function bodies; ${moduleSyntax} Use dynamic import or require explicitly when static module syntax is unsupported. ${variableRedeclaration} ${functionClassRedeclaration} ${splitSyntax}
|
|
75
81
|
|
|
76
82
|
## Available capabilities
|
|
77
83
|
Use \`capabilities.tree()\`, \`capabilities.find()\`, and \`capabilities.inspect()\` to discover the current request's live \`tools.*\` members before calling an unfamiliar binding. Prefer direct current-cell work; reserve \`code.run\` for source already held as data.
|
|
@@ -81,6 +87,8 @@ Native tool availability, executable names, shells, and path syntax depend on th
|
|
|
81
87
|
|
|
82
88
|
/** Register the session-bound REPL runtime. */
|
|
83
89
|
function installPtCRuntime(ctx, resolvedConfig, toolSchemasForAgent, sessionId) {
|
|
90
|
+
const presentationGeneration = randomUUID()
|
|
91
|
+
const replMemoryProjection = createReplMemoryProjection(presentationGeneration)
|
|
84
92
|
let activeConfig = resolvedConfig
|
|
85
93
|
let cordisTools
|
|
86
94
|
let runtimeBridge
|
|
@@ -151,6 +159,25 @@ function installPtCRuntime(ctx, resolvedConfig, toolSchemasForAgent, sessionId)
|
|
|
151
159
|
}
|
|
152
160
|
const cancelCordisActivation = () => pendingCordisActivation?.cancel()
|
|
153
161
|
try {
|
|
162
|
+
if (typeof ctx.inject === 'function') {
|
|
163
|
+
const projectionInjection = ctx.inject(['sessionProjections'], (scope) => {
|
|
164
|
+
if (disposed) return
|
|
165
|
+
try {
|
|
166
|
+
const unregister = scope.sessionProjections?.register?.(replMemoryProjection)
|
|
167
|
+
if (typeof unregister !== 'function') {
|
|
168
|
+
throw new Error('ptc-plus: sessionProjections.register did not return a disposer')
|
|
169
|
+
}
|
|
170
|
+
disposers.push(unregister)
|
|
171
|
+
} catch (error) {
|
|
172
|
+
ctx.logger?.warn?.('ptc-plus: REPL memory projection unavailable', error)
|
|
173
|
+
}
|
|
174
|
+
})
|
|
175
|
+
if (typeof projectionInjection === 'function') {
|
|
176
|
+
disposers.push(projectionInjection)
|
|
177
|
+
} else if (typeof projectionInjection?.dispose === 'function') {
|
|
178
|
+
disposers.push(() => projectionInjection.dispose())
|
|
179
|
+
}
|
|
180
|
+
}
|
|
154
181
|
cordisTools = activeConfig.cordisToolsEnabled
|
|
155
182
|
? createCordisToolsOwner(ctx)
|
|
156
183
|
: undefined
|
|
@@ -165,12 +192,14 @@ function installPtCRuntime(ctx, resolvedConfig, toolSchemasForAgent, sessionId)
|
|
|
165
192
|
ctx,
|
|
166
193
|
sessionConfig: activeConfig,
|
|
167
194
|
maxNestedRunCodeDepth: activeConfig.maxNestedRunCodeDepth,
|
|
195
|
+
presentationGeneration,
|
|
168
196
|
sessionId,
|
|
169
197
|
toolSchemasForAgent,
|
|
170
198
|
})
|
|
171
199
|
editTransport = createEditTransportOwner(ctx, {
|
|
172
200
|
durableReplay: activeConfig.durableReplay,
|
|
173
201
|
executeTentative: runtimeBridge.executeTentative,
|
|
202
|
+
presentationGeneration,
|
|
174
203
|
sessionId,
|
|
175
204
|
toolSchemasForAgent,
|
|
176
205
|
})
|
|
@@ -188,6 +217,7 @@ function installPtCRuntime(ctx, resolvedConfig, toolSchemasForAgent, sessionId)
|
|
|
188
217
|
if (ctx.tools.get(RUN_CODE, context?.scope) === undefined) return ''
|
|
189
218
|
return replGuidance(
|
|
190
219
|
activeConfig.looseTopLevelRedeclarations,
|
|
220
|
+
activeConfig.looseTopLevelFunctionClassRedeclarations,
|
|
191
221
|
activeConfig.durableReplay,
|
|
192
222
|
activeConfig.autoRewriteImports,
|
|
193
223
|
activeConfig.autoStripExports,
|
|
@@ -203,7 +233,11 @@ function installPtCRuntime(ctx, resolvedConfig, toolSchemasForAgent, sessionId)
|
|
|
203
233
|
disposers.push(ctx.on('tools/execute', (exec, next) => {
|
|
204
234
|
const rejected = directSurface.executionRejection(exec)
|
|
205
235
|
if (rejected !== undefined) return rejected
|
|
206
|
-
if (exec.name === RUN_CODE)
|
|
236
|
+
if (exec.name === RUN_CODE) {
|
|
237
|
+
const executionArguments = directSurface.executionArguments(exec)
|
|
238
|
+
return Promise.resolve(runtimeBridge.handleExecute(exec, next, executionArguments))
|
|
239
|
+
.then(result => directSurface.argumentDiagnostic(exec, result))
|
|
240
|
+
}
|
|
207
241
|
return next()
|
|
208
242
|
}))
|
|
209
243
|
disposers.push(ctx.on('tools/result', (exec, result) => {
|