dsh-ptc-plus 0.3.2 → 0.4.1
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 +65 -78
- package/README.md +65 -78
- 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-repair-zh.png +0 -0
- package/assets/ptc-plus-repl-workspace-en.png +0 -0
- package/assets/ptc-plus-repl-workspace-zh.png +0 -0
- package/assets/ptc-plus-settings-en.png +0 -0
- package/assets/ptc-plus-settings-zh.png +0 -0
- package/client.js +30596 -742
- package/compiler-amaro.cjs +5 -0
- package/compiler-amaro.cjs.map +6 -0
- package/compiler-asset-124f80c1bba92ff5fe79cfec6e8ad518f476de4a42514cae3919538887f510e8.txt +1 -0
- package/compiler-assets.json +3 -0
- package/compiler-core.cjs +554 -0
- package/compiler-core.cjs.map +6 -0
- package/compiler-platform.cjs +2 -0
- package/compiler-platform.cjs.map +6 -0
- package/compiler-typescript.cjs +388 -0
- package/compiler-typescript.cjs.map +6 -0
- package/docs/README.md +6 -0
- package/docs/adr/0004-declare-program-bindings-at-the-host.md +1 -1
- package/docs/adr/0006-rewrite-module-syntax-with-an-ast.md +5 -3
- package/docs/adr/0007-separate-worker-transport-from-session-semantics.md +1 -1
- package/docs/adr/0009-bound-expensive-acceptance-default.md +2 -0
- package/docs/adr/0010-session-log-derived-recovery-tips.md +59 -5
- package/docs/adr/0011-isolate-the-local-recovery-tip-provider.md +1 -1
- package/docs/adr/0012-preserve-mixed-destructuring-initialization.md +3 -1
- package/docs/adr/0013-isolate-repl-redeclaration-convenience.md +3 -1
- package/docs/adr/0014-persist-cell-rewrite-policy.md +6 -2
- package/docs/adr/0015-preserve-source-positions-through-rewrites.md +1 -1
- package/docs/adr/0016-archive-resolved-review-findings.md +1 -1
- package/docs/adr/0017-track-the-latest-dsh-public-surface.md +49 -0
- package/docs/adr/0018-use-versioned-fixture-for-ab-benchmark.md +3 -3
- package/docs/adr/0019-plugin-settings-and-kill-switch.md +5 -3
- package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
- package/docs/adr/0021-separate-host-bootstrap-from-session-runtime.md +12 -0
- package/docs/adr/0023-global-user-bindings.md +104 -0
- package/docs/adr/0024-repl-console-observation.md +33 -0
- package/docs/adr/0025-use-versioned-logical-binding-identities.md +119 -0
- package/docs/adr/0026-persist-the-delivery-verdict-against-the-verified-candidate.md +21 -0
- package/docs/adr/0027-run-the-session-kernel-in-a-killable-helper-process.md +37 -0
- package/docs/adr/0028-attach-to-the-host-ptc-execution-seam.md +103 -0
- package/docs/adr/0029-keep-plugin-unavailability-out-of-the-host-agent-lifecycle.md +27 -0
- package/docs/adr/0030-serve-both-typert-codec-generations-from-one-codec.md +27 -0
- package/docs/architecture.md +73 -21
- package/docs/binding-review-placement-design.md +200 -0
- package/docs/capability-projection.md +1 -1
- package/docs/client-ui.md +95 -19
- package/docs/durability-design.md +25 -10
- package/docs/evaluation.md +78 -6
- package/docs/installation.md +41 -6
- package/docs/publishing.md +5 -3
- package/docs/runtime-reference.md +72 -25
- package/docs/semantic-validation.md +29 -0
- package/docs/stateful-binding-updates-proposal.md +755 -0
- package/docs/user-bindings.en.md +64 -0
- package/docs/user-bindings.md +64 -0
- package/docs/value-wire.md +3 -3
- package/docs/verification.md +57 -0
- package/index.js +369 -92
- package/internal/ast-traversal.js +5 -2
- package/internal/binding-descriptors.js +1 -0
- package/internal/binding-pattern-traversal.js +25 -0
- package/internal/binding-pattern.js +26 -29
- package/internal/binding-source-analysis.js +391 -0
- package/internal/binding-update-policy.js +66 -0
- package/internal/bounded-worker-round.js +56 -0
- package/internal/callable-definition-environment.js +42 -0
- package/internal/callable-source-catalog.js +129 -0
- package/internal/callable-source-encoding.js +47 -0
- package/internal/callable-source-facts.js +459 -0
- package/internal/callable-source-format.js +2 -0
- package/internal/callable-source-lowering.js +123 -0
- package/internal/cell-analysis-contract.js +25 -0
- package/internal/cell-analysis.js +240 -290
- package/internal/cell-completion.js +15 -0
- package/internal/cell-error.js +7 -0
- package/internal/cell-parser.js +66 -0
- package/internal/cell-rewriter.js +3 -677
- package/internal/commonjs-export-evidence.js +63 -0
- package/internal/commonjs-source-evidence.js +72 -0
- package/internal/compiler-amaro.cjs +2 -0
- package/internal/compiler-compression.js +12 -0
- package/internal/compiler-data.js +58 -0
- package/internal/compiler-descriptors.js +54 -0
- package/internal/compiler-dynamic-cache.js +48 -0
- package/internal/compiler-entry.js +35 -0
- package/internal/compiler-generated-names.js +17 -0
- package/internal/compiler-intrinsics.js +84 -0
- package/internal/compiler-module-links.js +34 -0
- package/internal/compiler-operations.js +61 -0
- package/internal/compiler-platform-factory.js +84 -0
- package/internal/compiler-platform.js +136 -0
- package/internal/compiler-record-roles.js +53 -0
- package/internal/compiler-region-output.js +259 -0
- package/internal/compiler-resource-lowering.js +103 -0
- package/internal/compiler-scope-facts.js +115 -0
- package/internal/compiler-service.js +109 -0
- package/internal/compiler-source-cache.js +32 -0
- package/internal/compiler-source-pieces.js +93 -0
- package/internal/compiler-source-regions.js +132 -0
- package/internal/compiler-storage-source.js +54 -0
- package/internal/compiler-text.js +15 -0
- package/internal/compiler-typescript.cjs +2 -0
- package/internal/config-spec.js +83 -27
- package/internal/cordis-tools-owner.js +130 -21
- package/internal/diagnostic.js +27 -1
- package/internal/direct-surface-owner.js +76 -23
- package/internal/dynamic-binding-evidence.js +16 -0
- package/internal/dynamic-environment-compiler.js +779 -0
- package/internal/dynamic-environment-integration.js +87 -0
- package/internal/dynamic-environment-runtime.js +362 -0
- package/internal/dynamic-native-calls.js +150 -0
- package/internal/dynamic-native-runtime.js +248 -0
- package/internal/dynamic-scope-analysis.js +90 -0
- package/internal/edit-transport-owner.js +27 -2
- package/internal/execution-seam-compat.js +193 -0
- package/internal/failure-reporting.js +118 -18
- package/internal/host-rpc.js +66 -0
- package/internal/isolated-worker.js +548 -0
- package/internal/kernel-child.js +139 -0
- package/internal/kernel-worker.js +904 -120
- package/internal/language-semantics.js +14 -0
- package/internal/legacy-binding-catalog.js +48 -0
- package/internal/legacy-cell-analysis.js +600 -0
- package/internal/legacy-cell-parser.js +50 -0
- package/internal/legacy-cell-rewriter.js +631 -0
- package/internal/legacy-repl-convenience.js +291 -0
- package/internal/managed-module-operations.js +170 -0
- package/internal/module-compilation.js +321 -0
- package/internal/module-runtime-platform.js +19 -0
- package/internal/module-transform-contract.js +12 -0
- package/internal/native-await-declarations.js +68 -0
- package/internal/native-root-compilation.js +54 -0
- package/internal/native-root-dynamic.js +67 -0
- package/internal/recovery-tips.js +27 -15
- package/internal/rejected-cell-editor.js +13 -8
- package/internal/repl-convenience.js +2 -289
- package/internal/repl-memory-projection.js +81 -12
- package/internal/repl-observation-interest.js +70 -0
- package/internal/repl-rewrite-contract.js +6 -0
- package/internal/repl-scope-normalizer.js +2091 -0
- package/internal/repl-value-observer.js +114 -0
- package/internal/rpc-contract.js +52 -0
- package/internal/runtime-bridge-owner.js +172 -28
- package/internal/runtime-config.js +48 -52
- package/internal/runtime-contexts.js +82 -10
- package/internal/runtime-messages.js +111 -0
- package/internal/session-cell-executor.js +401 -87
- package/internal/session-journal-recovery.js +684 -0
- package/internal/session-journal-schema.js +106 -0
- package/internal/session-journal.js +184 -654
- package/internal/session-log-view.js +42 -9
- package/internal/session-runtime.js +256 -95
- package/internal/session-state.js +247 -71
- package/internal/source-position-map.js +211 -71
- package/internal/stateful-module-compiler.js +154 -0
- package/internal/stateful-module-runtime.js +303 -0
- package/internal/stateful-root-compiler.js +598 -0
- package/internal/stateful-root-runtime.js +340 -0
- package/internal/typert-codec-compat.js +28 -0
- package/internal/typescript-transform.js +29 -0
- package/internal/user-binding-authoring.js +70 -0
- package/internal/user-binding-console-worker.js +184 -0
- package/internal/user-binding-console.js +148 -0
- package/internal/user-binding-draft-projection.js +335 -0
- package/internal/user-binding-model-context.js +31 -0
- package/internal/user-binding-runner.js +56 -0
- package/internal/user-bindings-owner.js +1065 -0
- package/internal/user-bindings-store.js +293 -0
- package/internal/user-bindings.js +353 -0
- package/internal/value-wire-schema.js +28 -0
- package/internal/value-wire.js +29 -20
- package/internal/worker-client.js +57 -67
- package/internal/worker-environment.js +45 -0
- package/internal/worker-output-relay.js +29 -0
- package/internal/worker-shutdown.js +14 -0
- package/package.json +75 -7
- package/src/client-activity.js +88 -53
- package/src/client-authoring-view.js +580 -0
- package/src/client-binding-review.js +230 -0
- package/src/client-bindings-data.js +29 -0
- package/src/client-catalog.js +127 -0
- package/src/client-code-editor.js +84 -0
- package/src/client-console.js +112 -0
- package/src/client-copy.js +370 -0
- package/src/client-feature-gates.js +62 -0
- package/src/client-host-compat.js +150 -0
- package/src/client-indicator-view.js +267 -0
- package/src/client-repl-view.js +292 -0
- package/src/client-rpc.js +20 -0
- package/src/client-settings-view.js +221 -0
- package/src/client-styles.js +106 -0
- package/src/client-tool-view.js +108 -0
- package/src/client-transport.js +159 -0
- package/src/client-workbench.js +521 -0
- package/src/client.js +233 -615
package/docs/client-ui.md
CHANGED
|
@@ -1,41 +1,91 @@
|
|
|
1
1
|
# Client UI
|
|
2
2
|
|
|
3
|
-
PTC Plus
|
|
3
|
+
PTC Plus 提供**插件设置卡片**。卡片座位由宿主代际决定:旧代际在 DSH Web/Desktop 的 Settings → Plugin configuration 中以 `settings.plugin.item` 渲染,当前 DSH 在侧栏 Plugins 页面以 `plugins.row.config`(键 `<包名>#<行 id>`)渲染该 bundle 自己的配置;`src/client-host-compat.js` 同时发布到两个座位,由声明了槽位的那一代决定哪个生效,卡片按座位提供的 `summary`/`page` 视图分别渲染一句描述与完整表单。输入框旁的星光菜单还直接打开复用同一表单的应用内设置窗口,不依赖宿主页面的局部导航状态;菜单项悬浮提示保留原生设置座位的路径。
|
|
4
|
+
|
|
5
|
+
Client 根入口只依赖 `settingsScope`、`slots`、`locale`、`connection` 和 `remote`。头部贡献直接消费公开 session slot 提供的 `useProjection`;REPL 注册另依赖 `sessions` 的当前选择和 projection face。命令卡片等待公开 command slot,composer 管理入口直接消费现有管理 Remote;其中的编写动作再等待 `remote.commands` 与公开输入 hooks,不依赖已改名的 conversation registry 或未使用的 `ui-session` 模块。缺失、卸载或迟到的 slot/provider 只影响需要它的贡献;没有 `useProjection` 时不挂载依赖它的会话视图,命令卡片保留宿主结果但不提供草稿操作。没有输入 hooks 时不显示编写动作,已有全局绑定仍可查看和启停。preset 优先读取 `agentPreset` projection,缺失时依次读取会话公开摘要里的 projection 值与旧宿主的 `agentPreset` 字段;binding 值和草稿资格不采用该回退。当前会话身份取宿主已发布的选中证据:旧代际在会话列表上投影 `current`,当前代际把视图选择留在 controller 之外、以主视图持有的会话表达。两者都不读取私有 store。设置和独立正文 tool view 继续可用,不读取私有 store 或自行重建会话状态。
|
|
6
|
+
|
|
7
|
+
组件通过 renderer 提供的 `useProjection`、旧宿主的公开 `useSessions` 和注入 `hooks` 读取外部状态,设置写入与 RPC 由 apply 层注入 callback。业务组件不自行构造 external-store hook。设置、slot、provider 与插件释放共同拥有注册和订阅的生命周期;开关关闭时撤销相关贡献。
|
|
8
|
+
|
|
9
|
+
REPL 对 composer 的接管优先使用当前公开 `sessionId`/`pendingInteraction` 参数;旧宿主仅在 `session.sessionId` 匹配且 `interactions` 为空数组时允许接管。审批、提问和无法确认的交互状态继续显示宿主 composer,不通过 DOM 隐藏输入框。
|
|
10
|
+
|
|
11
|
+
这些新旧接口差异由 `src/client-host-compat.js` 集中处理:组件使用 `useSessionPreset`,注册层使用 `watchCurrentSessionPreset` 跟随当前会话及其 projection,并用 `isIdleSessionComposer` 判断 composer 资格。适配模块负责证据优先级与订阅切换、释放;`src/client.js` 负责设置开关、PTC 功能资格和 slot 生命周期。当前会话变化时重新读取公共能力,不缓存全局宿主版本或会话能力。
|
|
12
|
+
|
|
13
|
+
Client 按数据、传输、注册与视图分文件,沿用既有 `createX(React, deps)` 工厂:`src/client-copy.js` 与 `src/client-styles.js` 拥有双语字典和样式数据,`src/client-rpc.js` 与 `src/client-transport.js` 拥有 Remote 调用和观察传输,`src/client-feature-gates.js` 拥有“设置快照 → 功能资格”的唯一映射与受门控注册,`src/client-catalog.js` 拥有全局目录读取,`src/client-workbench.js` 拥有工作台状态迁移与视图,`src/client-settings-view.js`、`src/client-tool-view.js`、`src/client-repl-view.js`、`src/client-authoring-view.js`、`src/client-indicator-view.js` 各自拥有一个 slot 的视图。`src/client.js` 只做装配与注册,不持有业务状态。设置快照到功能布尔只有一个纯函数(`featureEnabled`),受门控贡献共用一个“订阅 → 判定 → 注册/注销 → 回滚”实现(`registerGated`);preset、projection 和公共能力仍由各自 owner 判定,在调用点与设置资格组合。
|
|
4
14
|
|
|
5
15
|
## 设置命名空间
|
|
6
16
|
|
|
7
17
|
Host half 通过 DSH 公共 `settings` 服务注册命名空间 `ptc-plus`。字段清单、默认值和校验来自 `internal/config-spec.js`,
|
|
8
|
-
由 `index.js` 的 `Config` schema 与设置注册共用;client half 构建时把同一份字段清单打进 bundle,不在 UI
|
|
18
|
+
由 `index.js` 的 `Config` schema 与设置注册共用;client half 构建时把同一份字段清单打进 bundle,不在 UI 中复制默认值。`CONFIG_GROUPS` 独立拥有按用途排列的展示顺序:插件总开关单独置顶,其后为“调用容错”“REPL 语法”“状态与恢复”“工具扩展”“界面显示”“资源限制”。每个字段只展示一次,各组使用独立标题、留白与分隔线。
|
|
9
19
|
|
|
10
20
|
## 可用设置
|
|
11
21
|
|
|
12
22
|
| 分组 | 字段 | 说明 |
|
|
13
23
|
| --- | --- | --- |
|
|
14
|
-
| 开关 | `enabled` | 关闭后不注册 `run_code`/`edit_run_code`、不修改 system prompt、不创建 session runtime
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
|
|
|
23
|
-
|
|
|
24
|
+
| 开关 | `enabled` | 关闭后不注册 `run_code`/`edit_run_code`、不修改 system prompt、不创建 session runtime;保留设置 UI,Host 在下一允许步骤撤销旧 PTC 声明。 |
|
|
25
|
+
| 调用容错 | `autoDescribeRunCode` / `canonicalizeToolCalls` | 默认开启;允许缺少外层摘要的 `run_code` 执行,并修复 schema 可唯一确认的顶层 native 工具误调用。 |
|
|
26
|
+
| REPL 语法 | `bindingUpdates` | 默认 `stateful`;同作用域的声明与赋值更新变量、函数、类和导入。选择 `protected` 后保护新建 const/import,并检测跨 cell 重声明。两种策略均支持静态 import/export。 |
|
|
27
|
+
| 状态与恢复 | `durableReplay` / `tipsEnabled` | 默认开启;控制 worker 重启后的状态恢复与失败恢复提示。 |
|
|
28
|
+
| 状态与恢复 | `tipCooldownMessages` / `tipEscalationFailures` | 同类提示间隔与详细提示阈值。 |
|
|
29
|
+
| 工具扩展 | `userBindingsEnabled` | 默认关闭;开启后加载跨会话 TypeScript helper,并在开关下方显示管理按钮,同时启用全局绑定工作台与 `/binding` Agent 编写入口。 |
|
|
30
|
+
| 工具扩展 | `cordisToolsEnabled` | 默认关闭;开启后为 PTC agent 加入官方 Cordis 工具、指引与精确的 `cordis-plugin-development` companion Skill,不发布同目录 sibling。 |
|
|
31
|
+
| 界面显示 | `enhancedToolView` | 默认开启;关闭后注销 PTC Plus 的两个 keyed tool view,恢复 DSH 原生 generic row。 |
|
|
32
|
+
| 界面显示 | `replViewEnabled` | 默认开启;控制顶级 REPL 页签,关闭时释放观察订阅,不影响设置中的全局管理入口。 |
|
|
33
|
+
| 界面显示 | `bindingAuthorButtonVisible` | 默认开启;控制输入框旁的 PTC Plus 快捷入口(全局绑定查看/启停/编写,以及直接打开完整插件设置窗口),不撤销 `/binding` 命令。 |
|
|
34
|
+
| 资源限制 | `computeMs` / `maxWallMs` | 单 cell event-loop active(包括同步阻塞)与总耗时预算;前者不证明 CPU 消耗。 |
|
|
35
|
+
| 资源限制 | `maxOldGenerationSizeMb` / `maxNestedRunCodeDepth` | kernel worker 内存与嵌套执行深度。 |
|
|
36
|
+
| 资源限制 | `maxOutputBytes` | 单 cell 日志与返回结果的合计字节上限。 |
|
|
37
|
+
| 资源限制 | `maxValueNodes` / `maxValueEdges` / `maxValueArrayLength` / `maxValueBigIntDigits` | Value Graph 与大数组、BigInt 的返回上限。 |
|
|
38
|
+
|
|
39
|
+
旧配置的五个开关(`looseTopLevelRedeclarations`、`looseTopLevelFunctionClassRedeclarations`、`autoRewriteImports`、`autoStripExports`、`autoSplitRedeclarations`)先由共享 resolver 迁移。完整策略映射到 `stateful` 或 `protected`;混合选择保留显式兼容态,只有该状态才显示旧控件。兼容态的统一策略控件显示“沿用旧版设置(尚未迁移)”,可直接选择“允许重声明和覆盖”或“启用名称保护”;选择后一次写入同时保存 `bindingUpdates` 并清除兼容标记,随后执行和模型指引采用相同的新语言策略,设置页恢复统一开关。仅查看设置不触发写入。
|
|
24
40
|
|
|
25
41
|
## enabled 开关与正文功能标记
|
|
26
42
|
|
|
27
43
|
所有字段都是实时设置:Host 在 settings watch 中安装、卸载或重配置 runtime。已提交的 cell 固定使用提交时的配置快照,运行中的更新从随后提交的 cell 开始使用;这不会替换 session-bound REPL 或已有 binding。`maxOldGenerationSizeMb` 在活动 worker 存在时因 Node 的创建期限制而拒绝并回滚,其他可重配置字段照常交给 owner。关闭后唯一的宿主副作用是注册 settings 命名空间,
|
|
28
44
|
保证设置卡片仍然可读;此时只有 `enabled` 可写,其他控件被禁用。运行时重配置失败时回滚到上一次已应用值。
|
|
29
45
|
|
|
30
|
-
`cordisToolsEnabled` 默认关闭并即时生效。它不切换 preset,而是把官方 Cordis 工具、owner guidance 与 `cordis-plugin-development` Skill 作为一个 agent-scoped mount
|
|
46
|
+
`cordisToolsEnabled` 默认关闭并即时生效。它不切换 preset,而是把官方 Cordis 工具、owner guidance 与 `cordis-plugin-development` Skill 作为一个 agent-scoped mount 加入或移出同时暴露 `run_code`、`skill` 工具与 preset/Skill service 的 PTC agent;顶层仍为 `run_code` / `edit_run_code`,普通 agent 不继承。暴露面齐全但挂载失败时,启用会完整回滚;agent scope 缺少 companion surface 时只是延后,不报错也不发布。完整运行要求见 [运行时参考](runtime-reference.md)。
|
|
47
|
+
|
|
48
|
+
## 全局用户 Binding 工作台
|
|
49
|
+
|
|
50
|
+
`/binding new` 和 `/binding edit` 的历史命令处保留原始需求、状态和错误说明。候选被接受后,完整源码、模型上下文与保存/启用/丢弃操作由官方 `conversation.input.dock` 在当前输入框上方承载;历史条目只提供该请求自己的只读来源。面板通过 dock 内的零高度锚点悬浮在整个普通输入区上方,不顶高正文或宿主遮罩;默认展开,正文内部滚动。整条标题按钮支持点击与 Enter/Space,箭头随折叠状态变化;输入框只保留一个星光入口:首轮前即可通过官方 Menu 悬停、点击或键盘查看全局绑定、切换启停及打开完整工作台;设置条目直接打开复用设置卡片表单的应用内窗口,关闭后将焦点还给仍可用的星光按钮;编写命令可用时显示“编写新绑定”,并在同一个 Menu 内提供“修改绑定”第二步来选择已有条目。该入口与头部标识、REPL 页签同属 PTC surface:只在当前会话使用 `ptc` 或兼容 `code` preset 时注册,其他 preset 既不显示入口也不读取该会话的命令目录。该入口以插件署名提示说明来源与用途,有草稿时改为提示待处理草稿。有草稿时显示数量角标,草稿在独立分组中选择。当前 Host 每会话只保留一份候选,菜单不列出过期历史;隐藏编写快捷入口或命令服务缺席不影响已有草稿的访问。关闭和重新打开只改变展示,不撤销候选或待决 RPC。保存或丢弃确认成功后面板自动关闭;失败和结果待确认时保持用户的显隐选择。候选身份、写资格和异步结算由一个 Client review controller 复用 draft projection 与现有 RPC owner,页头不再提供第二套当前写操作。实现细节与验收证据见[Binding 审阅位置设计](binding-review-placement-design.md)。
|
|
51
|
+
|
|
52
|
+
`userBindingsEnabled` 关闭时不渲染任何 Global User Binding 管理界面,Host 也不注册对应 RPC 或 Agent 命令。开启后,REPL 页签中的“全局绑定”和设置管理按钮打开的大尺寸应用内弹窗复用同一个 `UserBindingsWorkbench`。设置卡片保留开关与管理按钮,不嵌入编辑器。普通管理不依赖当前存在 PTC 会话;Agent 辅助编写仍使用当前可用会话的 `/binding` 入口。
|
|
53
|
+
|
|
54
|
+
工作台默认载入首个条目,目录支持名称过滤和启停开关。内容依次为“接口声明”“模型上下文”“实现源码”“代码控制台”“条目配置”。接口只展示源码派生声明;实现源码默认折叠、只读,展开后使用公共 `CodeBlock` 提供 TypeScript 高亮与复制。点击“编辑”后开放源码与条目配置;源码使用 CodeMirror 提供高亮、行号、撤销与重做,保存或取消后恢复只读。模型上下文可直接修改,首次改动进入编辑状态,并在条目顶部显示验证、保存和取消操作。只改模型上下文保留接口预览,其他字段变化撤销旧派生声明,验证后再展示;草稿声明不证明模型已接收。操作反馈占用稳定位置,等待 RPC 不淡化整个工作台。目录保留 `.ts` 导入,保存保留 revision 校验。桌面使用目录与内容两列,窄容器改为单列;弹窗内部滚动,支持 Escape、关闭按钮和键盘焦点回环。显式关闭后,焦点返回最近一次打开或恢复弹窗时仍连接、可见且可用的键盘控件;从输入区打开时,该控件失效则回到可用的作者入口。临时隐藏保留返回目标并让宿主保有焦点,恢复时 body 不覆盖已有目标。
|
|
55
|
+
|
|
56
|
+
“模型上下文”编辑 `modelContext.includeDeclaration` 和 `instructions`,对应“将接口声明提供给模型”和“给模型的提示词”。声明开关默认开启,只控制已有源码派生接口的注入;非空提示词独立注入,最多 4096 字符,Host 同时检查完整启用集合的 16384 字符模型内容预算。新会话首轮及会话中途保存或启用后的下一次请求均使用当前配置,不等待绑定激活。候选历史和命令卡片保留接受时的字段;草稿保存、取消、重新加载与 revision 规则覆盖源码和提示词。取消声明勾选且清空提示词可省略模型上下文,不关闭绑定激活。
|
|
57
|
+
|
|
58
|
+
代码控制台直接执行当前条目的未保存源码草稿。用户可输入 `readText("./example.txt")`、声明变量或使用顶层 `await`,通过运行按钮或 Ctrl/Cmd+Enter 执行;下一条命令可继续使用临时变量。控制台通过 `console-run` 取得 Host 生成的 opaque environment handle,并以 `console-release` 释放;单次候选导出调用通过兼容的 `run` RPC 提供。控制台 worker 使用共同 root 编译与逻辑状态机制,源码草稿使用共同模块编译入口,Node REPL 承担底层求值;它不连接 Agent kernel,也不写入其 journal。模块导出可直接按名称调用,相对 import 从 binding 存储目录解析。运行、停止、重置环境、清空记录分别是独立动作;折叠不重置环境。普通语法或运行错误保留状态和此前修改,停止、超时、输出超限与 worker 故障会释放环境。执行代码具有 DSH 进程的 Node/OS 权限,这种状态隔离不构成 sandbox。
|
|
59
|
+
|
|
60
|
+
首次执行才创建 worker。源码草稿改动后的下一次执行、切换条目、保存修改后的源码、离开工作台或手动重置都会清空旧环境。连续 10 分钟没有执行代码时自动释放,输入输出记录保留;下一次从当前草稿开始,绝不自动重放旧命令。Host 最多保留 4 个临时环境,每个环境一次仅执行一个命令,并沿用 `maxWallMs`、`maxOutputBytes` 和 `maxOldGenerationSizeMb`。源码与单次命令各限制 1 MiB;Client 最多保留 40 条、合计 131072 个 UTF-16 code unit 的展示记录,单条最多 65536 个,截断有明确标记。关闭全局绑定功能或插件时释放全部临时环境。
|
|
61
|
+
|
|
62
|
+
每次执行的命令与输出分开展示。输出沿用会话工具结果的灰色背景、边框和 12px 圆角,带独立标签;长结果在至多 240px 高的内容区内滚动,窄屏自动换行,错误使用错误色。设置弹窗与 REPL 页复用同一输出组件。
|
|
63
|
+
|
|
64
|
+
Client 的管理操作由 `src/client-rpc.js` 通过 DSH Remote `ptcPlusBindings.invoke` 发给 Host owner;Gateway 使用既有 `/api` 通道,Connection 在分派前执行 Host/Origin 检查与浏览器认证。Client 不直接读写 `$DSH_HOME/ptc-plus/bindings.json`,不自行判断冲突,也不把 settings 同步当作通用 RPC。Host 返回 revision、结构化条目视图和错误;外部文件变化或过期 revision 会拒绝写入。编辑中也可重新加载目录与 revision,保留未保存的源码、条目字段和编辑器状态,再由用户明确重试保存;刷新不自动重复写入,也不把磁盘内容覆盖到草稿。
|
|
65
|
+
|
|
66
|
+
保存 revision 随已加载源码保存,单独更新目录不能使缓存源码取得更新的保存资格。非编辑状态重新加载时,同步选中条目的源码、声明和编辑基线;条目已删除则清除选中内容。编辑中重新加载会保留草稿,更新保存 revision 和取消编辑后的基线;取消时显示最近读到的磁盘条目。目录与条目读取的 revision 不一致时保留原状态,提示再次重新加载。过期请求和已释放工作台的响应不能覆盖当前内容。重新加载相同源码保留临时控制台环境,源码变化或条目删除则释放环境,不自动执行命令。
|
|
67
|
+
|
|
68
|
+
手动保存区分创建与编辑:请求显式携带 `intent`(`create`/`update`)、`originalId` 和 `expectedRevision`,由 Host 校验写入资格,Client 不以按钮禁用代替该校验。新建填写已存在的稳定 ID 时 Host 报冲突,Client 保留原条目与用户草稿并显示错误,用户重新加载目录后再决定是否重试;编辑只更新加载时的原 ID,不会静默变成创建或覆盖其他条目。稳定 ID 在已存条目的普通编辑中只读,新建时仍可填写;不提供重命名。
|
|
69
|
+
|
|
70
|
+
工作台的编辑文档身份与表单文本分离:`draft.id` 只是待保存数据,输入条目字段不重建源码编辑器或代码控制台,光标、选区、撤销历史和临时计算状态都保留;只有显式替换源码环境、切换条目、保存修改后的源码、真实重置或卸载才释放环境。全局管理弹窗的挂载生命周期同样与 composer 的临时可见性分离:宿主审批等交互暂时隐藏普通输入区时弹窗隐藏但不销毁,恢复后显示同一份未保存文本;显式关闭、功能关闭和 owner 释放仍释放资源,隐藏不恢复已撤销的 Host 写资格,也不在审批界面叠加操作。
|
|
71
|
+
|
|
72
|
+
全局目录读取由一个 owner 拥有,消费面通过 `claim()` 各取一份独立来源:同一来源内读取按最新一次失效(含中止前一次请求),写入串行,`connection/reset` 重置,卸载时释放;快照通过订阅发布,消费方不再自持 epoch。因此头部弹窗、工作台、REPL 页签与编写入口各自跟随自己的读取,一个面的迟到响应不会覆盖另一个面的快照,也不会恢复已撤销的写资格。会话观察(`ptcPlusRepl` projection)是另一种事实,继续按各自的 surface generation 失效,不与全局目录共用一个 epoch。
|
|
31
73
|
|
|
32
|
-
|
|
74
|
+
PTC session 的头部弹窗在功能启用时增加 Session 与 Global 页签。Session 保留当前可复用 binding 的只读检查;Global 只读展示持久化目录的启停状态,可按需展开精确源码;修订入口由 composer 星光菜单统一承载。头部摘要在 Session 显示可复用绑定总数,在 Global 显示目录条目数;数据不可用时保留空摘要行,切换页签不改变头部高度。目录条目数与“启用”状态不证明当前会话已成功激活。composer 已有非空草稿时保留原文并显示反馈;公开接口不提供 focus 时,Client 不访问宿主 DOM 强制聚焦。名称和成员被限制在各自 grid 列内,长名称与成员列表提供完整 title。窄弹窗不复制设置工作台的完整编辑、候选运行、启停、导入或删除功能。
|
|
75
|
+
|
|
76
|
+
接受候选时,Host 生成不可猜测的 locator,并把 locator、精确 candidate 源码和请求/命令身份放入接受结果的私有 metadata。`ptcPlusBindingDraft` projection 分别拥有可写草稿定位与只读历史;历史源码不从当前 catalog 重读。管理 Remote 不提供 caller/session identity,所有草稿操作凭 locator,不信任 payload session ID。Binding 命令卡片通过公共 `conversation.chat.commandview` 的 `binding` key 接管宿主命令行,直接读取宿主折叠后的 CommandNode,不注册 turn-tail 展示或重复关联命令事件。当前 dock 使用公共 `Button` 和 `CodeBlock` 呈现保存、丢弃与源码,历史请求复用只读源码展示;缺少原语时才降级。两处模型上下文以接口声明状态标签和完整提示词组成只读区,不显示禁用复选框。源码区不嵌套另一层卡片边框,已结束状态紧凑排列,源码可通过原生 details 继续展开。
|
|
77
|
+
|
|
78
|
+
“保存为停用”和“保存并启用”均原子认领草稿并校验 catalog revision,后者同时写入启用状态;两者都不运行候选。并发丢弃返回 busy。保存/丢弃确认成功后关闭当前面板并撤销操作入口,历史请求仍保留精确源码和结果;Host 的公共 action notice 引用接受结果,供日志 projection 和卡片重挂载恢复。保存回执不宣称当前会话已激活。回执未持久化且 Host 已重启时保持未知,不凭空 locator 猜测保存。目录冲突会重读 catalog、draft 和 review,保留仍有效的草稿供用户重试,不自动重复写入;权威空 draft 才撤销操作。会话结束、功能关闭或 agent disposal 撤销内存 locator;正常轮次结束只撤销未完成交接资格,已经接受的草稿继续等待用户决定。
|
|
79
|
+
|
|
80
|
+
编写中、就绪、保存和丢弃等 chrome 从结构化事实在渲染时通过 `settings.ptcPlus` 翻译,已有回执随 locale 切换。Host admission 只返回 `kind: success`,非 GUI consumer 仍能观察成功结算;历史成功 text 不参与状态渲染。原始错误、用户需求与候选源码保持原文。
|
|
81
|
+
|
|
82
|
+
`enhancedToolView` 默认开启并即时生效。开启时 PTC Plus 通过公共 keyed tool-view surface 为 `run_code` 与 `edit_run_code` 提供增强行,并在可用时使用 DSH 公共 `DisclosureRow`/`CodeBlock` primitive,缺少某项 capability 时使用插件自有的等价降级;关闭时立即注销这两个 keyed view,由 DSH 原生 generic row 负责布局、状态、代码高亮和输入/输出卡片。该开关只影响 Client 展示,不改变工具、prompt、runtime 或 session 语义。composer 星光入口使用公共 `Menu`、`Tooltip`、`Toast`、`Modal` 和 `IconSparkle16`;设置窗口复用设置卡片的完整表单与写入 callback,星光菜单的“修改绑定”第二步继续使用同一公共 `Menu` 的条目、滚动与键盘语义。缺失 `IconSparkle16` 时降级为纯文本按钮,缺失 `Toast` 时使用插件自有的内联状态提示;缺失 `Tooltip` 时悬浮说明由原生 `title` 承载。
|
|
33
83
|
|
|
34
84
|
`autoDescribeRunCode` 的设置名称是“允许执行缺少摘要的 run_code”,默认开启并即时生效。缺少外层 `run_code.description` 时,调用使用派生参数通过本地 DSH 校验,备用摘要仅进入 presentation metadata;关闭时由 DSH 校验原始参数。两种状态的模型请求保持字节稳定并包含 required `description`,原始调用参数、已有摘要、cell 源码和嵌套 native 工具参数保持不变。
|
|
35
85
|
|
|
36
|
-
设置卡片、正文 tool view 与 REPL 可复用 binding 卡片的全部文案都注册到 DSH client locale 的 `settings.ptcPlus` 命名空间,随当前界面语言在中文与 English 之间切换;字段名称与说明的两种语言文本同样来自 `internal/config-spec.js`(`label`/`labelEn`、`description`/`descriptionEn`,某一字段的说明要么两种语言都有,要么都没有),展示 chrome 文案由 client half 拥有。稳定 REPL 指引不承载 UI 品牌名。启用且会话选择 `ptc` 或兼容的 `code` preset 时,`conversation.session.header.actions` 以稳定 id `ptc-plus-active` 显示简洁的 `PTC Plus`
|
|
86
|
+
设置卡片、正文 tool view 与 REPL 可复用 binding 卡片的全部文案都注册到 DSH client locale 的 `settings.ptcPlus` 命名空间,随当前界面语言在中文与 English 之间切换;字段名称与说明的两种语言文本同样来自 `internal/config-spec.js`(`label`/`labelEn`、`description`/`descriptionEn`,某一字段的说明要么两种语言都有,要么都没有),展示 chrome 文案由 client half 拥有。稳定 REPL 指引不承载 UI 品牌名。启用且会话选择 `ptc` 或兼容的 `code` preset 时,`conversation.session.header.actions` 以稳定 id `ptc-plus-active` 显示简洁的 `PTC Plus` 标识;视口不超过 560px 时隐藏该可选标识,为原生页头操作留出空间,会话绑定继续从 REPL 页签访问。preset 与 binding inventory 优先读取 session slot 的公共 `useProjection`;只有 preset 在缺少 projection 时可读取旧宿主公开会话摘要,binding inventory 不回退。关闭时不注入任何 PTC 指引或工具 surface。
|
|
37
87
|
|
|
38
|
-
绿色 `PTC Plus`
|
|
88
|
+
绿色 `PTC Plus` 活动标识支持鼠标悬浮、键盘聚焦和点击:悬停停留 150ms 的意图延迟后展开,指针离开触发器与卡片 200ms 后关闭,该宽限把指针从触发器带进卡片,回到其中即取消;点击可固定卡片、再点一次关闭,从而点击打开的卡片与键盘聚焦打开的卡片都不随指针离开而关闭;点击别处关闭,Escape 关闭并把焦点还给标识。因此页头里扫过的指针不会留下悬浮卡片。卡片通过浏览器 Popover top layer 脱离普通 stacking context,按触发器和当前视口的可用空间在上方或下方定位,因此不受会话侧栏覆盖;长列表只在卡片内部滚动,滚动只按动画帧重算一次定位。卡片展开只按打开动作读取全局目录,不轮询;切换到全局页签时重新读取一次。变量、函数、类和导入使用可区分的类型色彩。卡片通过标准 `useProjection("ptcPlusRepl")` 读取公共 session projection,展示当前 runtime owner 已证明可供该 agent 后续 cell 复用的 binding 名称、类别、单行定义预览、原始行列,以及该身份被后续 cell 复用的次数;卡片摘要同时给出同一口径的总复用次数。点击整行即可在卡片内展开有界 TypeScript 声明源码,并以抽屉式过渡动画显示。候选来源由 AST preparation 从 cell 文本确定,BindingCatalog 只按实际提交的声明和写入更新定义;重放沿用相同执行证据。赋值即使不改名,也可能改变定义来源,使旧 inventory 的观察请求失效。来源更新不读取值、不执行代码、不触发 getter。Host 在每个结算结果的并行私有 `meta.dshPtcPlusBindings` envelope 中写入 runtime generation 和完整的 value-independent inventory;最多携带 128 项、名称最长 128 字符、每段声明源码至多 1024 个 UTF-16 code unit、声明源码合计至多 16384 个 code unit,同时保留精确有效总数和省略数。volatile cell 的 live binding 只在其精确 provenance 仍属于模型可见 state frontier 时继续显示;restore、discarded settlement 或 model-visible surface contraction 会收缩 worker,在后续 cell 重新物化有效 binding surface 前显示不可确认。
|
|
39
89
|
|
|
40
90
|
清单按最近声明或重声明优先的栈顺序排列,同一 cell 内靠后的声明位于靠前声明之上。BindingCatalog 保留这个顺序,presentation snapshot 和 projection 原样传递,不根据名称重新排序。
|
|
41
91
|
|
|
@@ -43,9 +93,31 @@ Host half 通过 DSH 公共 `settings` 服务注册命名空间 `ptc-plus`。字
|
|
|
43
93
|
|
|
44
94
|
`enhancedToolView` 开启且插件启用时,Client 通过公共 keyed `tool.call.toolview` 注册 `run_code` 与 `edit_run_code`;任一开关关闭时实时 dispose 两个注册,让 owner 恢复 DSH 原生 fallback。这个正文 slot 只依赖 Host 提供的 key、`toolName`、`sessionId`、`useSessions`、运行中/已结算 `block` 与 `inspect` 公共契约。增强行保留 Code / Code edit 标题、可展开的原始源码(`arguments` 与 `argsRaw` 任一公共形态均可读)、结果、可见且可访问的运行/失败/中断状态和 Inspect 入口;在提供时优先使用公共 `DisclosureRow` 与 `CodeBlock`,缺少 `DisclosureRow` 时回退到插件自有行,缺少 `CodeBlock` 时回退为纯文本源码。`DisclosureRow` 路径把运行/失败/中断状态、摘要和已证明的功能标记放进同一行始终可见的单行预览;完成态由标题与摘要表达,运行/失败/中断状态由文字 chip 承担并保持可访问。预览间距由插件自有类对称提供,并按单行内容布局,不依赖 Host primitive 的行内几何;源码、结果和 Inspect 只出现在展开主体。结果内容与原生 ioCard 采用相同的灰色圆角背景(`--dsw-alias-markdown-code-block` 加 12px 圆角与边框),失败态使用错误色文字;代码块的语言/复制栏保持原生 CodeBlock 的常亮可见;`检查调用` 入口采用原生 inspectButton 同款胶囊样式,默认 opacity 0,仅在卡片 `:hover` 或 `:focus-visible` 时淡入(opacity .1s),不触发任何布局位移。窄屏下回退路径的摘要允许换行。
|
|
45
95
|
|
|
46
|
-
功能标记不是计数,也不把“插件已启用”冒充成一次功能收益。Client 只在完整 v1-
|
|
96
|
+
功能标记不是计数,也不把“插件已启用”冒充成一次功能收益。Client 只在完整 v1-v9 journal 和对应附属 metadata 能证明时显示:自动改写 import(附模块名)、自动剥离 export、自动拆分混合重声明(附已有 binding)、带完整 target/derived-run/non-noop/可选恢复边界关系且与调用目标前置条件一致的安全编辑执行、成功的 `code.run`、由 `PTC-R002` 的 `warning/recover/rolled-back` 语义元组证明本次确实发生的持久重放,以及 `repl.state` 操作。Client 对 v4 同时封闭校验 `bindingPolicy`、`rewritePolicy` 与 `moduleSemantics`,对 v5 还要求 `userBindingsFingerprint`,对 v6 进一步要求 `userBindingsReusePolicy` 为 `fingerprint-v1` 或 `implementation-v1`,对 v7 还要求 `moduleSemantics` 携带可识别的 `importExpressionBoundary`(v1-v6 的 `moduleSemantics` 保持只含 `defaultExportBinding` 的封闭字段集),对 v8 还要求 `userBindingsShadowPolicy` 与 `userBindingNames` 通过封闭校验,对 v9 进一步要求已知的 `languageSemantics`;任一缺失或畸形都不产生功能标记。进程保留或 discarded 状态不作为正文功能标记。普通变量或 function/class 重声明、顶层 native 调用是否来自 canonicalizer、`cordis_*` 成员是否由官方可选 Cordis mount 提供,以及是否实际选择了 prompt 恢复提示没有独立的 Client-only 事实,因此不根据可复制的代码形状、工具名前缀或设置默认值推测;恢复边界本身不展示。
|
|
97
|
+
|
|
98
|
+
正文工具行和头部 Session 清单不检查或改写宿主 DOM,不调用 Host、不主动加载历史。头部卡片只展示随结果持久化的名称与定义源码,不使用值预览;全局管理操作单独使用前述管理 Remote。这些展示不改变 canonical result、tool schema、system prompt、runtime context、journal schema 或迁移器,也不向模型公开状态。未知 journal 版本、未知 metadata 字段和损坏 metadata 只会让对应功能标记或 binding 列表缺席,不会隐藏源码或结果;无法脱离 session call identity 解析非空 v1 `confirms` 时同样只省略标记,不触发历史读取或迁移。因此 UI 是否安装、能否渲染以及用户是否悬浮、聚焦或展开正文行,都不会改变模型请求或会话继续语义,也不能作为在模型 surface 收缩后继续保留 runtime binding 的证据。
|
|
99
|
+
|
|
100
|
+
## REPL 顶级页签
|
|
101
|
+
|
|
102
|
+
Client 通过公开 `conversation.view` 注册 `ptc-plus-repl`(标签 `REPL`,order 20),与对话、轨迹同级。注册作用域订阅 `sessions.list` 的当前会话及其 `agentPreset` projection face:插件与 `replViewEnabled` 开启且当前 preset 为 `ptc` 或 `code` 时注册,其余情况注销。会话切换、preset 改变、设置关闭和 provider/plugin 释放都会清理对应订阅与注册。DSH 拥有页签选择与注销后的回退;列表属于当前 browser Client,插件不创建多会话导航器。空会话的页签可见性仍由宿主 shell 决定。
|
|
103
|
+
|
|
104
|
+
REPL 根元素使用官方轨迹页同样的 `data-conversation-composer-overlay` 布局标记,由宿主提供满高视口并禁用对话宽度拖拽条;工作区内部滚动。仅在该页挂载期间,通过公开 `conversation.composer` chain 注册当前 session 专属的空替代项,隐藏普通消息输入框。宿主 overlay 保留原输入框与草稿,离开 REPL、关闭插件或释放 provider 时恢复。存在 `pendingInteraction` 时替代项不参与选择,审批、提问等宿主交互保持优先。插件不查询或改写宿主 DOM,不覆盖宿主 CSS。
|
|
105
|
+
|
|
106
|
+
REPL 是单页工作区,上方为“会话绑定”,下方直接展示完整“全局绑定”工作台,不设内部页签。会话区使用紧凑表格和相邻的绑定检查区;名称为普通等宽文字,类别为文字列。名称搜索与类型筛选只过滤已有展示清单,不请求更多观察数据;清单保留来源顺序,默认检查首个匹配条目。选中条目的定义、行列和值在检查区展示,定义使用公共 `CodeBlock` 的 TypeScript 高亮与复制按钮,缺少该原语时降级为原文。长清单在固定高度区域内滚动,窄屏将清单、检查区、全局目录和编辑器纵向排列;筛选或检查会话绑定不会重置全局编辑区。
|
|
47
107
|
|
|
48
|
-
|
|
108
|
+
“会话绑定”使用 `useProjection('ptcPlusRepl')` 展示名称、类别、定义源码、原始行列、复用次数和有界值预览,区块标题同时给出总复用次数。`dshPtcPlusBindings` metadata v5 与 projection state v5 在来源清单上增加每项 `reuseCount` 与顶层 `reuseTotal`,并保留可选 `observation`;v3/v4 metadata 仍可读,缺失的复用计数按 0 恢复。复用次数按 cell 编译后源码中的静态引用累计:一次结算 cell 对同一身份至多计一次,重声明、普通赋值与 `delete` 不计,执行未到达的引用仍计;`legacy-v1` 历史 cell 不提供引用事实,因此不计入。复用计数只属于 UI presentation,不是恢复证据,也不进入模型上下文。观察时间位于区块标题旁,值的截断状态标在对应预览旁,无法安全观察的值显示“不可读取”,尚无观察结果则显示“尚未观察”。定义仍为已记录的有界源码片段,复制只复制当前片段,不补读历史或执行代码。预览不表示完整快照,后续异步变化不会自动刷新这份观察。
|
|
109
|
+
|
|
110
|
+
空清单或恢复后暂无清单时只显示紧凑的全宽空状态,不保留空的表格与检查区。会话观察区通过 IntersectionObserver 和文档可见性持有公开 Remote `ptcPlusRepl.invoke` 的可取消 `watch` 请求,Host 最多接受 64 个观察订阅。只有 live cell 分派时仍有该 session 的可见订阅,才发送结算后的值观察名称。请求意外结束时清理该请求,并在仍可见时按 1、2、4 秒间隔最多重试三次;达到上限后停止计时,后续可见性或连接生命周期变化可重新尝试。区域离开视口、文档隐藏、连接替换、关闭页签开关或 provider 释放都撤销订阅和待重试计时器,旧请求结束不能撤销新请求。
|
|
111
|
+
|
|
112
|
+
清单可见但没有观察时,同一宿主认证的 Remote 通过 `observe` 请求一次有界读取。只接受现存、已结算且 surface generation 未改变的 worker,并校验请求清单与当前 binding catalog 一致;不启动 worker、不执行 cell、不恢复或重放历史。请求与 cell 共用队列及 readiness 握手,连同排队最多等待 250 ms。Host 最多接受 64 个按需请求,同一 worker 有活动读取时不再增加读取。结果只保存在对应 Client 清单的局部展示状态,不回写 metadata、projection 或日志;清单变化、取消及过期响应均不能恢复旧预览。不存在后台轮询。
|
|
113
|
+
|
|
114
|
+
新代际从 `stateful-root-runtime.js` 已提交的普通本地值生成预览,不执行来源 getter,也不为观察读取 import、关联 alias 或 ambient accessor。即使 cell 后续失败,已经成功提交的本地声明与实际写入仍可由最终 catalog 证明。旧原生 storage 继续通过 Acorn 分析成功执行的 lowered program:`var` 只读取 REPL context 的自有 data descriptor,`let`/`const` 通过有界 `vm.runInContext` 读取已证明的裸标识符,lexical storage 优先于同名全局属性。worker 启动时探测 await 程序的真实 lexical storage;失败只降级该旧路径的预览,不阻断执行。未证明名称不借用同名全局属性。值观察不调用 REPL evaluator、不改变最后求值结果、不开放调试连接。`node:util.types.isProxy` 在反射前排除 Proxy,包括 revoked Proxy;只预览有界原始值与数组的前五个自有槽,不触发 getter、原型读取、`toJSON` 或自定义 formatter。函数、Symbol、普通对象、模块 namespace 和无法证明 storage 的名称显示不可读取。
|
|
115
|
+
|
|
116
|
+
最多观察 128 个名称,每项文本最多 512 个 UTF-16 code unit。数组只按固定索引读取前 5 个自有槽位,空槽明确标识,嵌套值不展开;额外自有属性未被检查,因此即使短数组也保留不完整标记。除数组外的对象统一显示不可读取,包括普通对象、TypedArray、Buffer、String 包装对象和模块 namespace;预览不枚举任何值的完整属性集合。普通字符串提供有界文本预览;BigInt 在转换前比较固定范围,至多输出 128 位,超限只显示有界提示。Worker 在 100 ms 后停止新的 lexical read,单项 VM 读取上限为 25 ms。Host 最多等待 250 ms,随后显示没有预览的已结算结果。
|
|
117
|
+
|
|
118
|
+
执行 `done` 与后续 `observation` 是独立的私有消息。待观察名称先由 `createReplMemorySnapshot` 按展示清单的名称、定义来源、条目数量和源码总预算筛选,被省略的 binding 不占用观察名额,也不影响其他条目的预览。Host 先结束 cell 的计算预算、lease 与 journal 结算,再接收可选预览;遗漏、迟到或畸形预览不改变执行结果,不触发 worker 重启。预览按最终 catalog 的名称过滤,只附加到私有 UI metadata,不进入模型上下文、canonical value 或 journal,不作为 replay 或保留隐藏 binding 的证据。cold replay 不采集历史观察,restore/discarded 与原有 generation、模型可见 frontier 失效规则共用。完整边界见 [ADR 0024](adr/0024-repl-console-observation.md)。
|
|
119
|
+
|
|
120
|
+
250 ms 只是等待可选预览的上限,不表示 worker 已就绪。下一 cell 先经私有 `prepare` / `ready` 握手,匹配的首次 `ready` 才派发代码。`computeMs` / `maxWallMs` 预算通常在发送 `prepare` 前启动;仅同一 worker 已确认开始且尚未完成的观察暂缓计时,直到收到该观察的完成消息或匹配的 `ready`。按需读取通过 `observation-started` 确认,发送请求本身不提供预算豁免;迟到确认不能暂停或重置已经启动的预算。观察身份独立于 250 ms 的展示等待记录。等待期间仍可取消,并保留 session disposal 与 worker failure 的处理;过期、畸形或重复的就绪消息不能启动额外执行。后台用户回调造成的非观察阻塞仍会正常超时和重置 worker。
|
|
49
121
|
|
|
50
122
|
live 配置若因宿主能力缺失或 runtime 安装/重配置失败,会先回滚所有已创建或更新的 owner,再把持久设置回写为上一次已应用值;回滚写入失败时 Host 记录 activation diagnostic,避免静默把配置显示成不存在的 runtime。
|
|
51
123
|
|
|
@@ -57,7 +129,11 @@ live 配置若因宿主能力缺失或 runtime 安装/重配置失败,会先
|
|
|
57
129
|
npm run build
|
|
58
130
|
```
|
|
59
131
|
|
|
60
|
-
`package.json` 声明 `dsh.client` 与 `./client` export
|
|
132
|
+
`package.json` 声明 `dsh.client` 与 `./client` export,并声明当前公共 UI 模块的依赖图。`npm run build` 从 `src/client.js` 生成 `client.js`,`npm run build:check` 比较确定性产物;`prepack` 会阻止陈旧 bundle 发布。
|
|
133
|
+
|
|
134
|
+
`npm run test:client` 使用 DSH 发布的 Cordis、SlotTestRuntime、renderer 和 conversation registry/assembler 验证激活、Location 关联、响应式更新和释放。产物测试(`test/client-bundle.test.js`)只断言构建产物契约:可加载、公开 slot 与 entry 身份、依赖边界和检出换行属性;它不读取 `src/client.js`,也不断言源码写法、CSS 数值或文案字面量,界面行为归运行测试。测试 loader 只适配发布的 ModuleLoader 格式,并为上游 test-runtime 缺失的两个源码引用暴露同一发布 renderer 的函数,不复制其行为。打包后的浏览器启动另由 `npm run test:client:web` 验证,前置条件与命令见 [安装指南](installation.md)。
|
|
135
|
+
|
|
136
|
+
`npm run test:client:layout -- --browser-channel msedge` 从真实 Client renderer 生成包含公共 Button/CodeBlock/Modal 和 CodeMirror CSS 的固定视图,再用 Playwright 检查 320、390、1440 px viewport 下的长中英文条目、58 条会话绑定、横向溢出、控件矩形与折叠区,包含 REPL 观察区、完整工作台和设置弹窗。截图和测量保留在 ignored `artifacts/binding-layout/`。这是几何与原生 details 验收;筛选、选中、编辑撤销、RPC、冲突、页签生命周期和 locale 行为由 `test:client` 执行,真实编辑器高亮、键盘操作、保存、宿主布局和主题由 `test:client:web` 执行。
|
|
61
137
|
|
|
62
138
|
## 回退
|
|
63
139
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## 状态
|
|
4
4
|
|
|
5
|
-
本文拥有 `dsh-ptc-plus` 的 journal、两阶段确认和冷恢复契约;`internal/session-journal.js`
|
|
5
|
+
本文拥有 `dsh-ptc-plus` 的 journal、两阶段确认和冷恢复契约;`internal/session-journal-schema.js` 拥有封闭字段集合与版本常量,`internal/session-journal.js` 拥有校验、迁移与创建,`internal/session-journal-recovery.js` 拥有事件关联与分支折叠,`internal/session-runtime.js` 拥有 live kernel;它们提供实现证据。
|
|
6
6
|
|
|
7
7
|
## 恢复承诺
|
|
8
8
|
|
|
@@ -26,11 +26,12 @@ PTC Plus 的正确承诺是:
|
|
|
26
26
|
|
|
27
27
|
## Journal
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
每个进入执行缝的 cell 创建 mutable tentative journal:
|
|
30
30
|
|
|
31
31
|
```ts
|
|
32
32
|
{
|
|
33
|
-
version:
|
|
33
|
+
version: 9,
|
|
34
|
+
languageSemantics: "legacy-v1" | "stateful-v1" | "protected-v1",
|
|
34
35
|
bindingPolicy: {
|
|
35
36
|
variableRedeclarations: boolean,
|
|
36
37
|
functionClassRedeclarations: boolean
|
|
@@ -41,8 +42,15 @@ PTC Plus 的正确承诺是:
|
|
|
41
42
|
autoSplitRedeclarations: boolean
|
|
42
43
|
},
|
|
43
44
|
moduleSemantics: {
|
|
44
|
-
defaultExportBinding: "legacy-variable" | "live-readonly"
|
|
45
|
+
defaultExportBinding: "legacy-variable" | "live-readonly",
|
|
46
|
+
importExpressionBoundary: "legacy" | "statement-safe"
|
|
45
47
|
},
|
|
48
|
+
userBindingsFingerprint: string | null,
|
|
49
|
+
userBindingsReusePolicy: "fingerprint-v1" | "implementation-v1",
|
|
50
|
+
userBindingsShadowPolicy: "whole-entry" | "per-name",
|
|
51
|
+
userBindingNames:
|
|
52
|
+
| { name: string, state: "provider" | "local" | "absent" | "unknown", entryId?: string }[]
|
|
53
|
+
| null,
|
|
46
54
|
status: "durable" | "volatile" | "discarded" | "noop",
|
|
47
55
|
calls: CapabilityCall[],
|
|
48
56
|
operations: StateOperation[],
|
|
@@ -59,9 +67,14 @@ PTC Plus 的正确承诺是:
|
|
|
59
67
|
字段含义:
|
|
60
68
|
|
|
61
69
|
- `durable`:创建可重放 node,推进 `durableHead`;
|
|
70
|
+
- `languageSemantics`:固定完整语言代际;新统一策略选择 `stateful-v1` 或 `protected-v1`,显式旧设置兼容态与 v1–v8 历史使用 `legacy-v1`。冷重放从该字段选择编译路径,不用当前配置替换历史声明、闭包和初始化语义;
|
|
62
71
|
- `bindingPolicy`:记录该 cell 实际采用的变量重声明和 function/class 重声明语义;冷重放读取每个 node 的完整记录值,并用它重建 binding 可写性,不读取恢复时的 profile 配置;
|
|
63
72
|
- `rewritePolicy`:记录该 cell 解析和 lowering 时使用的三个 AST rewrite 开关;冷重放读取每个 node 的记录值,不读取恢复时的 profile 配置;
|
|
64
|
-
- `moduleSemantics
|
|
73
|
+
- `moduleSemantics`:保留旧模块 lowering 的独立代际;`legacy-v1` 按记录值恢复 default binding 与模块引用写入的语句边界。当前 live cell 写入 `live-readonly` 与 `statement-safe`,但新语言的可写 alias、default 关联和提交规则由 `languageSemantics` 决定,不能仅凭历史字段中的 `readonly` 推断当前 binding 不可写;
|
|
74
|
+
- `userBindingsFingerprint`:`null` 明确表示该 cell 没有 Global User Binding 快照;SHA-256 值要求最终 result 同时携带 fingerprint 一致的私有快照,缺失或不一致时形成 unknown boundary;
|
|
75
|
+
- `userBindingsReusePolicy`:记录全局绑定模块的复用代际;新 cell 写入 `implementation-v1`,按执行输入复用模块,历史 `fingerprint-v1` 则按完整条目指纹复用,保留仅修改说明或顶层显示名称时发生的初始化;
|
|
76
|
+
- `userBindingsShadowPolicy`:记录该 cell 的 session-local 覆盖粒度;新 cell 写入 `per-name`,只有同名 session-local binding 覆盖对应全局名称,同条目的其他名称继续激活;v1-v7 迁移的历史 node 写入 `whole-entry`,保留整条来源条目退出后续全局激活的语义;该粒度与 `userBindingsReusePolicy` 相互独立;
|
|
77
|
+
- `userBindingNames`:`per-name` 且 status 非 `noop`/`discarded` 时记录该 cell 结算时按名称排序的事实,state 为 `provider`、`local`、`absent` 或 `unknown`,provider 事实另带 `entryId`,必须对应并行快照的条目并覆盖快照公开的每个名称;`whole-entry`、`noop` 与 `discarded` node 为显式 `null`;
|
|
65
78
|
- `volatile`:只推进 live heap,不推进 `durableHead`;
|
|
66
79
|
- `discarded`:基础设施失败,calls 和 operations 必须为空;若中止时仍有未结算的 program binding call,则以首个 `global.member` 保留 `volatileReason`,恢复时不能把这个 possible-effect boundary 折叠为 no-op;
|
|
67
80
|
- `noop`:程序未执行,calls 和 operations 必须为空;
|
|
@@ -79,7 +92,7 @@ SessionRuntime 创建 kernel 时完全忽略历史 nodes、head、checkpoints
|
|
|
79
92
|
|
|
80
93
|
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-与恢复)。
|
|
81
94
|
|
|
82
|
-
当前实现只写入 `version:
|
|
95
|
+
当前实现只写入 `version: 9` schema。v9 必须携带 `languageSemantics`,其值为 `legacy-v1`、`stateful-v1` 或 `protected-v1`;v1–v8 固定迁移为 `legacy-v1`,由冻结历史编译器重放,不能因当前配置或新 lowering 改变隐藏状态([ADR 0025](adr/0025-use-versioned-logical-binding-identities.md))。v1-v8 作为封闭 predecessor 输入规范化为 v9:v1-v3 的旧 `bindingMode` 精确映射到 `bindingPolicy.variableRedeclarations`,而 `functionClassRedeclarations` 固定为 `false`,因为旧 pipeline 不具备该语义;`moduleSemantics.defaultExportBinding` 固定迁移为 `legacy-variable`,使 loose 历史保留旧的可写生成 binding、strict 历史保留旧的 const 行为;v1-v6 的 `moduleSemantics.importExpressionBoundary` 固定迁移为 `legacy`,使历史写入沿用其记录时的语句 lowering,v7 保留自身记录的边界代际。v1 仍使用三个 rewrite 开关全关的历史默认值,并只在 session log 唯一证明 call identity 时迁移字符串 confirmation;v2/v3 保留自身 `rewritePolicy`。v4/v5 保留已有 binding/rewrite/module 语义;v6 与 v7 保留其记录的 `userBindingsReusePolicy`。v1-v4 的 `userBindingsFingerprint` 固定为 `null`,v5 及之后的代际保留自身记录的快照指纹;v1-v5 的 `userBindingsReusePolicy` 固定为 `fingerprint-v1`。v1-v7 的 `userBindingsShadowPolicy` 固定迁移为 `whole-entry`,`userBindingNames` 固定为 `null`,因此历史 node 继续按整条条目退出,只有 v8 起的 cell 使用 `per-name` 名称证据。无法表示为非负 event sequence 的 confirmation 必须形成 unknown boundary 并触发状态收缩。包括 `languageSemantics`、`bindingPolicy`、`rewritePolicy`、`moduleSemantics`、`userBindingsFingerprint`、`userBindingsReusePolicy`、`userBindingsShadowPolicy`、`userBindingNames`、`diagnostics` 在内的当前必需字段缺失或策略未知时 journal 必须失效,否则会削弱最终持久值与 tentative journal 的严格一致性确认;失效 journal 不证明旧 binding,但也不单独成为后续当前调用的 availability gate。profile 后续切换任一 binding 或 AST rewrite 开关只影响新 cell,历史 node 始终按自身记录的 policy 和 module semantics 重放。新旧全局绑定复用策略与覆盖粒度可共存于同一历史,重复规范化不能把旧策略或旧粒度升级为当前值;没有返回值的 completion 不能证明模块内部状态相等。
|
|
83
96
|
|
|
84
97
|
## Capability Call Transcript
|
|
85
98
|
|
|
@@ -114,7 +127,7 @@ pre-execute -> tools/execute -> post-execute
|
|
|
114
127
|
插件采用:
|
|
115
128
|
|
|
116
129
|
1. `tools/execute` 保存 execution 对象与 session context;
|
|
117
|
-
2. `
|
|
130
|
+
2. 执行缝的 `run` 真正进入 kernel 时创建 tentative journal;
|
|
118
131
|
3. 成功结果由 `presentationMeta` 投影 journal,失败结果由 around hook 附加;
|
|
119
132
|
4. `tools/result` 规范化最终 `meta.dshPtcPlus` 与 runtime tentative journal;
|
|
120
133
|
5. 两者语义完全相同时确认 tentative 状态;
|
|
@@ -237,7 +250,7 @@ state: ...
|
|
|
237
250
|
help: ...
|
|
238
251
|
```
|
|
239
252
|
|
|
240
|
-
|
|
253
|
+
通知进入正常执行缝 logs,结构化值进入当前 journal,因此成功结果和错误结果都能呈现并从 session log 重建。收缩边界随当前 result 持久化,后续 cold start 从新分支恢复,不重复撞击同一损坏历史;每个 kernel 只发送一次,避免污染后续上下文。
|
|
241
254
|
|
|
242
255
|
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。
|
|
243
256
|
|
|
@@ -251,6 +264,8 @@ live kernel 首次进入 volatile 只更新 journal 的 `status` / `volatileReas
|
|
|
251
264
|
- 冷恢复丢弃不可信后缀使用 `rolled-back`;
|
|
252
265
|
- 只有已知外部 dispatch 发生但 completion 无法确定时才使用 `unknown` 并附 `dispatchState: "unknown"`,插件不得在宿主未提供该事实时猜测。
|
|
253
266
|
|
|
267
|
+
`PTC-N001` collision 诊断另带 `collisions`:每条记录为 `{name, kind, reason, start, end}`。`reason` 由判定冲突的编译器 owner 记录(`reserved-program-binding-not-shadowable`、`protected-root-redeclaration`、`import-binding-redeclaration`、`redeclaration-splitting-disabled`,以及既有的重声明策略值),渲染只消费已记录的原因,不从请求描述符重新推导保留名或保护策略。
|
|
268
|
+
|
|
254
269
|
模型可见文本与 `diagnostics` 必须由同一个结构确定性生成。恢复不通过解析既有 message 重建诊断;session export/import 和 replay 均保留结构化 code、cause、dispatch state 与 state effect。源码 frame 使用 `@babel/code-frame` 的无色投影。
|
|
255
270
|
|
|
256
271
|
## 插件边界
|
|
@@ -259,8 +274,8 @@ live kernel 首次进入 volatile 只更新 journal 的 `status` / `volatileReas
|
|
|
259
274
|
|
|
260
275
|
- `tools/execute`;
|
|
261
276
|
- `tools/result`;
|
|
262
|
-
- `
|
|
263
|
-
-
|
|
277
|
+
- 执行缝的 `run`;
|
|
278
|
+
- 当前执行缝 request 的 public bindings 与 signal;
|
|
264
279
|
- `run_code.output.presentationMeta`;
|
|
265
280
|
- 标准 `tool/call` 与 `tool/result.meta`。
|
|
266
281
|
|
package/docs/evaluation.md
CHANGED
|
@@ -4,7 +4,26 @@
|
|
|
4
4
|
|
|
5
5
|
The model-backed runners support native Windows paths and WSL repositories mounted as `/mnt/<drive>/...`. They invoke the Windows DSH installation through `pwsh.exe`; the Windows process environment must resolve `dsh --version` and a drive-qualified `DSH_HOME` or user-profile `.dsh` directory. Native Linux and macOS DSH execution are not supported by these runners.
|
|
6
6
|
|
|
7
|
-
Both entrypoints validate path conversion, PowerShell startup, the installed DSH command, and the Windows DSH home before creating artifacts
|
|
7
|
+
Both entrypoints validate path conversion, PowerShell startup, the installed DSH command, and the Windows DSH home before creating evaluation artifacts or installing the development plugin. A public Node preload runs a keyless real-worker probe before the DSH version command: it checks persistent bindings, syntax rejection, synchronous and awaited exceptions, and explicit return. The probe owns and cleans its worker scratch directory. A failure uses `PTC-EVAL-PREREQ` and prevents model work.
|
|
8
|
+
|
|
9
|
+
The actual `process.version`, `process.execPath`, DSH JavaScript entry, and observed release are recorded in manifests; subsequent DSH invocations use that exact Node executable and entry. Do not launch a probe through `npm exec node`, which can resolve a different runtime. The release is evidence, not a behavior selector or compatibility gate. Keep the selected installation and repository DSH dependencies current.
|
|
10
|
+
|
|
11
|
+
## Configuration Preflight
|
|
12
|
+
|
|
13
|
+
Model-backed evaluation requires explicit authorization and an explicit provider, model, and credential-variable name. Run it in an isolated DSH home and workspace. Resolve the selected provider from the user's existing DSH configuration, then copy only its validated API, endpoint, model list, and provider-specific routing fields into the isolated settings. Keep the credential variable name unchanged and let the child process resolve its value from the inherited environment; never read, print, serialize, or store credential values.
|
|
14
|
+
|
|
15
|
+
Generate a fresh routing/session header for providers that require one, and use the same resolved provider configuration for every comparison arm. If the normal profile lacks a required provider field, repair the isolated copy or use the repository's existing isolated audit driver. Do not weaken the provider check or edit the normal profile.
|
|
16
|
+
|
|
17
|
+
After configuring the selected runner's route, set its configuration-only variable to `1` before invoking the command:
|
|
18
|
+
|
|
19
|
+
| Command | Configuration-only variable |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| `npm run test:expensive` | `DSH_PTC_ACCEPTANCE_CONFIG_ONLY` |
|
|
22
|
+
| `npm run test:ab` | `DSH_PTC_AB_CONFIG_ONLY` |
|
|
23
|
+
|
|
24
|
+
Each runner reads its own configuration-only variable; the names are not interchangeable. When that variable is set to `1`, the runner returns after its isolated configuration checks. Preflight may create local artifacts and isolated configuration; it does not invoke the model. A successful preflight establishes configuration readiness, not model behavior or semantic correctness. Remove the configuration-only setting only when proceeding to the explicitly authorized paid run.
|
|
25
|
+
|
|
26
|
+
Inspect only redacted session-log and report artifacts, and record model usage without request headers or credential material. Both commands invoke the configured model and consume quota when run without their configuration-only setting.
|
|
8
27
|
|
|
9
28
|
## Stable ordinary-task A/B fixture
|
|
10
29
|
|
|
@@ -27,7 +46,7 @@ The paired run uses the latest installed DSH release, a configured model, PTC mo
|
|
|
27
46
|
|
|
28
47
|
Resolved configurations are identical except for `ptc-plus.disabled`. Agent instructions, skills, auxiliary title generation, and local identity extensions are disabled. The model route, permission mode, neutral persona, injected initial context, fixture bytes, and resolved tool surface stay paired within each run.
|
|
29
48
|
|
|
30
|
-
The
|
|
49
|
+
The shared overlay selects `tools.mode: ptc` and explicitly projects `sandbox-policy.mode` and `approval.policy`. Before any model work, both runners validate the resolved tools row with the public `ToolRuntime.Config` schema from `@deepseek-ai/dsh-tools`, then check the selected evaluation policy. A successful config dump alone does not validate plugin settings; agreement with a runner-supplied expected string cannot bypass the Host schema. `CONFIG_ONLY` also performs this zero-model schema check. The runners do not rely on child-process environment variables to project these policies across the WSL-to-Windows execution boundary.
|
|
31
50
|
|
|
32
51
|
Each arm executes in an independently named, opaque scratch tree outside the evaluator artifact tree. Treatment names are confined to evaluator-owned records. Blind packets replace the session workspace in descriptions, source, results, and final answers, including Windows, forward-slash, and JSON-escaped spellings, before the arm map is written.
|
|
33
52
|
|
|
@@ -39,24 +58,77 @@ Acceptance metrics follow durable session-log semantics. `modelRequests` counts
|
|
|
39
58
|
|
|
40
59
|
Stable-header acceptance canonicalizes empty fields by DSH rules and compares the exact system value and ordered complete tool-schema JSON across every header epoch. Any unapproved change fails with the first differing field. `headerPolicy.allowedTransitions` names the exact epoch and route, configuration, or capability condition; `headerPolicy.historyReplacements` declares an exact replacement count and never permits header drift. Hashes remain diagnostic report data rather than the correctness test.
|
|
41
60
|
|
|
61
|
+
The shared Host contract recognizes `series` as an unchanged request header beginning a distinct message series, not a new schema or an inferred provider call. Usage evidence supports both historical standalone `assistant/chunk` events and compact streams in `assistant/message` or `assistant/attempt`. An embedded stream's last usage agrees with its message's accounting; formally linked duplicate storage is counted once, conflicting evidence fails, and reported usage from attempts without a surface message remains part of quota consumption. Logical steps, header epochs and physical attempts remain distinct. Missing usage is not a zero-cost claim.
|
|
62
|
+
|
|
63
|
+
Runtime-context audits track the binding catalog independently of recovery snapshots. They detect unchanged binding text repeated inside an otherwise changed snapshot, while allowing one reassertion after a formal surface replacement removed its evidence. Model-authored ambient declarations are not plugin catalog injections.
|
|
64
|
+
|
|
65
|
+
### Focused Program Work
|
|
66
|
+
|
|
67
|
+
The typed program-surface descriptor owns `expect.programWork`: `inspectionSymbols` limits schema expansion, and each `callLimits` entry declares a namespace/member's `maxCalls` and optional `maxCallsPerArguments`. Counts include unsuccessful calls. The fixed fixture is immutable during this task, so its native read is limited to one observation; the parent passes the observed marker into the isolated child as source data. Tree retrieval is limited to one, and find/inspect counts are bounded without requiring one exact source or cell sequence.
|
|
68
|
+
|
|
69
|
+
The shared trajectory collector validates the journal and decodes nested arguments as `args` for in-memory use. JSON reports preserve `argsWire`, a canonical PTC Value Graph that retains undefined, omitted object properties, explicit null, bigint, and cycles. Auditing decodes this evidence and uses structured equality, independent of source spelling or object-key order; missing or corrupt evidence fails. `programWork.observations` reports call counts and `repeatedArgumentCalls` separately from `machineMetrics.repeatedSourceCalls`. A workload needing fresh observations must explicitly allow its counts; these limits never suppress runtime calls or establish effect idempotence.
|
|
70
|
+
|
|
71
|
+
### Guarded Edit Acceptance
|
|
72
|
+
|
|
73
|
+
Every edit is validated by the canonical editor against the target reconstructed at dispatch from the session log. Both literal and regex deltas accept an optional valid `expected_target_call_seq`; successful edits must preserve the captured target and the editor's exact derived source and description. Scenario-specific literal deltas and source privacy remain separately checked by `editTransports`.
|
|
74
|
+
|
|
75
|
+
`expect.guardMismatchEdits` lists the one-based edit ordinals intentionally targeting a different call. Such an edit passes only with the structured `{ edited: false, reason }` result and no journal or derived execution metadata. Other edits still require their execution journal. Deterministic tests execute diagnostic-generated EOF closures and reject stale guards through the existing Host tool pipeline; the default paid cohort stays at five workflows.
|
|
76
|
+
|
|
77
|
+
## Recorded paired observation
|
|
78
|
+
|
|
79
|
+
One identity-blinded paired experiment used `opencode-go/deepseek-v4-flash`, the same versioned fixture, task prompts and permissions in both arms, and two repetitions of each of nine tasks: 18 sessions per arm.
|
|
80
|
+
|
|
81
|
+
| Nine tasks, two repetitions | PTC Plus | DSH PTC mode without PTC Plus | Observed difference |
|
|
82
|
+
| --- | ---: | ---: | ---: |
|
|
83
|
+
| Model requests | 66 | 88 | 25.0% fewer |
|
|
84
|
+
| Tool calls | 50 | 79 | 36.7% fewer |
|
|
85
|
+
| Token traffic | 729,642 | 942,901 | 22.6% lower |
|
|
86
|
+
| Identity-blinded rubric score | 138 / 162 | 118 / 162 | 12.3 percentage points higher |
|
|
87
|
+
|
|
88
|
+
In the module-syntax task, PTC Plus completed each repetition in one `run_code`. The other arm failed the static-import requirement in both repetitions, using eight tool calls in total. This stochastic observation is not a performance guarantee. Two PTC Plus sessions and five sessions in the other arm exceeded preset machine budgets, so the overall matrix did not pass machine acceptance. Token traffic includes input, cache-read, cache-write and output tokens. These measurements describe that experiment, not acceptance of subsequent plugin changes.
|
|
89
|
+
|
|
42
90
|
## Reporting
|
|
43
91
|
|
|
44
|
-
|
|
92
|
+
### Binding Workflow
|
|
93
|
+
|
|
94
|
+
`scripts/binding-workflow-scenario.json` owns the constant-helper authoring, user save, and availability scenario. `scripts/binding-files-workflow-scenario.json` separately covers a file helper with write/delete capabilities and a pre-existing directory and sentinel. `test/binding-workflow.test.js` runs both through public CommandRuntime, AgentLoop, ToolRuntime, Session, and prompt assembly with a deterministic adapter. It checks saving, availability observation, preservation of pre-existing content, and rejection of write/delete probes. The constant workflow also checks ordinary history, stable system/tools, and restart. These fixtures prove the Host and audit contracts, not stochastic model behavior or provider cache gains.
|
|
95
|
+
|
|
96
|
+
The deterministic authoring test additionally keeps one command turn active across several real REPL cells: an in-memory comparison exposes a wrong result, corrected source passes assertions, and that exact source is submitted as a disabled draft without a store write. It checks the generated task's test scope and final-source review guidance alongside stable system text and tool schemas. This proves the execution path is available, not that an unconstrained model chooses it.
|
|
97
|
+
|
|
98
|
+
For model-backed authoring evaluation, include both new and edit requests, normal and edge inputs, and a helper whose external integration must remain untested. Inspect submitted source, tool calls and results for tests before acceptance, correct use of feedback, unnecessary discovery, external effects and unsupported completion claims. Compare first-call latency, total time, request count and token usage under the same explicit route; a shorter reasoning block or more calls alone is not a quality criterion. Use concise result evidence when reviewing final answers, not reasoning transcripts as correctness proof.
|
|
99
|
+
|
|
100
|
+
The packed Client can also be checked in a real isolated DSH Web profile without model requests:
|
|
101
|
+
|
|
102
|
+
```sh
|
|
103
|
+
npm run test:client:web -- --dsh-entry <installed-dsh-cli-js> --binding-workflow
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Use `--browser-channel <channel>` when testing with an installed Chromium browser. The local adapter drives public command and tool execution; Playwright saves and discards drafts through the UI, checks English and Chinese lifecycle labels, refreshes saved source, and measures settled desktop and narrow layouts including dark mode. Screenshots and measurements are written to `artifacts/client-web-smoke`; the temporary Host and home are cleaned up. `npm run test:client:layout` separately checks focused card, list, and REPL-tab geometry.
|
|
107
|
+
|
|
108
|
+
For an explicitly authorized model check, use an isolated DSH home and workspace with the selected provider, model, and credential-variable configuration. Run the keyless worker probe with the same resolved Node executable before starting DSH. First send an ordinary message, then run the scenario command, review the generated source, choose Save and enable in the binding review dock above the composer, and send its status question. Export that session log for `auditBindingWorkflow(events, scenario)` in `scripts/acceptance-contract.mjs`; `inspectLog` accepts the same descriptor as `expect.bindingWorkflow`. This interactive workflow remains separate from the five default paid scenarios because the headless single-task runner cannot perform the user save action.
|
|
109
|
+
|
|
110
|
+
The audit owns completeness: matching command and successful admission, accepted candidate and its successful SDK transcript, a formally linked save before the exact status question, settled calls, and a completed answer must all exist. Results distinguish `incomplete`, `unproved`, and `machine-passed`; all nonpassing results include failures. Final prose always retains `semantic-review-required` and must be checked against actual model-visible facts.
|
|
111
|
+
|
|
112
|
+
The oracle rejects routine host/storage scanning and checkpoint reflection. `constantExports` optionally proves only nullary synchronous exports returning declared primitive literals, from the exact accepted source, save relation, and the status cell's validated active snapshot and journal fingerprint. A bounded AST proof tracks local values and only marks catch unreachable after proving its try body cannot throw. Unsupported syntax, object coercion, source mismatch, and shadowing remain insufficient evidence; a name allowlist cannot authorize calls. Export metadata alone does not prove a runtime value's type. Reports distinguish `recorded-dispatch`, `potential-source`, and `unreachable-source`; neither potential source nor insufficient evidence claims an effect happened. The next real user message ends the status scope. These rules belong solely to acceptance, not runtime permission or interception.
|
|
113
|
+
|
|
114
|
+
An effectful follow-up test needs separate task authorization. Its fixture must acquire an exclusive temporary directory with the platform primitive, preserve any pre-existing same-name directory and unrelated sentinel, and clean only its owned directory. For a status-only workflow any write/delete test is a failure, regardless of cleanup success. Historical logs can be audited offline; stochastic model quality and cache improvements remain unmeasured until an explicitly configured model run is performed.
|
|
115
|
+
|
|
116
|
+
Both runners require an explicit model route and credential-variable name before any host probing or artifact creation. The referenced credential variable must already be available in the inherited environment. These configuration-only examples name it without reading or assigning its value:
|
|
45
117
|
|
|
46
118
|
```sh
|
|
47
119
|
DSH_PTC_ACCEPTANCE_PROVIDER=<provider> \
|
|
48
120
|
DSH_PTC_ACCEPTANCE_MODEL=<model> \
|
|
49
121
|
DSH_PTC_ACCEPTANCE_API_KEY_ENV=PROVIDER_API_KEY \
|
|
50
|
-
|
|
122
|
+
DSH_PTC_ACCEPTANCE_CONFIG_ONLY=1 \
|
|
51
123
|
npm run test:expensive
|
|
52
124
|
|
|
53
125
|
DSH_PTC_AB_PROVIDER=<provider> \
|
|
54
126
|
DSH_PTC_AB_MODEL=<model> \
|
|
55
127
|
DSH_PTC_AB_API_KEY_ENV=PROVIDER_API_KEY \
|
|
56
|
-
|
|
128
|
+
DSH_PTC_AB_CONFIG_ONLY=1 \
|
|
57
129
|
npm run test:ab
|
|
58
130
|
```
|
|
59
131
|
|
|
60
|
-
`npm run test:ab` writes `report.json`, `report.md`, per-session trajectory artifacts, and blind-review packets under `artifacts/ab-trajectories/`. Both commands invoke the configured model and consume quota.
|
|
132
|
+
For the authorized model run, remove the corresponding configuration-only assignment after preflight succeeds. `npm run test:ab` then writes `report.json`, `report.md`, per-session trajectory artifacts, and blind-review packets under `artifacts/ab-trajectories/`. Both commands invoke the configured model and consume quota outside configuration-only mode.
|
|
61
133
|
|
|
62
134
|
Token traffic is the sum of input, cache-read, cache-write, and output tokens. Model behavior is stochastic, so comparable new results establish a reproducible observation rather than a universal performance claim.
|
package/docs/installation.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
PTC Plus requires Node.js `^22.19.0 || >=24.0.0` and targets the latest available DSH release with TypeScript PTC mode. Compatibility with the preceding Host contract is retained through public capability detection; when both generations expose competing presentation evidence, the current DSH contract wins. Compatibility follows those live extension surfaces rather than a version allowlist.
|
|
4
4
|
|
|
5
|
+
The worker uses the Host's Node executable. Startup verifies native REPL framing, imports, syntax failures, synchronous throws, awaited rejections, and original return values. The adapter combines public eval callbacks with domain error events before REPL formatting; a source-end witness distinguishes empty completion from falsy rejection. A failed or timed-out probe reports a runtime prerequisite failure before user code executes. The engine range follows DSH; CI exercises Node 22.19, 24, and 26, without claiming that untested future releases have already passed.
|
|
6
|
+
|
|
5
7
|
Install the plugin into the profile that actually runs the target DSH surface. Do not assume a profile named `default` is active.
|
|
6
8
|
|
|
7
9
|
## Compatibility and Authority
|
|
@@ -16,14 +18,20 @@ Install the plugin into the profile that actually runs the target DSH surface. D
|
|
|
16
18
|
|
|
17
19
|
`danger-full-access` is the primary supported experience. The worker isolates the REPL lifecycle; it is not a malicious-code sandbox. DSH continues to own native-tool scope, policy, approval, cancellation, sandboxing, and scheduling. Narrower profiles expose only their available capabilities; PTC Plus does not simulate missing authority or add another permission system.
|
|
18
20
|
|
|
19
|
-
The optional `cordisToolsEnabled` integration requires the current DSH installation to provide its shipped `cordis` preset plus the public preset, Skill, Cordis, settings, and tool-runtime packages. PTC Plus declares those host-owned DSH packages as unrestricted required peers instead of installing private runtime copies; runtime capability validation owns compatibility, and CI
|
|
21
|
+
The optional `cordisToolsEnabled` integration requires the current DSH installation to provide its shipped `cordis` preset plus the public preset, Skill, Cordis, settings, and tool-runtime packages. PTC Plus declares those host-owned DSH packages as unrestricted required peers instead of installing private runtime copies; runtime capability validation owns compatibility, and CI loads the packed plugin inside complete stable and alpha DSH installations. That load step runs `scripts/dsh-execution-seam-smoke.mjs`, which reads the execution service the installed tool runtime reads and requires the plugin to take it over, and `scripts/dsh-rpc-contract-smoke.mjs`, which registers the packed Remote descriptors with the installed TYPERT registry and evaluates the decoder that generation reads ([ADR 0030](adr/0030-serve-both-typert-codec-generations-from-one-codec.md)); an import alone cannot distinguish a loaded plugin from one whose injection is unsatisfied, because Cordis leaves the latter pending without an error, and it cannot show that the Host accepts a wire contract it validates only at registration. Service packages retain the dependency graph selected by their Host distribution rather than independently selecting each service's release tag. DSH's profile module fallback must resolve the peers from the active installation. Do not copy `SKILL.md` or add the Cordis preset's Skill directory to global roots. If the host surface is incomplete, plugin activation or enabling the setting fails instead of loading a second DSH core.
|
|
22
|
+
|
|
23
|
+
The plugin attaches to whichever program-execution service the installed DSH registers, and it presents the capabilities of the execution it performs ([ADR 0028](adr/0028-attach-to-the-host-ptc-execution-seam.md)). Cells run in the session kernel under the session's configured budgets, so `run_code` advertises neither a per-call deadline nor a file sandbox, and DSH rejects `timeoutMs` and `sandbox_permissions` with its own message instead of the plugin accepting an input it would then ignore.
|
|
24
|
+
|
|
25
|
+
Every installation path uses an unmodified official DSH distribution. Local plugin development packages this checkout; it does not build, patch, or substitute the Host. Missing public layout interfaces remain a feature limitation, not an instruction to customize DSH. See [ADR 0017](adr/0017-track-the-latest-dsh-public-surface.md) for distribution and acceptance requirements.
|
|
26
|
+
|
|
27
|
+
The Client root requires `settingsScope`, `slots`, `locale`, and `connection`. Contributions wait for their public slots and consume the supplied session hooks; the composer action additionally requires `remote.commands`. Neither an unused `ui-session` module nor a renamed conversation registry gates activation. Preset selection prefers `agentPreset` projection evidence, falling back only to the preceding public session summary field when that projection is absent. Binding values and draft capabilities always require their own projections. No private store or raw-log fallback is used. Slot and provider disposal withdraw the contributions they own.
|
|
20
28
|
|
|
21
29
|
## npm Release
|
|
22
30
|
|
|
23
31
|
Use this form after the selected version is available from the npm registry:
|
|
24
32
|
|
|
25
33
|
```sh
|
|
26
|
-
dsh plugin --profile <profile> add dsh-ptc-plus@0.
|
|
34
|
+
dsh plugin --profile <profile> add dsh-ptc-plus@0.4.1
|
|
27
35
|
dsh --profile <profile> --dump-config
|
|
28
36
|
```
|
|
29
37
|
|
|
@@ -60,7 +68,7 @@ pnpm dsh --profile <profile> --dump-config
|
|
|
60
68
|
|
|
61
69
|
```sh
|
|
62
70
|
npm pack
|
|
63
|
-
dsh plugin --profile <profile> add /absolute/path/to/dsh-ptc-plus-0.
|
|
71
|
+
dsh plugin --profile <profile> add /absolute/path/to/dsh-ptc-plus-0.4.1.tgz
|
|
64
72
|
dsh --profile <profile> --dump-config
|
|
65
73
|
```
|
|
66
74
|
|
|
@@ -70,11 +78,22 @@ Windows development checkouts can create and install an immutable content-addres
|
|
|
70
78
|
scripts\install-dev.cmd <profile>
|
|
71
79
|
```
|
|
72
80
|
|
|
81
|
+
Installation and a successful Host import do not prove browser activation. Run the model-free packed Web smoke from this checkout with the latest DSH installed, its `pnpm` available, and a Playwright browser:
|
|
82
|
+
|
|
83
|
+
```sh
|
|
84
|
+
npx playwright install chromium
|
|
85
|
+
npm run test:client:web -- --dsh-entry /absolute/path/to/dsh/lib/bin.js
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
On Windows, `--browser-channel msedge` can use the existing Edge installation. The script packs the current source, installs the tarball through `dsh plugin` into a temporary `DSH_HOME`, starts Web on a free loopback port, and opens the conversation and PTC Plus settings surfaces. It closes its browser/Host and removes the temporary profile; screenshots and release evidence remain under ignored `artifacts/client-web-smoke/`. It makes no model request and does not use or update the normal profile. `npm run test:client` supplies the deterministic provider, renderer, projection, and disposal tests included in `verify`/`check`.
|
|
89
|
+
|
|
73
90
|
## Isolated latest-DSH development launcher
|
|
74
91
|
|
|
75
|
-
To test this checkout in a separate DSH installation, double-click `scripts\run-dev-dsh.cmd`. It resolves the
|
|
92
|
+
To test this checkout in a separate DSH installation, double-click `scripts\run-dev-dsh.cmd`. It resolves the newest published DSH release by semantic version over all published versions, prereleases included, rather than following a dist-tag that a release can leave behind; it 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.
|
|
93
|
+
|
|
94
|
+
The launcher defaults to `https://registry.npmjs.org/` for version queries, npm installs and DSH's pnpm subprocesses, including the `@deepseek-ai` scope. This avoids mirror synchronization gaps where a new DSH package is available before its dependencies. It prints the selected registry and refreshes version metadata online; an unavailable version query can still reuse the previously cached version. Set `DSH_DEV_REGISTRY` to an absolute HTTP(S) registry URL to select another source explicitly. The choice applies only to the launcher process and its children; npm configuration files and persistent environment settings are unchanged. Other explicitly configured package scopes retain their own registries.
|
|
76
95
|
|
|
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.
|
|
96
|
+
The default cache is `%LOCALAPPDATA%\dsh-ptc-plus-dev`. It contains the isolated `DSH_HOME`, DSH installations, immutable plugin snapshots, and a pnpm store. Cleanup aims to retain three DSH versions and plugin snapshots, always including the selected installation and snapshot even when another directory has a newer timestamp. Locked directories warn and remain for a later cleanup attempt; their installation marker is removed before deletion so partially deleted installations cannot be reused. Failed pnpm store pruning also warns and continues startup. Installation errors still stop the launcher. Set `DSH_DEV_CACHE` to move the cache, `DSH_DEV_PROFILE` to change the profile name, `DSH_DEV_VERSION` to pin an npm dist-tag or version instead of the newest published release, `DSH_DEV_PORT` to choose a fixed Web port, or `DSH_DEV_MAX_VERSIONS` to change the retention count (1-10).
|
|
78
97
|
|
|
79
98
|
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
99
|
|
|
@@ -87,4 +106,20 @@ dsh plugin add github:muyuanjin/dsh-ptc-plus#main
|
|
|
87
106
|
dsh --dump-config
|
|
88
107
|
```
|
|
89
108
|
|
|
90
|
-
After an npm release, the package spec may instead be `dsh-ptc-plus@0.
|
|
109
|
+
After an npm release, the package spec may instead be `dsh-ptc-plus@0.4.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.
|
|
110
|
+
|
|
111
|
+
## Session format upgrades
|
|
112
|
+
|
|
113
|
+
The public DSH Session format catalog can renumber events when converting historical assistant streams. It treats plugin result metadata as opaque, so its automatic conversion alone cannot preserve PTC sequence references. Before opening historical PTC sessions in the new Host, stop the processes using that profile and retain a backup of each original log.
|
|
114
|
+
|
|
115
|
+
From this source checkout, convert a source artifact with the destination Host's public catalog:
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
npm run session:migrate -- --dsh-entry /path/to/dsh/lib/bin.js --input /backup/session.jsonl --output /staging/session.v2.jsonl
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The output header and command report identify the actual target **Session format**, independent of the DSH package version. Use the corresponding canonical filename `session.v<N>.jsonl` in that session's existing directory. Match the persistence provider's encoding: `.zstd` input/output uses the `zstd` executable, with separate header and event frames. The example names format 2; use the format reported by the selected catalog. Only place the validated output in the stopped profile after inspecting it. Keep the predecessor artifact for rollback; do not continue editing the same history through old and new Hosts in parallel.
|
|
122
|
+
|
|
123
|
+
The converter verifies that ordered tool records retain their identities, maps journal confirmations, edit targets and recovery boundaries, and revalidates the output. It leaves original model arguments, source, results and recorded effects unchanged. Input files are never overwritten, including through hard links; existing destinations require explicit `--force`. A current-format source needs no output. A Host without the public catalog cannot perform Host format conversion.
|
|
124
|
+
|
|
125
|
+
Already converted logs with stale PTC references cannot be repaired from their numeric values alone: use the original predecessor or backup. Preserve any newer activity separately. Logs containing retired `ptc-plus/recovery-boundary` events are refused by Host format conversion; the existing command without `--dsh-entry` remains the separate retired-event converter, whose output needs validation before a further upgrade. The migration tool does not modify a running persistence queue or silently repair unproved history.
|