dsh-ptc-plus 0.3.1 → 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 +66 -73
- package/README.md +66 -73
- 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 +30610 -722
- 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 +6 -4
- package/docs/adr/0007-separate-worker-transport-from-session-semantics.md +15 -3
- 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 +9 -3
- package/docs/adr/0014-persist-cell-rewrite-policy.md +11 -5
- 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 +8 -6
- package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
- package/docs/adr/0021-separate-host-bootstrap-from-session-runtime.md +17 -3
- 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 +82 -22
- package/docs/binding-review-placement-design.md +200 -0
- package/docs/capability-projection.md +1 -1
- package/docs/client-ui.md +96 -20
- package/docs/durability-design.md +61 -24
- package/docs/evaluation.md +78 -6
- package/docs/installation.md +41 -6
- package/docs/program-data-plane.md +6 -0
- package/docs/publishing.md +5 -3
- package/docs/runtime-reference.md +79 -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 +374 -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 +252 -242
- 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 -553
- 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 +91 -25
- 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 +28 -3
- 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 +911 -116
- 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 -201
- package/internal/repl-memory-projection.js +81 -12
- package/internal/repl-observation-interest.js +70 -0
- package/internal/repl-rewrite-contract.js +21 -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 -51
- package/internal/runtime-contexts.js +82 -10
- package/internal/runtime-messages.js +111 -0
- package/internal/session-cell-executor.js +455 -91
- package/internal/session-journal-recovery.js +684 -0
- package/internal/session-journal-schema.js +106 -0
- package/internal/session-journal.js +237 -440
- package/internal/session-log-view.js +42 -9
- package/internal/session-runtime.js +325 -80
- package/internal/session-state.js +249 -40
- 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 +81 -11
- package/src/client-activity.js +109 -45
- 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
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# Binding 草稿在当前输入框上方展示
|
|
2
|
+
|
|
3
|
+
状态:完整草稿由已发布的 `conversation.input.dock` 承载;历史命令位置只保留请求和只读来源。面板采用输入区上方的悬浮布局,验收以正式打包后的浏览器实际行为为准。
|
|
4
|
+
|
|
5
|
+
## 产品目标与分发边界
|
|
6
|
+
|
|
7
|
+
`/binding new` 和 `/binding edit` 产生的完整草稿应直接出现在当前会话的最新操作位置,即普通用户输入框上方。每份新候选首次接受后自动展开,用户无需滚回命令起点、悬停或先打开弹窗,就能阅读源码、模型上下文并保存或丢弃草稿;此后可以主动折叠或关闭面板。
|
|
8
|
+
|
|
9
|
+
卡片是插件自己的当前草稿审阅区,可以是独立面板;不要求成为某个历史 Turn 内的消息节点,也不要求复用原生回答 renderer。后续回答继续追加时,未处理的当前草稿仍跟随输入区。历史记录用于追溯,当前操作区用于处理草稿,两者的位置不必相同。
|
|
10
|
+
|
|
11
|
+
会话历史中的 `/binding` 编写请求始终保留原来的初始样式:标题、状态标识、原始命令与需求、适用的失败说明。草稿生成后,该条目只更新状态,不再自动长成带源码和保存操作的完整卡片。迁移到 dock 的是接受候选后的详细内容与操作区,不是编写请求本身。
|
|
12
|
+
|
|
13
|
+
PTC Plus 必须独立安装到未经修改的官方 DSH,不能修改宿主源码或安装包、要求定制宿主,或把自行新增的宿主接口当作已发布能力。[CONTEXT.md](../CONTEXT.md) 与 [ADR 0017](adr/0017-track-the-latest-dsh-public-surface.md) 拥有此边界。插件自有组件、独立 div、CSS、Portal、页面浮层和公共 renderer 替换都是 UI 工具,不因偏离原生消息布局而被排除;选择依据是实际位置、可分发性、生命周期和宿主职责是否得到保留。
|
|
14
|
+
|
|
15
|
+
本功能的成功条件是:完整草稿默认展开、输入框仍可用、当前候选不会串会话或恢复过期操作权限、官方内容与其他插件继续共存。插件不额外接管审批、取消或绑定持久化,不为移动 UI 改变模型请求、journal 或绑定执行。
|
|
16
|
+
|
|
17
|
+
## 选定落点:`conversation.input.dock`
|
|
18
|
+
|
|
19
|
+
官方声明把该 slot 定义为 **“Full-width entries above the composer card”**:`kind: list`、`scope: session`,owner 为 `InputZone { session, input }`。原生 `ConversationRoot` 在普通 composer 栈中先渲染 dock,再渲染输入框。官方 Todo、Goal 和输入队列都通过独立 id 贡献到这里。
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
会话历史
|
|
23
|
+
绑定编写:/binding new 或 edit 的原始请求(保留初始样式,更新状态)
|
|
24
|
+
后续正文与工具过程
|
|
25
|
+
原生回答尾部、文件产物与操作
|
|
26
|
+
──────────────────────────
|
|
27
|
+
当前输入区
|
|
28
|
+
PTC Plus 完整 Binding 草稿悬浮面板(不占正文布局高度)
|
|
29
|
+
名称、用途、导出信息
|
|
30
|
+
完整源码与模型上下文(默认展开,内部可滚动)
|
|
31
|
+
保存为停用 / 保存并启用 / 丢弃
|
|
32
|
+
Todo / Goal / 输入队列等 dock 内容
|
|
33
|
+
用户输入框
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
插件以独立 id `ptc-plus-binding-review` 注册,初始 `order: 30`。slot 内的零高度锚点承载脱离文档流的面板;以普通 composer 整体的顶部为几何边界,面板悬浮在其他 dock 与输入框上方。展开、折叠不增加正文的布局高度,也不拉高宿主底部遮罩。它会覆盖其后方的部分历史内容;用户可折叠或关闭以阅读,输入框和其他 dock 仍可用。该注册不独占 list,也不重排其他贡献。
|
|
37
|
+
|
|
38
|
+
该落点不参与 Chat 节点排序,不占用 `turnTail` 的 chain,也不需要调用原生 renderer 再拆解其结果。宿主继续拥有正文、原生尾部、文件产物、分支和滚动容器;插件拥有面板内部渲染与样式。不得用额外的虚假事件把 UI 布局写进 session log。
|
|
39
|
+
|
|
40
|
+
| 方案 | 适用性与本次选择 |
|
|
41
|
+
| --- | --- |
|
|
42
|
+
| `conversation.input.dock` 中锚定的悬浮面板 | 已发布的 session list 提供会话生命周期和输入区位置;采用插件自己的浮层布局和有界几何测量。 |
|
|
43
|
+
| 页面级 Portal | 本需求不需要脱离普通 composer 的可见性边界;留在 dock 内可随宿主接管自动隐藏。 |
|
|
44
|
+
| 替换公开 renderer,再组合公开组件 | 公共契约支持时可以使用;本需求无需接管原生回答渲染。没有公开的“下一个 renderer”入口时,不假定可以组合任意注册项。 |
|
|
45
|
+
| 独立 Conversation 节点 | 适合需要历史位置的业务内容;当前目标不需要,而且同轮尾部节点可能改变原生分支资格。 |
|
|
46
|
+
| 命令位置或原生操作行 | 前者位置过早,后者是紧凑操作区;不作为当前完整审阅的落点。 |
|
|
47
|
+
|
|
48
|
+
## 数据来源与当前草稿选择
|
|
49
|
+
|
|
50
|
+
复用 `internal/user-binding-draft-projection.js` 的 `ptcPlusBindingDraft`,以及 `internal/user-bindings-owner.js` 现有 RPC。当前 view 包含 `phase`、`capability`、`commandId` 和可选 `history`;历史记录保存 `acceptedSeq`、精确 candidate 及 action 的正式来源关系。源码、请求身份、版本和 `modelContext` 都已有 owner。
|
|
51
|
+
|
|
52
|
+
面板选择当前 projection 标识的编写请求。`commandId` 关联命令;candidate 的 `requestId` 和 `version` 区分草稿;当前 `capability` 仅用于现有 Host RPC。不能通过“history 最后一条尚未保存”或原始日志扫描推测可操作候选,也不能把历史 request 身份当作 locator。
|
|
53
|
+
|
|
54
|
+
匹配当前请求的已接受 history 可以立即提供只读完整内容;`draft` 与 `draft-review` RPC 则确认当前候选及操作状态,`list` 提供 catalog revision。RPC 返回的请求、命令和版本必须与正在展示的候选一致,才能启用写操作;不一致时刷新现有 owner 的证据,不能在 A 的源码下面放 B 的保存按钮。旧 metadata 没有历史源码时使用现有 RPC 读取路径,不从模型正文提取代码补齐。
|
|
55
|
+
|
|
56
|
+
草稿一旦被 Host 接受并投影即可显示,即使模型还在输出。`command/done` 只表达命令处理,不证明有草稿;`turn/end` 继续由既有 projection 用于编写失败等状态判断,不是面板出现的前置条件。成功接受后的输出、普通工具调用、无最终正文或后续取消,都不由 Client 自行推断为撤销草稿。
|
|
57
|
+
|
|
58
|
+
历史请求的状态与当前可操作草稿分别按证据派生。请求条目复用原有外观,但状态文案必须表达已有证据,不能为保留外观继续显示无法证明的“正在编写”或“编写失败”:
|
|
59
|
+
|
|
60
|
+
| 精确关联到该请求的证据 | 可展示的事实 |
|
|
61
|
+
| --- | --- |
|
|
62
|
+
| CommandNode 的命令处理错误 | 命令处理失败与宿主提供的错误;它不代表其他请求的草稿状态。 |
|
|
63
|
+
| CommandNode 的命令处理成功 | 请求已受理;单凭这一结果不能判定草稿已生成。 |
|
|
64
|
+
| 当前 projection 的 `commandId` 匹配,且 `phase` 为 `pending` 或 `failed` | 分别显示正在编写或未生成可保存草稿;该当前状态不能归到其他历史请求。 |
|
|
65
|
+
| 对应的已接受 candidate/history | 草稿已生成及其精确内容;没有当前 locator 时仍只是只读证据。 |
|
|
66
|
+
| 对应的 Host action 回执 | 已保存或已丢弃;跨重建只使用现有 RPC 或带正式来源关系的历史回执,不由 locator 消失推断结果。 |
|
|
67
|
+
| 没有候选或回执,当前 projection 也不再标识该请求 | 保留可证明的命令处理结果;编写结果显示未知,不推断仍在运行、已失败或已被替换。 |
|
|
68
|
+
|
|
69
|
+
已接受 candidate 和 action 分别拥有生成与处理结果;当前 projection 拥有当前编写状态和 locator。命令准入结果不覆盖这些事实。当前 RPC 确认的结果沿用既有展示规则,不被提升为已经持久化的历史回执。
|
|
70
|
+
|
|
71
|
+
例如 A 已有草稿,B 命令成功准入后整轮未接受候选,既有 projection 会恢复到 `A.ready`,并不保留 B 的编写终态。此时 A 按原展示选择恢复;B 在缺少独立终态证据时显示“请求已受理,编写结果未知”。重新挂载、分页和重连采用相同规则,不能通过 A 恢复、B 不在 history 中或临时 Client 缓存来证明 B 失败。此需求按现有证据明确表达未知即可,不新增日志事件或投影字段来补造结论。
|
|
72
|
+
|
|
73
|
+
本次位置调整不需要 `acceptedTurn`、新 Conversation Definition、额外位置 metadata、projection 升版或 journal 迁移。若实施发现现有数据不足以满足上述选择规则,先记录具体反例和最小 owner 修正,再调整计划;不能为布局预先增加恢复协议。
|
|
74
|
+
|
|
75
|
+
## 展示与操作生命周期
|
|
76
|
+
|
|
77
|
+
| 状态或事件 | 当前输入区的行为 |
|
|
78
|
+
| --- | --- |
|
|
79
|
+
| 没有可展示的当前候选或已确认回执 | dock 不占空间;历史请求及其已有候选仍可只读查看,不从历史挑一份升级为当前草稿。 |
|
|
80
|
+
| 编写中 | 原命令条目保留已有编写状态;dock 不重复展示一份编写请求,也不把上一份草稿冒充本次结果。 |
|
|
81
|
+
| 已接受,正在确认操作资格 | 新候选首次在 dock 展开,操作按钮暂不可用并说明正在载入。目录读取慢不应让已知源码消失;用户主动折叠或关闭后,读取完成不强制展开。 |
|
|
82
|
+
| 当前草稿可用 | 按用户选择保持展开、折叠或关闭;展开时显示完整内容和模型上下文,保留保存为停用、保存并启用、丢弃及既有 revision 冲突处理。 |
|
|
83
|
+
| 保存或丢弃成功 | 确认精确候选的处理结果后自动关闭面板;历史保留精确候选和有证据的 action。保存不等于会话已激活。 |
|
|
84
|
+
| 编写失败或旧草稿恢复 | 原请求只显示上述证据规则支持的状态;缺少证据时显示编写结果未知。没有已接受候选就不产生完整 dock 卡片。Host 恢复旧草稿时沿用该候选的展示选择,不自行改变 fallback 规则。 |
|
|
85
|
+
| 资格撤销、Host 重启或只剩历史证据 | 对仍能证明属于当前显示内容的候选保留只读查看;撤下写操作。没有当前身份时不把历史重新挑成活动草稿。 |
|
|
86
|
+
| 开始下一次编写 | 当前区跟随新的 projection;旧候选留在历史位置,不能跨请求沿用 busy、错误、回执或 locator。 |
|
|
87
|
+
| 切换会话、断线重连、分支或 seed | 按新会话 projection 重建;加载期间禁止沿用旧会话内容和写权限。历史可见性与当前资格分别判断。 |
|
|
88
|
+
| 禁用功能、释放 slot 或卸载插件 | 释放本功能拥有的订阅、计时器和面板;不自动保存、丢弃或执行候选。 |
|
|
89
|
+
|
|
90
|
+
同一会话只保留一个当前完整审阅 controller,按会话、请求、版本和 locator 隔离异步读取与动作。`conversation.chat.commandview` 的 `binding` key 继续渲染原有编写请求,不能因 dock 已注册、已出现或被关闭而返回空内容。保留 `BindingCommandCard` 的请求外观和状态区,只移走候选详细内容及写操作。所需展示能力可用且该请求精确对应尚未处理的当前候选时,必须提供“打开草稿”入口,用于展开 dock,不重新执行 `/binding`;隐藏编写按钮的设置不影响该入口。历史主动查看仍可展开只读源码,但接受候选不得自动展开历史详情,也不能在历史中恢复保存或丢弃按钮。
|
|
91
|
+
|
|
92
|
+
现有页头 popover 的候选展示与保存/丢弃入口也应收拢:保留状态与管理入口,不再创建第二套当前草稿写入流程。历史只读内容可以复用展示组件,但不能恢复控制器或写权限。
|
|
93
|
+
|
|
94
|
+
抽取现有 `BindingCommandCard` 的展示和 RPC 行为时,分别保留请求条目、纯候选内容组件与当前审阅 controller。不要仅把依赖 `node.commandId` 的原组件直接塞入没有 Command node 的 dock,再伪造 node 参数。未处理草稿不因超时或下一条普通消息自动消失;用户主动调整面板只改变本地展示。
|
|
95
|
+
|
|
96
|
+
写操作仍使用 `save-draft` / `discard-draft`,传递现有 capability、version 及适用的 expected revision。请求切换、组件卸载或资格变动后的迟到响应不能恢复旧按钮;一次失败读取不证明候选已被撤销。待决写入按精确候选隔离:同一候选不重复提交,接受新候选后可独立读取资格和操作,旧响应不能阻塞新候选或清除其 busy 状态。已有必要的资格刷新可以复用,但不能为确定位置或等待回答结束新增轮询、事件订阅或第二套状态机。
|
|
97
|
+
|
|
98
|
+
## 折叠、展开、关闭与重新打开
|
|
99
|
+
|
|
100
|
+
除独立关闭按钮外,整条标题栏是一个原生折叠/展开按钮,标题、状态与箭头区域都可以点击;Enter 和 Space 使用原生按钮语义。展开时箭头朝下表示收起,折叠时朝上表示展开,状态与 `aria-expanded` 一致,并遵循减少动画的系统偏好。完整内容默认展开不等于禁止用户收起。
|
|
101
|
+
|
|
102
|
+
| 用户操作 | 展示结果与草稿状态 |
|
|
103
|
+
| --- | --- |
|
|
104
|
+
| 折叠 | dock 保留名称、状态、展开和关闭按钮,收起正文及保存/丢弃操作;不改变候选或编写事务。 |
|
|
105
|
+
| 展开 | 未处理候选在原 dock 位置恢复完整内容;已处理候选仅从历史请求查看。写操作仍以当前 Host 证据为准。 |
|
|
106
|
+
| 关闭 | 隐藏整个 dock 面板,不保存、不丢弃、不取消编写,也不删除历史请求。 |
|
|
107
|
+
| 重新打开 | 输入框星光按钮的草稿菜单或当前历史请求的“打开草稿”展开同一当前候选;不重新发命令、生成候选或创建第二个操作 controller。 |
|
|
108
|
+
| 丢弃草稿 | 仅明确点击“丢弃”才调用既有 Host RPC;它与关闭面板是不同操作。 |
|
|
109
|
+
|
|
110
|
+
公开 `conversation.input.left` 只注册一个星光图标,统一插件设置快捷访问、全局绑定管理、编写与当前草稿访问。图标在悬浮或聚焦时以插件署名提示说明来源与用途,有未处理候选时改为提示草稿状态。首条消息前即可通过悬停、点击或方向键打开官方 `Menu`;设置条目直接打开复用完整设置表单的应用内窗口,悬浮提示保留宿主原生设置路径;全局绑定展示名称、用途及启用状态,点击条目切换对所有会话生效的启用配置,并可打开既有完整工作台。有未处理候选时显示数量角标,菜单中单独分组,按名称与状态选择候选后展开面板。菜单中的“编写新绑定”沿用既有命令可用性与输入保护;“修改绑定”是同一个 `Menu` 的第二个步骤,列出已有全局条目,选择后以相同保护预填 `/binding edit <id> `。当前 Host 每会话只保留一份当前草稿,因此角标为 `1`,不把历史候选计为待处理草稿。草稿访问不依赖命令服务;隐藏编写快捷入口时保留已有草稿的星光图标,但不显示全局目录、管理与新建操作。插件与全局绑定功能开关仍统一控制整个入口。
|
|
111
|
+
|
|
112
|
+
菜单使用公共 Portal 和 `getAnchorRect`,以触发按钮自身为锚点定位,按按钮上沿之上的实际可用空间限制列表高度;全局绑定与新建、修改、管理操作共享原生滚动区域,较矮视口下仍可逐项访问。悬停停留 150ms 的意图延迟后才打开菜单,指针扫过输入区不弹出菜单;点击与方向键路径不受延迟影响。菜单由外部点击或 Escape 关闭。悬停打开的菜单在指针离开触发器与列表 200ms 后关闭,重新进入列表或触发器即取消;该宽限覆盖指针短暂离开整个菜单的瞬间,因此越过输入区选择条目仍然可行。点击打开的菜单保持到显式关闭。点击与方向键打开时聚焦首个可用操作,Tab 可到达新建、修改和管理操作;进入“修改绑定”步骤后焦点移到第一个条目。候选变化、会话切换、功能关闭、卸载或普通输入区被接管时关闭菜单;普通刷新不关闭菜单。菜单选择必须向同一 review controller 传递精确候选,不能把旧项点击重定向到新候选。原请求条目中的入口也只能打开其精确对应的当前候选;旧请求只允许查看自己的只读历史。展示能力暂不可用时,不提供实际无法打开面板的操作。
|
|
113
|
+
|
|
114
|
+
全局目录由现有 `list` Remote 按菜单打开动作读取,不轮询;读取在后台进行,期间菜单沿用上一次已确认的目录并保持条目可操作,只有写入进行中才禁用切换。显式“重新加载”调用 `reload` 重新读取存储文件并清除已修复的读取错误。启停沿用 `enable`/`disable` 与 `expectedRevision`。写入期间禁用重复切换,关闭菜单不取消已发出的操作。冲突或失败后撤下过期目录,用户重新读取后再决定是否重试,不自动重发写入。重连和组件释放使旧响应失效;菜单读取、显示和启停配置不执行绑定源码。菜单明确区分全局启用配置与待处理草稿,角标只统计草稿。
|
|
115
|
+
|
|
116
|
+
展示选择以 `(sessionId, requestId, candidateVersion)` 归属,只有 `expanded`、`collapsed`、`hidden` 三种本地状态。当前 Client 内切换会话再返回、RPC 刷新、重连、普通消息追加以及审批临时接管,不重置同一候选的选择;真正接受的新候选默认展开,并从该候选的内容顶部开始阅读;同一候选的普通刷新保留滚动位置。刷新页面或重新加载插件后按当前有效候选恢复默认展开,不要求把展示偏好写入持久存储。共享此选择只协调插件视图,不承载 locator 或 Host 事务资格,也不增加 session log、模型消息或管理 RPC。
|
|
117
|
+
|
|
118
|
+
显隐选择不影响业务操作;精确候选一旦确认保存或丢弃成功,当前面板自动关闭。失败或结果待确认时保留用户的显隐选择:
|
|
119
|
+
|
|
120
|
+
| 结算时的展示选择 | 保存或丢弃已确认成功 | 写入失败或结果待确认 |
|
|
121
|
+
| --- | --- | --- |
|
|
122
|
+
| `expanded` | 自动关闭;回执与精确源码从原请求只读查看。 | 保留完整面板并展示错误或待确认状态;仅在重新证明可写后允许手动重试。 |
|
|
123
|
+
| `collapsed` | 自动关闭;原请求显示处理结果。 | 保持折叠,标题提示有错误或结果待确认,允许用户展开查看。 |
|
|
124
|
+
| `hidden` | 保持关闭,不弹回执;原请求展示有证据的处理结果。 | 保持关闭,保留就近重新打开入口并提示有待查看状态,不自动展开或重试。 |
|
|
125
|
+
|
|
126
|
+
关闭或折叠待决操作中的面板不取消已发出的保存/丢弃 RPC;操作结算仍由同一 controller 接收。未确认处理结果时保留当前候选的访问入口,但入口不证明可以再次写入;一次网络错误不能触发重新提交。已确认保存或丢弃后移除两个当前草稿打开入口,结果和精确候选继续从原历史请求只读查看。确认结果统一由当前 controller 收敛:保存响应、精确 review RPC 或 projection 回执均关闭匹配候选,普通刷新不能重新打开;旧候选的迟到结果不能关闭新草稿。locator 撤销本身不证明处理成功。
|
|
127
|
+
|
|
128
|
+
用户关闭时,焦点移到就近的星光按钮,聚焦本身不弹出菜单;没有该入口时回到输入框。成功后自动关闭仅在面板原本持有焦点时恢复焦点,不能打断用户在其他区域的操作。异步成功移除当前聚焦的打开入口时也应保持合理焦点,不能将其留在已移除节点;宿主接管时不从审批界面抢焦点。折叠按钮提供 `aria-expanded`,被隐藏的内容不得继续接受键盘焦点。
|
|
129
|
+
|
|
130
|
+
## 输入区接管与布局边界
|
|
131
|
+
|
|
132
|
+
官方普通 composer 是 `conversation.composer` chain 的 fallback。当前实现使用 `overlay: true`:其他 contribution 被选中时,fallback 保持挂载但被 `display:none` 隐藏,因此 input dock 也会隐藏。**注册成功不等于任何时候都可见;隐藏也不等于已卸载。**
|
|
133
|
+
|
|
134
|
+
审批或其他宿主交互接管输入区时,草稿区和重新打开入口随普通输入框一起暂时让位,不通过 Portal 把保存按钮强行叠到审批上。PTC Plus 的 REPL 视图接管 composer 时也按此规则隐藏;回到普通输入区后恢复同一份有效草稿及其原有展开、折叠或关闭选择。重建时读取 projection 和 RPC,不依靠隐藏 DOM 保留权限。长驻 controller 必须能处理隐藏期间的撤销;用于刷新资格的任务仍受功能和会话生命周期约束,不能只依赖 unmount 清理。
|
|
135
|
+
|
|
136
|
+
普通对话中的正文继续流式输出、产生工具结果或开始下一轮,不是隐藏卡片的理由。所需边界是“普通输入区是否被宿主接管”,不能把 `input` 的任意 busy 状态当作隐藏条件,也不要求用户等待真实轮次结束。
|
|
137
|
+
|
|
138
|
+
面板采用不透明主题底色、细边框与阴影,明确表达临时浮层;插件拥有的标题、滚动正文和操作区以分隔线区分。名称只在标题出现,正文保留导出信息、用途、完整源码及模型上下文;丢弃与保存动作分置两侧,窄屏允许换行。面板在 dock 内居中并以 `44rem` 限制阅读宽度,两侧至少留出 `16px`,避免控件跨入会话两侧的原生拖拽区域,不固定到 `document.body` 坐标。
|
|
139
|
+
|
|
140
|
+
长内容必须保留完整文本并在内部滚动,不能以截断源码换取高度。通常正文区以 `min(32dvh, 20rem)` 为上限,标题和操作区保持可见。标准 DOM 几何、`ResizeObserver` 和 visual viewport 事件共同拥有定位与空间测量:面板底部位于整个普通 composer 上方 `8px`,顶部在 scrollport 内留出 `8px`。多行输入或其他 dock 占用较多空间、正文剩余不足 `80px` 时,改为整张面板单层滚动,使源码、模型上下文与操作均可通过滚动或键盘到达,不把源码区压成零高度。面板本身始终受实际剩余空间限制。折叠时仍需要定位观察;隐藏、处理成功和卸载释放观察。只写入插件元素的样式,不改宿主布局,不持续滚动正文。浏览器验收同时检查实际点击命中、折叠前后的 composer 坐标与正文滚动范围,不能仅凭注册成功或静态截图证明可用。不要把宿主未公开的 CSS 变量或私有类名提升为必需契约。
|
|
141
|
+
|
|
142
|
+
源码和模型上下文默认展开。历史详情和 dock 共用只读模型上下文区,以“接口声明”状态标签说明是否向模型提供,并单独呈现完整提示词或空状态;不使用禁用的表单控件表示配置。当前卡片不采用 hover 才显现的布局,不自动抢焦点或持续调用 `scrollIntoView`。键盘可进入内容滚动区和所有动作,窄屏操作行允许换行,动态视口下仍能访问输入框与审批。共享 list 的顺序只管理本插件贡献,不重排其他插件。
|
|
143
|
+
|
|
144
|
+
## 集中兼容与实施顺序
|
|
145
|
+
|
|
146
|
+
一项公共能力由一个执行环境中的 owner 管理。Client 入口通过既有 `ctx.slots.inject` 等待 `conversation.input.dock`,沿用 `src/client-feature-gates.js` 的 `registerGated`(订阅设置 → 判定资格 → 注册/注销 → 回滚)、`ctx.effect()` 与 disposer 释放注册。root `apply` 注册 session-scoped contribution,由 renderer 的公共会话 props、projection hooks 和现有 RPC 注入提供数据;不另起 session coordinator。
|
|
147
|
+
|
|
148
|
+
本方案不消费 Conversation event registry,因此无需为了旧 `conversationEvents` 与后续 `uiConversation.events` 增加适配。确有公共 props 形态差异时集中到 `src/client-host-compat.js`,组件使用统一语义;不能以 DSH 版本号分支,也不为没有差异的 dock 包一层泛化框架。
|
|
149
|
+
|
|
150
|
+
slot 的迟到、释放、再次声明和功能开关必须测试。缺少所需展示能力时,历史中仍保留紧凑的编写请求与已有的只读历史,并显示“草稿审阅面板暂不可用”;不恢复历史里的完整操作卡片,不伪装成用户主动关闭,也不自动保存、丢弃或执行草稿。重新打开入口只在实际能打开面板时提供,能力恢复后按同一候选原有展示选择恢复。审批接管属于普通输入区暂时隐藏,不是公共能力缺失,不显示能力错误。
|
|
151
|
+
|
|
152
|
+
展示能力的就绪与释放由一处 Client 注册 owner 协调,包括 dock、重新打开入口和所需公共 props,不在组件中分别猜测能力或自行声明宿主落点。在目标官方分发中缺少这些能力意味着本方案尚不能通过产品验收;保留请求与提示不可用不等于已交付输入框上方的审阅功能。
|
|
153
|
+
|
|
154
|
+
实施记录:
|
|
155
|
+
|
|
156
|
+
1. 已在未经修改的官方 `0.1.3-alpha.2` 安装中注册最小 dock,并以真实浏览器确认其位于输入框上方。
|
|
157
|
+
2. 已复用 draft projection 与现有 RPC owner,历史命令卡片保留请求和只读候选,当前候选由单一 Client review controller 管理;页头不再提供第二套写操作。
|
|
158
|
+
3. 已实现折叠、展开、关闭、输入框旁重新打开、迟到响应隔离、跨会话隔离、待决写操作和 composer takeover 生命周期。
|
|
159
|
+
4. 已以最终 tarball 运行官方 Web smoke,覆盖长内容、窄屏、低视口、隐藏编写按钮和展示操作的 session-log 不变性,并同步更新 ADR、Client UI 与用户文档。
|
|
160
|
+
|
|
161
|
+
## 验收与交付证据
|
|
162
|
+
|
|
163
|
+
| 验收项 | 必须观察的结果 |
|
|
164
|
+
| --- | --- |
|
|
165
|
+
| 官方安装 | 正式 tarball 安装成功,Host 源码和安装文件不变,实际加载最终插件 bundle。测试 fixture 自行声明 slot 不能替代此项。 |
|
|
166
|
+
| 请求与位置 | `/binding new`、`edit` 发出时保留历史中原有的绑定编写请求样式;接受后只更新请求状态,完整详情和写操作首次在 dock 展开,原条目不消失也不变成完整操作卡片。 |
|
|
167
|
+
| 展示控制 | 点击折叠态的标题文字即可展开,Enter/Space 同样可用,箭头随状态变化;展开/折叠不改变 composer 坐标或正文滚动范围。关闭仅隐藏,输入框旁与当前请求都能重新打开;同一候选的 RPC 更新、重连、普通消息和审批接管不覆盖用户选择,新候选首次展开。 |
|
|
168
|
+
| 内容与操作 | 精确源码和模型上下文默认可读;保存为停用、保存并启用、丢弃、busy、冲突、失败及回执正确。 |
|
|
169
|
+
| 结算与显隐 | 保存或丢弃过程中分别保持展开、折叠和关闭,验证成功、失败及结果待确认组合。已确认成功自动关闭面板;已处理后的两个当前入口移除,回执与源码从原请求只读访问。 |
|
|
170
|
+
| 请求状态证据 | A 已有草稿,B 命令成功准入后未接受候选,projection 回到 A;B 在重新挂载、分页和重连后显示准入成功及编写结果未知,不能冒用 A 的 ready 或推断失败。命令处理错误、匹配 projection 的 failed、接受及 action 各自只归到对应请求。 |
|
|
171
|
+
| 候选与异步 | 新请求、旧请求恢复、跨会话、迟到 RPC、断线、重启、分支和 seed 不串候选,不以历史或旧 locator 恢复写权限。 |
|
|
172
|
+
| 唯一控制器 | 命令处和页头不再同时出现另一套当前保存控件;折叠或关闭期间的写操作不会丢失结算或重复提交。主动展开历史仅只读,分页不重新挂载活动控制器。 |
|
|
173
|
+
| 宿主共存 | 官方文件产物、Todo、Goal、队列和另一插件的 dock 内容继续显示;原生分支资格、目标与草稿 UI 无关。 |
|
|
174
|
+
| 接管与恢复 | 宿主审批及 REPL 接管时不遮挡接管界面,恢复普通输入框后草稿仍可读;隐藏期间撤销不会恢复旧操作权限。 |
|
|
175
|
+
| 浏览器 | 桌面、窄屏、中英文、长源码、键盘和焦点、多 dock 与小视口下内容和输入框可达,无强制滚动或页面溢出。 |
|
|
176
|
+
| 日志与请求 | 展示、展开、隐藏和历史查看不新增 event、模型提示词或声明,不影响前缀稳定性、journal 或模块初始化;真实保存沿用已有 notice/catalog 契约。 |
|
|
177
|
+
| 能力生命周期 | 验证既有与当前契约、迟到声明、释放、重挂载和开关。能力缺失时保留紧凑请求与明确不可用提示,没有历史写操作或无效的打开入口;恢复后沿用候选和显隐选择。审批接管不误报能力缺失,不以版本号或新造 slot 代替能力证明。 |
|
|
178
|
+
|
|
179
|
+
按项目 ledger 流程记录实施发现,最终在稳定树上运行 `npm run check` 和 `git diff --check HEAD --`。独立 reviewer 无缺陷、确定性测试通过、实际 UI 验收是不同证据;不能把其中任一项替代其余。提交与发布仍遵循用户授权及独立审查条件。
|
|
180
|
+
|
|
181
|
+
## 公共契约与历史证据
|
|
182
|
+
|
|
183
|
+
已核对官方源码中的 slot 声明、原生根布局和贡献实例,以及已安装官方包的类型声明与实际 Client bundle 中的 dock 渲染。它们证明接口存在及设计落点可用,尚不证明 PTC Plus 面板已实现或完成浏览器验收。
|
|
184
|
+
|
|
185
|
+
以下标签仅标识只读历史源码样本,不定义运行分支、测试白名单或当前兼容目标:
|
|
186
|
+
|
|
187
|
+
| 历史样本 | 与本方案相关的事实 |
|
|
188
|
+
| --- | --- |
|
|
189
|
+
| `dsh-v0.1.1-rc.2` | ui-conversation 声明 session/list 的 `conversation.input.dock`,根布局在输入框之前渲染它。 |
|
|
190
|
+
| `dsh-v0.1.2-rc.1` | 相同的公共 dock 与相对输入框位置;不依赖 Chat 拆包后的 registry。 |
|
|
191
|
+
| `dsh-v0.1.3-alpha.2` | 相同的公共 dock 与位置;已安装官方分发也包含该 slot。 |
|
|
192
|
+
|
|
193
|
+
公开规则与受检源码入口:
|
|
194
|
+
|
|
195
|
+
- [Slots 扩展规则](https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.3-alpha.2/docs/subsystems/slots.zh.md):基数、scope、selector 与生命周期。
|
|
196
|
+
- [输入区插槽声明](https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.3-alpha.2/packages/client/ui-conversation/src/client/contract/slots.ts):`conversation.input.dock` 和 `InputZone`。
|
|
197
|
+
- [原生会话根布局](https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.3-alpha.2/packages/client/ui-conversation/src/client/skeleton/ConversationRoot.tsx):dock、普通输入框与 composer chain 的组合。
|
|
198
|
+
- [Slot 渲染契约](https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.3-alpha.2/packages/client/ui-slots/src/index.ts):`overlay` 隐藏而不卸载 fallback。
|
|
199
|
+
- [Todo](https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.3-alpha.2/packages/client/ui-conversation/src/client/skeleton/TodoPanel.tsx)、[Goal](https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.3-alpha.2/packages/client/ui-goal/src/client/index.ts)、[输入队列](https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.3-alpha.2/packages/client/ui-conversation/src/client/queue/QueueDock.tsx):官方独立 list contribution 的实际用法。
|
|
200
|
+
- [早期根布局](https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.1-rc.2/packages/client/ui-conversation/src/client/skeleton/ConversationRoot.tsx)与[后续根布局](https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.2-rc.1/packages/client/ui-conversation/src/client/skeleton/ConversationRoot.tsx):既有公开 dock 的位置证据。
|
|
@@ -43,6 +43,6 @@ explorer 不调用 capability、不提升 authority、不读取隐藏服务、
|
|
|
43
43
|
|
|
44
44
|
## Non-tool APIs
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
执行缝 request 已携带的 owner-provided program namespace 会原样进入 cell,并与 native tools 共享 lease;插件不翻译其领域契约。与插件保留的 `capabilities`、`code` 或 `repl` 同名时 request 明确失败,避免两套 binding 静默分叉;普通 cell 局部变量可以 shadow 这些低频 namespace,需要时从 `globalThis` 访问。`tools` 仍保持保留,因为 shadow 它会移除主要 typed 能力面。`code.run` 只隔离执行已经作为数据持有的 source;当前 cell 能直接完成的 Node、fetch 或 native tool 工作不需要嵌套。当前公共扩展面没有发现额外 DSH/插件服务的 registry,PTC Plus 不猜测隐藏服务,也不保留未来脚手架。显式注册、生成 manifest、装饰器或扫描只是可能的发现机制,不能替代类型、authority、lease 和 settlement 契约。
|
|
47
47
|
|
|
48
48
|
explorer 本身只做 deterministic inspection,不调用模型。任何 Agent 生成的语义摘要都必须由用户主动触发,或由用户预先授权且有硬预算、用量记录和取消能力的 policy 触发;它不属于当前运行时。
|
package/docs/client-ui.md
CHANGED
|
@@ -1,51 +1,123 @@
|
|
|
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
|
|
|
42
|
-
投影通过 DSH 正式的 `tool/call.data.callId` / `tool/result.data.message.source.callId` 身份配对 `run_code` 与 `edit_run_code`,不依赖可选 `sourceEventSeqs`。它只接受当前 runtime generation 的 envelope,并在 `session/end-seed` 清除旧 lifecycle 的 live 证明;缺少、损坏、其他 generation 的 metadata、无关 tool result
|
|
92
|
+
投影通过 DSH 正式的 `tool/call.data.callId` / `tool/result.data.message.source.callId` 身份配对 `run_code` 与 `edit_run_code`,不依赖可选 `sourceEventSeqs`。它只接受当前 runtime generation 的 envelope,并在 `session/end-seed` 清除旧 lifecycle 的 live 证明;缺少、损坏、其他 generation 的 metadata、无关 tool result 与不影响 binding provenance 的 result-only replacement 都不能覆盖仍有效的最后已证明清单。若 surface replacement 遮蔽了声明 provenance,runtime 与 projection 共用的 model-visible frontier 判定会让相关 inventory 失效。缺少有效 metadata、projection service 或兼容 registration contract 时只显示不可确认,不主动读取历史、不迁移日志,也不影响继续会话。来源跳转要求 Host 提供打开 tool call 或 source location 的公共 capability;缺少该 capability 时,卡片只提供内联检查,不访问私有 store 或宿主 DOM。
|
|
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
|
|