dsh-ptc-plus 0.4.8 → 0.4.10
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 +11 -3
- package/README.md +11 -3
- package/client.js +1151 -529
- package/cordis.patch.yml +12 -2
- package/docs/README.md +1 -0
- package/docs/adr/0005-temporary-rejected-cell-edit-transport.md +19 -0
- package/docs/adr/0019-plugin-settings-and-kill-switch.md +13 -2
- package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +1 -1
- package/docs/adr/0023-global-user-bindings.md +1 -1
- package/docs/adr/0028-attach-to-the-host-ptc-execution-seam.md +82 -18
- package/docs/adr/0030-serve-both-typert-codec-generations-from-one-codec.md +3 -3
- package/docs/adr/0032-own-session-log-facts-in-a-host-only-projection.md +27 -0
- package/docs/adr/0033-gate-client-visual-usability-in-a-browser.md +23 -0
- package/docs/architecture.md +3 -3
- package/docs/binding-review-placement-design.md +29 -21
- package/docs/client-ui.md +20 -8
- package/docs/client-visual-contract.md +48 -0
- package/docs/durability-design.md +12 -0
- package/docs/installation.md +27 -6
- package/docs/runtime-reference.md +1 -1
- package/docs/user-bindings.en.md +2 -2
- package/docs/user-bindings.md +3 -3
- package/docs/verification-optimization-work.md +26 -0
- package/docs/verification.md +2 -0
- package/index.js +28 -7
- package/internal/compiler-platform.js +5 -3
- package/internal/compiler-service.js +2 -9
- package/internal/cordis-tools-owner.js +22 -19
- package/internal/direct-surface-owner.js +2 -0
- package/internal/edit-transport-owner.js +8 -5
- package/internal/execution-provider-owner.js +157 -0
- package/internal/execution-seam-compat.js +69 -113
- package/internal/isolated-worker.js +12 -8
- package/internal/recovery-tips.js +50 -21
- package/internal/runtime-bridge-owner.js +88 -57
- package/internal/runtime-contexts.js +13 -13
- package/internal/session-events.js +40 -4
- package/internal/session-journal-recovery.js +678 -181
- package/internal/session-log-view.js +189 -43
- package/internal/session-runtime.js +58 -10
- package/internal/settings-compat.js +12 -2
- package/internal/user-bindings-owner.js +6 -5
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +13 -14
- package/src/client-authoring-view.js +222 -141
- package/src/client-binding-review.js +2 -0
- package/src/client-code-editor.js +6 -0
- package/src/client-copy.js +10 -0
- package/src/client-feature-gates.js +12 -5
- package/src/client-host-compat.js +23 -2
- package/src/client-primitives.js +249 -0
- package/src/client-repl-view.js +3 -3
- package/src/client-settings-view.js +2 -29
- package/src/client-styles.js +92 -33
- package/src/client-tool-view.js +8 -3
- package/src/client-workbench.js +3 -3
- package/src/client.js +72 -46
- 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/cordis.patch.yml
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
- id: ptc-runtime
|
|
2
|
+
isolate:
|
|
3
|
+
ptcRuntime: ptc-plus-original
|
|
4
|
+
|
|
3
5
|
- insert:
|
|
6
|
+
- id: ptc-plus-execution
|
|
7
|
+
name: dsh-ptc-plus/execution-provider
|
|
8
|
+
intercept:
|
|
9
|
+
loader:
|
|
10
|
+
await: false
|
|
11
|
+
config:
|
|
12
|
+
originalEntryId: ptc-runtime
|
|
13
|
+
isolation: ptc-plus-original
|
|
4
14
|
- id: ptc-plus
|
|
5
15
|
name: dsh-ptc-plus
|
package/docs/README.md
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
## Maintenance
|
|
24
24
|
|
|
25
25
|
- [Deterministic Verification](verification.md): complete checks, backend test concurrency, coverage, and focused diagnostics.
|
|
26
|
+
- [Client Visual Contract](client-visual-contract.md): browser prerequisites, control and state coverage, fault counterexamples, and packed Host evidence boundaries.
|
|
26
27
|
- [Incremental Review Verdict](adr/0026-persist-the-delivery-verdict-against-the-verified-candidate.md): predeclared parallel lanes, dependency-scoped invalidation, and the composite commit verdict.
|
|
27
28
|
- [Focused Verification](verification-optimization-work.md): bounded coverage diagnostics and their relationship to the final verification gate.
|
|
28
29
|
- [Semantic Validation](semantic-validation.md): pinned Test262 cases, dialect contracts, native differential matrices and their limits.
|
|
@@ -49,6 +49,25 @@ signal. A settled result retires the relation. The retained registration does no
|
|
|
49
49
|
tool outside a code composition, and one shared session lifecycle revokes outstanding request and
|
|
50
50
|
call records on session, agent, or plugin disposal.
|
|
51
51
|
|
|
52
|
+
The code composition deliberately retains a complete native registry and nested
|
|
53
|
+
SDK while the public assembly hook projects only the two direct transports.
|
|
54
|
+
This is an accepted exception to the Host recommendation that assembly hooks
|
|
55
|
+
should not change the visible tool list; registry and model-visible lists need
|
|
56
|
+
not be identical. Requiring stock `ptc` collapse would reject the editor, and
|
|
57
|
+
restricting the registry to the two transports would remove native program
|
|
58
|
+
bindings. Live-schema-proven native-call normalization is therefore retained
|
|
59
|
+
before persistence and Host dispatch, preserving call identity and native JSON
|
|
60
|
+
arguments through ordinary DSH validation, policy and approval. Stable
|
|
61
|
+
configuration still requires byte-stable plugin text and ordered schemas.
|
|
62
|
+
|
|
63
|
+
An unchanged native root call, including one left unchanged when canonicalization
|
|
64
|
+
is disabled, is rejected by the plugin's execution hook. Because Host
|
|
65
|
+
pre-execution approval precedes that hook, such a call can prompt for approval
|
|
66
|
+
before rejection; this ordering is an accepted limitation, not a registry-level
|
|
67
|
+
admission guarantee. Acceptance does not establish a new public direct-set API.
|
|
68
|
+
Revisit the projection if the official Host changes the assembly contract or
|
|
69
|
+
provides independent direct-tool admission without narrowing the nested SDK.
|
|
70
|
+
|
|
52
71
|
`edit_run_code` targets the most recent editable cell in the current turn when its persisted
|
|
53
72
|
`tool/call` event is recorded. Execution resolves that snapshot through the event sequence rather
|
|
54
73
|
than reading the latest target when the handler begins. Intervening inspection tools do not erase
|
|
@@ -14,11 +14,13 @@ PTC Plus 0.1.0 deliberately had no Client UI. The runtime surface was the DSH PT
|
|
|
14
14
|
|
|
15
15
|
PTC Plus registers one DSH settings namespace `ptc-plus` with the same field list, defaults and validation as the Host Config schema. The field definitions live once in `internal/config-spec.js`; `index.js` builds the Cordis Config schema from it, and the esbuild client bundle imports the same module so the UI does not copy defaults or validation.
|
|
16
16
|
|
|
17
|
-
The settings card belongs to plugin configuration. Current DSH renders a bundle's own configuration on the sidebar Plugins → Installed page through `plugins.row.config` (keyed, root) as `<bundle package name>#<row id>` and reserves `plugins.item` for the host-plane pages DSH itself ships.
|
|
17
|
+
The settings card belongs to plugin configuration. Current DSH renders a bundle's own configuration on the sidebar Plugins → Installed page through `plugins.row.config` (keyed, root) as `<bundle package name>#<row id>` and reserves `plugins.item` for the host-plane pages DSH itself ships. Historical, unfrozen Hosts use `settings.plugin.item` (keyed, root) in the Settings panel, keyed by the served namespace. `src/client-host-compat.js` publishes to these plugin configuration seats through `ctx.slots.inject`, which waits until the owning page declares its slot. General settings may coexist with plugin configuration and is not a seat for this card. The composer shortcut opens an application-modal rendering of the same complete form, so direct access does not depend on a host page's component-local navigation state; its hover hint names the observed native plugin configuration seat. The package's top-level `icon` field points to a packaged SVG; DSH owns loading and displaying it on the installed bundle and row pages.
|
|
18
18
|
|
|
19
19
|
The settings card places the plugin switch first, then groups controls by purpose: tool call tolerance, REPL syntax, state and recovery, tool extensions, interface display, and resource limits. Recovery tips and their thresholds stay together, and global binding management appears directly below its enable switch. `CONFIG_GROUPS` owns this presentation order independently of Host schema field order and defaults. `autoDescribeRunCode` defaults to true and controls only a request-bound local execution policy. When enabled, a call that omits the outer `description` uses derived arguments for local DSH validation, and the fallback summary enters presentation metadata only; when disabled, DSH validates the original arguments. Both states produce byte-stable model-visible tool schemas, order, and system sections with the required `description` declaration. Original call arguments, explicit summaries, cell source, and nested native-tool arguments remain unchanged.
|
|
20
20
|
|
|
21
|
-
The configurable set is the Host runtime configuration plus `enabled: boolean` (default true). `enabled` is the kill switch: when false the Host keeps the settings namespace, client card, and passive message cleanup defined in [ADR 0010](0010-session-log-derived-recovery-tips.md). The next permitted accepted step may clear earlier PTC declarations. It does not install the runtime bridge, edit transport, direct-surface owner, system prompt section, tool registrations, or execution hooks, and does not read binding storage. When true the same runtime as pre-settings PTC Plus is installed. On the generations that expose a section installer, every field is live when its owner can reconcile it: the Host observes the settings scope and installs, uninstalls, or reconfigures owners without replacing existing session-bound bindings. The
|
|
21
|
+
The configurable set is the Host runtime configuration plus `enabled: boolean` (default true). `enabled` is the kill switch: when false the Host keeps the settings namespace, client card, and passive message cleanup defined in [ADR 0010](0010-session-log-derived-recovery-tips.md). The next permitted accepted step may clear earlier PTC declarations. It does not install the runtime bridge, edit transport, direct-surface owner, system prompt section, tool registrations, or execution hooks, and does not read binding storage. When true the same runtime as pre-settings PTC Plus is installed. On the generations that expose a section installer, every field is live when its owner can reconcile it: the Host observes the settings scope and installs, uninstalls, or reconfigures owners without replacing existing session-bound bindings. The volatile-only settings shape exposed by both frozen Host graphs has no section installer and serves only fields marked volatile in the plugin's exported `Config`; the Host provides the form and commits volatile-only changes into the live references, notifying the owning fiber through the public `loader/volatile-update` event. The plugin subscribes and reconciles through its existing update path instead of running a per-field settings watch. Node fixes a worker's V8 `maxOldGenerationSizeMb` limit at construction, so changing that field while a session worker is active or a submitted cell is preparing to execute is rejected and the settings provider is restored to the previous value; other reconfiguration failures use the same compensation path. The TypeScript language check occurs at activation, allowing disabled settings to load on a host using another code runtime while rejecting and rolling back an enable attempt. If the settings service is absent, the Host falls back to composition config and enables the runtime.
|
|
22
|
+
|
|
23
|
+
The host-only log-fact projection remains owned by the plugin/controller lifecycle when the runtime is disabled, as specified in [ADR 0032](0032-own-session-log-facts-in-a-host-only-projection.md). It supports passive message cleanup without retaining a worker, tool or default model-visible state projection.
|
|
22
24
|
|
|
23
25
|
Every settings-card and PTC Plus tool-row string is registered into the DSH client locale namespace `settings.ptcPlus` and follows the active DSH client locale. Field copy exists in both locales from the single `internal/config-spec.js` source (`label`/`labelEn`, `description`/`descriptionEn`); display chrome copy is owned by the Client half. The stable REPL guidance remains plugin-owned protocol text without UI branding. The transport names remain `run_code`/`edit_run_code`; DSH owns their identity.
|
|
24
26
|
|
|
@@ -34,6 +36,15 @@ Feature notices name actual per-result events rather than configuration defaults
|
|
|
34
36
|
|
|
35
37
|
Runtime activation is transactional. If a live enable cannot complete, every owner acquired before the failing setup step is disposed, the failure is logged, and the settings provider is asked to persist `enabled: false`; a failed compensating write remains an explicit activation diagnostic rather than an unreported state mismatch.
|
|
36
38
|
|
|
39
|
+
The settings compatibility owner binds the write identity when the provider
|
|
40
|
+
appears. A Host-owned `Config` document is addressed by its owning Loader
|
|
41
|
+
entry's profile ID; a historical section installer is addressed by its section
|
|
42
|
+
namespace. Enable-failure and live-reconfiguration compensation use that same
|
|
43
|
+
bound writer, not a fixed namespace substituted for the owning entry. The
|
|
44
|
+
writer and page policy are released with the settings provider.
|
|
45
|
+
|
|
46
|
+
Compatibility evidence and the consequences of removing historical branches are bounded by [Installation: Compatibility Evidence](../installation.md#compatibility-evidence). The two frozen graphs do not establish full Host coverage of the section-installer or settingsScope shapes.
|
|
47
|
+
|
|
37
48
|
## Alternatives Considered
|
|
38
49
|
|
|
39
50
|
1. Keep no Client UI. Rejected: PTC Plus requires a settings surface and a kill switch. Away from settings, users cannot tell whether PTC Plus is actively installed because the only marker is application behavior.
|
|
@@ -24,7 +24,7 @@ Cordis tools remain native program bindings under `tools.*`. The PTC code-only d
|
|
|
24
24
|
|
|
25
25
|
Cordis definitions and Runs are process-local, while PTC journals replay every settled program binding as a recorded value without redispatch. On the first prompt for an agent or a new Cordis enable generation, PTC Plus derives whether normalized journals contain a Cordis transcript. If they do, it emits the fixed `tools:ptc-plus-cordis-recovery` runtime context: recorded values remain journal data, but the model must perform a live read-only Cordis Inspect before relying on prior IDs, state, approvals, or capability observations. The context remains until a newly settled successful `cordis_inspect*` call appears in the session log. It neither asserts that live state was lost nor reruns a mutating call.
|
|
26
26
|
|
|
27
|
-
Companion Skill resolution is capability-based. A generation that publishes an absolute composition path for the shipped `cordis` preset uses its sibling `skills` root. For a pathless generation, PTC Plus asks the Host's public `pluginPackages.packageOf` service for the active installation's `@deepseek-ai/dsh-agent-preset` or `@deepseek-ai/dsh-agent-presets` resource, then selects that generation's known Skill layout. Older generations that do not publish `pluginPackages` may resolve only the historical plural package from the Host's `ctx.baseUrl`; this compatibility path is disabled whenever the service exists, including when it returns no package. It never uses plugin-anchored ambient Node lookup, because a profile or Desktop installation may contain a stale package from another Host generation. PTC Plus accepts a root only when it contains the exact `cordis-plugin-development/SKILL.md`; it does not infer support from a package name or directory alone. An unusable preset (`broken`) is reported as unavailable before path or package resolution, while an invalid published path remains a host contradiction rather than falling through to a different generation.
|
|
27
|
+
Companion Skill resolution is capability-based. A generation that publishes an absolute composition path for the shipped `cordis` preset uses its sibling `skills` root. For a pathless generation, PTC Plus asks the Host's public `pluginPackages.packageOf` service for the active installation's `@deepseek-ai/dsh-agent-preset` or `@deepseek-ai/dsh-agent-presets` resource, then selects that generation's known Skill layout. Each resolution reads the current service after preset resolution; owner creation does not fix later mounts to an earlier service or its absence. Older generations that do not publish `pluginPackages` may resolve only the historical plural package from the Host's `ctx.baseUrl`; this compatibility path is disabled whenever the service exists, including when it returns no package. It never uses plugin-anchored ambient Node lookup, because a profile or Desktop installation may contain a stale package from another Host generation. PTC Plus accepts a root only when it contains the exact `cordis-plugin-development/SKILL.md`; it does not infer support from a package name or directory alone. An unusable preset (`broken`) is reported as unavailable before path or package resolution, while an invalid published path remains a host contradiction rather than falling through to a different generation.
|
|
28
28
|
|
|
29
29
|
## Alternatives Considered
|
|
30
30
|
|
|
@@ -69,7 +69,7 @@ An enabled agent whose effective public tool view contains `run_code` receives `
|
|
|
69
69
|
|
|
70
70
|
Either command appends complete authoring instructions through `agent.steer` and completes admission once the normal Agent turn has been requested. Admission means authoring started, not that a candidate exists. Under enabled configuration, `code.submitBindingDraft({requestId, entry})` is a stable program SDK member, including its discovery schema. It uses the ordinary cell lease and program-call transcript. The Host captures the exact active request at cell creation and checks agent identity, request ID, generation, and single-submission eligibility before and after asynchronous validation. Acceptance, turn stop, error, cancellation, replacement, disablement, or disposal revokes submission eligibility without changing the declaration. No request-specific tool or Skill registration changes the system prefix. Cold replay returns a recorded receipt without submitting again or restoring writable access.
|
|
71
71
|
|
|
72
|
-
The schema, SDK and authoring instructions include both `modelContext` fields. Authoring asks for a declaration-injection choice and a usage prompt containing only information missing from the interface; when types and API comments suffice, the prompt is empty. Edits preserve existing prompt preferences unless the requirement changes them. The workbench exposes both controls directly, without requiring source-edit mode; changes enter an unsaved draft with save and cancel actions. The input-dock review exposes accepted prompt metadata before a user saves it; the command card retains read-only history. Saving as disabled does not add configured API text to ordinary requests.
|
|
72
|
+
The schema, SDK and authoring instructions include both `modelContext` fields. Authoring asks for a declaration-injection choice and a usage prompt containing only information missing from the interface; when types and API comments suffice, the prompt is empty. Edits preserve existing prompt preferences unless the requirement changes them. The workbench exposes both controls directly, without requiring source-edit mode; changes enter an unsaved draft with save and cancel actions. The input-dock review exposes accepted prompt metadata before a user saves it; a zero-height plugin-owned anchor positions a portaled floating preview so disclosure does not resize the transcript or composer. An enlarged public Modal (or its plugin fallback) renders the same candidate and actions, with independently scrolling content and fixed header/footer. Returning to the preview changes only display; the portal yields when the composer entry is not reachable. The preview measures only its own anchor and visual viewport while visible, avoiding Host clipping/stacking without ancestor writes. In very limited space it shows the header and enlarge action. Neither presentation creates another review controller or write authority; the command card retains read-only history. Saving as disabled does not add configured API text to ordinary requests.
|
|
73
73
|
|
|
74
74
|
Authoring uses ordinary `run_code` cells to develop and test pure logic with in-memory inputs, assertions and substitutes. Temporary session variables are permitted; the task prohibits test effects on external files and services. Imports and initializers with unknown effects are reviewed without execution. Tests can guide corrections and comparisons before the final source, exports, types and usage prompt are checked together. The answer reports verified behavior and untested integration, without requiring reasoning transcripts or a fixed number of calls. This is task guidance under DSH authority, not a sandbox or an additional permission mechanism. It does not expose the workbench's candidate runner to the Agent.
|
|
75
75
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
PTC Plus supplies the session-bound REPL by taking over the program-execution
|
|
6
6
|
seam DSH uses for `run_code`. DSH registers that seam as a Cordis service and
|
|
7
|
-
has renamed it between releases:
|
|
7
|
+
has renamed it between releases: a historical request-only generation published
|
|
8
8
|
`ctx.codeRuntime` (`@deepseek-ai/dsh-code-runtime`) and the current one publishes
|
|
9
9
|
`ctx.ptcRuntime` (`@deepseek-ai/dsh-ptc-runtime`). A plugin that declares the
|
|
10
10
|
removed name as a required injection never applies on the current host. Cordis
|
|
@@ -22,10 +22,41 @@ accepts a confinement request it cannot enforce silently weakens DSH's policy.
|
|
|
22
22
|
|
|
23
23
|
## Decision
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
`internal/execution-provider-owner.js` owns public provider composition;
|
|
26
|
+
`internal/execution-seam-compat.js` owns live selection and the request/spec
|
|
27
|
+
boundary. Selection uses the registered capability, not a version string.
|
|
28
|
+
|
|
29
|
+
**Composition owns the routing relationship.** The shipped bundle preserves the
|
|
30
|
+
original `ptc-runtime` row's module and configuration and gives its `ptcRuntime`
|
|
31
|
+
service a named isolation. A separate execution-provider row observes that
|
|
32
|
+
original entry through public Loader resolution and injection, then registers a
|
|
33
|
+
plugin-owned global provider through Cordis. The main plugin installs its
|
|
34
|
+
execution callback only in that provider's private entry. The original service
|
|
35
|
+
is never modified and may be frozen or sealed. Custom compositions configure
|
|
36
|
+
the original entry ID and matching isolation explicitly. Entry IDs resolve in the
|
|
37
|
+
provider row’s owning Loader tree, including the profile’s Include subtree;
|
|
38
|
+
they are not assumed to be root-tree IDs.
|
|
39
|
+
|
|
40
|
+
The execution-provider row remains present when the main plugin is disabled;
|
|
41
|
+
without a callback it delegates native execution and capability getters to the
|
|
42
|
+
original. Its stable adapter follows original-generation replacement, but a
|
|
43
|
+
resolved spec remains bound to the generation that produced it and cannot run
|
|
44
|
+
after that generation retires. Before bundle removal changes the original isolation,
|
|
45
|
+
the public Loader lifecycle withdraws only the plugin's provider registration
|
|
46
|
+
synchronously, leaving the global service slot available for the original to
|
|
47
|
+
return. Cleanup cannot retire a newer registration. A plain, uncomposed provider
|
|
48
|
+
is a deployment error, not a reason to fall back to descriptor mutation.
|
|
49
|
+
|
|
50
|
+
Activation reads the current original generation's language through the live seam.
|
|
51
|
+
The adapter's stable identity does not make its first language a permanent fact;
|
|
52
|
+
an unsupported or unavailable current generation cannot authorize activation.
|
|
53
|
+
The original-generation observer also notifies the installed controller after source
|
|
54
|
+
replacement. An incompatible language retires the active PTC runtime without changing
|
|
55
|
+
the user's enabled setting; returning to TypeScript reconciles it again. Descriptor,
|
|
56
|
+
resolve/run and upstream delegation entries reject an installed-language mismatch
|
|
57
|
+
while that cleanup is pending, so SDK preparation cannot describe a different
|
|
58
|
+
language from the callback's execution. A TypeScript replacement retains the existing
|
|
59
|
+
session runtime. The subscription and its disposer belong to the injected controller.
|
|
29
60
|
|
|
30
61
|
**Selection is a live capability.** The plugin's static injection names only the
|
|
31
62
|
services both generations provide; the seam owner waits through `inject` for
|
|
@@ -48,14 +79,17 @@ failure naming the service; when a preceding-generation attachment exists, the
|
|
|
48
79
|
report accompanies its restoration so `run_code` never silently returns to the
|
|
49
80
|
host provider.
|
|
50
81
|
|
|
51
|
-
**
|
|
82
|
+
**New requests and resolved execution specs remain distinct.** The owner publishes `invokeUpstream`,
|
|
52
83
|
which reproduces each generation's own call shape — directly for
|
|
53
84
|
`run(request)`, and as `run(resolve(request))` for the two-step seam — and
|
|
54
|
-
`
|
|
55
|
-
|
|
56
|
-
`
|
|
57
|
-
|
|
58
|
-
|
|
85
|
+
`installExecute(execute)`, which owns only the plugin provider's private callback
|
|
86
|
+
and returns its disposer. The plugin's entry receives the complete input.
|
|
87
|
+
`runUpstream(spec)` delegates an already resolved spec directly to the original
|
|
88
|
+
provider, retaining its object identity, cwd, deadline, sandbox policy and future
|
|
89
|
+
execution fields. Non-session callers use this path without resolving again.
|
|
90
|
+
Fresh isolated requests still use `invokeUpstream(request)`. Session cells consume
|
|
91
|
+
their program, bindings and signal under the session's own execution contract;
|
|
92
|
+
the boundary never drops fields before choosing which consumer owns execution.
|
|
59
93
|
|
|
60
94
|
**The seam describes the execution the plugin performs.** While the plugin owns
|
|
61
95
|
the seam it also answers the descriptors with its own behavior: no
|
|
@@ -69,10 +103,32 @@ DSH's authority decisions with DSH instead of accepting an input the plugin woul
|
|
|
69
103
|
then ignore. Withdrawal is unconditional rather than generation-conditional,
|
|
70
104
|
because the rule belongs to the plugin's execution rather than to a generation:
|
|
71
105
|
the preceding generation's contract defines none of these members and nothing in
|
|
72
|
-
its install closure reads them, so withdrawing there is inert
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
106
|
+
its install closure reads them, so withdrawing there is inert. These values are
|
|
107
|
+
derived getters on the plugin provider, not replacement descriptors on the
|
|
108
|
+
original. Releasing the private callback restores native delegation and its
|
|
109
|
+
original capability values without any write to the original service.
|
|
110
|
+
|
|
111
|
+
**The tool-result bridge has a separate accepted compatibility boundary.**
|
|
112
|
+
`internal/runtime-bridge-owner.js` retains its wrappers on the registered
|
|
113
|
+
`run_code` definition's `execute` and `output.presentationMeta`. The latter
|
|
114
|
+
publishes execution-local journal, recovery, binding and presentation evidence;
|
|
115
|
+
the former supplies derived execution arguments when an omitted description is
|
|
116
|
+
generated, while the persisted model-authored arguments remain unchanged.
|
|
117
|
+
This bounded use of a shared tool definition is accepted even though public
|
|
118
|
+
lookup does not guarantee mutation support. It requires those properties to be
|
|
119
|
+
redefinable: frozen definitions or outputs reject execution and are not a
|
|
120
|
+
supported compatibility claim. Frozen original execution providers remain
|
|
121
|
+
supported through the independent composition described above.
|
|
122
|
+
|
|
123
|
+
The bridge retains call-local settlement isolation, native canonical values,
|
|
124
|
+
output limits, original callback receivers, and descriptor/ownership restoration
|
|
125
|
+
on rollback or disposal. DSH continues to own validation, policy, approval,
|
|
126
|
+
cancellation and final result projection. Acceptance retains this bridge rather
|
|
127
|
+
than claiming that a public per-execution metadata carrier or raw/derived input
|
|
128
|
+
protocol has been implemented. Replacing it becomes necessary if an official
|
|
129
|
+
Host changes this dependency or publishes an equivalent result/input contract.
|
|
130
|
+
The direct-tool projection has its own accepted boundary in
|
|
131
|
+
[ADR 0005](0005-temporary-rejected-cell-edit-transport.md).
|
|
76
132
|
|
|
77
133
|
## Alternatives considered
|
|
78
134
|
|
|
@@ -90,6 +146,10 @@ plugin would publish a service it does not implement, making this a provider
|
|
|
90
146
|
rather than a consumer, and would have to model the wrapped provider's resolution
|
|
91
147
|
semantics for callers that never reach its REPL.
|
|
92
148
|
|
|
149
|
+
**Replace descriptors on the registered original.** Public service lookup does
|
|
150
|
+
not grant mutation ownership. Such attachment fails on frozen providers and
|
|
151
|
+
cannot establish a durable extension contract; it is not a compatibility fallback.
|
|
152
|
+
|
|
93
153
|
**Forward the resolved spec's directory, deadline, and policy to the session
|
|
94
154
|
kernel.** The kernel has its own directory, budgets, and journal semantics; a
|
|
95
155
|
per-call host deadline would have to be reconciled with the configured budget,
|
|
@@ -101,9 +161,13 @@ escalation it thinks it is offering.
|
|
|
101
161
|
|
|
102
162
|
## Consequences
|
|
103
163
|
|
|
104
|
-
The
|
|
105
|
-
|
|
106
|
-
|
|
164
|
+
The frozen Host graphs exercise the `ptcRuntime` resolve/run shape. The
|
|
165
|
+
`codeRuntime` request-only shape is a historical compatibility branch with
|
|
166
|
+
fixture coverage, not a second frozen Host generation. The evidence boundary is
|
|
167
|
+
recorded in [Installation](../installation.md#compatibility-evidence).
|
|
168
|
+
Seam tests cover selection and input preservation for both shapes. Real public
|
|
169
|
+
Loader tests cover frozen originals, exact configuration and spec delegation,
|
|
170
|
+
main-plugin activation, source replacement and bundle removal. A host that registers neither
|
|
107
171
|
execution service cannot be served, and its activation settles with a bounded
|
|
108
172
|
diagnostic naming the missing seam — `no host execution seam (ptcRuntime or
|
|
109
173
|
codeRuntime) is registered` — after the attachment window instead of staying
|
|
@@ -4,7 +4,7 @@ Date: 2026-09-18
|
|
|
4
4
|
|
|
5
5
|
## Problem
|
|
6
6
|
|
|
7
|
-
PTC Plus publishes its Remote services through DSH's TYPERT registry, and that registry validates every strict codec it is handed before any endpoint exists. The codec carries the decoder for one wire member, and DSH changed where the host reads it:
|
|
7
|
+
PTC Plus publishes its Remote services through DSH's TYPERT registry, and that registry validates every strict codec it is handed before any endpoint exists. The codec carries the decoder for one wire member, and DSH changed where the host reads it: a historical schema-based generation keeps the decoder on `codec.schema` and evaluates `codec.schema.parse(value)`, while the current generation keeps a `create()` factory, rejects a codec without it, and evaluates `codec.create().parse(value)`. The plugin published only the preceding shape, so a release that requires `create` fails registration inside the plugin's own activation: the Host entry never activates and the Client entry reports a failed fiber, although every import, load check, and type-level use still succeeds.
|
|
8
8
|
|
|
9
9
|
## Decision
|
|
10
10
|
|
|
@@ -12,7 +12,7 @@ PTC Plus publishes its Remote services through DSH's TYPERT registry, and that r
|
|
|
12
12
|
|
|
13
13
|
Each generation validates only the member it owns and ignores the other, so one published contract serves whichever shape the installed host implements. Compatibility follows the live acceptance behavior of the registry rather than a release version, and the decoder is published once, so a host that reads both members cannot obtain two different decoders for one wire member.
|
|
14
14
|
|
|
15
|
-
CI registers the packed contract with the installed host's own registry from the frozen official `latest` and `next` graphs (`scripts/dsh-rpc-contract-smoke.mjs`)
|
|
15
|
+
CI registers the packed contract with the installed host's own registry from the frozen official `latest` and `next` graphs (`scripts/dsh-rpc-contract-smoke.mjs`). Both frozen graphs read `create()`; they do not exercise a schema-only Host. Unit fixtures cover `schema.parse`, not a complete historical Host installation. The evidence boundary is [Installation: Compatibility Evidence](../installation.md#compatibility-evidence); passing two graphs must not be reported as packaging verification of both codec shapes.
|
|
16
16
|
|
|
17
17
|
## Alternatives Considered
|
|
18
18
|
|
|
@@ -24,4 +24,4 @@ CI registers the packed contract with the installed host's own registry from the
|
|
|
24
24
|
|
|
25
25
|
## Consequences
|
|
26
26
|
|
|
27
|
-
One plugin build
|
|
27
|
+
One plugin build carries both the historical schema-based and factory-based codec shapes, and the compatibility rule lives in a single module with the decoder published once. A future generation that requires another member, or that rejects a codec carrying a member it does not know, needs this owner updated; the regression test is CI's registration against the installed registry, which fails on the frozen Host graph that changed instead of on the user's machine. The decoder keeps the project's maintained schema runtime, so a host that validates payloads itself still evaluates the same semantics the plugin's own tests exercise through both members.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Own session-log facts in a host-only projection
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
Synchronous prompt consumers repeatedly folded the complete session log and separately scanned historical runtime snapshots and tips. Recovery also read an obsolete Session snapshot API, so removing that API could turn unavailable history into an apparently empty session. Independent caches at each consumer would retain duplicate semantic rules and cannot prove a common observation cut.
|
|
6
|
+
|
|
7
|
+
## Decision
|
|
8
|
+
|
|
9
|
+
`internal/session-journal-recovery.js` owns one synchronous event transition for the executable call/result timeline. Batch cold recovery and the host-only `ptcPlusSessionLog` projection use that same transition. The projection is registered through `sessionProjections` under its injected Cordis effect, has plain JSON state and an explicit state version, and publishes no Client wire view. Irrelevant log-only events return the previous reference.
|
|
10
|
+
|
|
11
|
+
The state preserves pending and ambiguous call identities, turn scope, edit-target claims, prune windows, normalized journals and transcript counts. It stores minimal call evidence and deterministic non-content result identity digests, not a second raw event log. Runtime presentation adds the ordered surface sequence vector and recognized runtime records. Replacement follows surface positions, not numeric sequence ranges: a newly appended replacement can occupy an earlier surface position. Historical notice identity, per-trigger ordinal, cooldown and unresolved escalation counts are updated at event entry; synchronous consumers read those facts without scanning the historical arrays.
|
|
12
|
+
|
|
13
|
+
Asynchronous consumers obtain an immutable cut from the public `sessionQuery.observeSession` reader, use `projectionMode: 'none'`, and release the observation lease. The captured cut is passed through recovery, call matching, no-op confirmation and derived edit execution. Its surface evidence is paired with that cut; a newer live surface cannot silently change an earlier observation. Historical array-backed sessions retain a read-only batch fallback over the shared transition. Missing current services or malformed historical arrays are diagnosed rather than represented as successful empty evidence. Cancellation and Host query failures remain authoritative errors.
|
|
14
|
+
|
|
15
|
+
The log-fact owner belongs to the plugin/controller lifecycle rather than an enabled worker activation. Disabling the runtime therefore leaves this host-only unit available to retract previously delivered PTC messages, while releasing tools, workers and enabled-generation UI projections. Unloading the plugin releases the unit. This does not keep hidden computation alive or inject a model-visible binding projection.
|
|
16
|
+
|
|
17
|
+
Result republication preserves the original settlement position and normalized evidence. A content-only prune clone, including a clone of another clone, is not a new execution, edit target, success or claim settlement. If the original result is absent, the original call position bounds the newly reconstructed chronology; later executions remain later. Tip identities retain their delivery positions so discovering an earlier success does not erase warnings delivered afterward.
|
|
18
|
+
|
|
19
|
+
Projection checkpoints are fold shortcuts only. State version 8 retains each settlement's independent publication index, first-observed index, ordinary/reconstructed classification and normalized run evidence, including ordinary runs without journals. Ordinary-result deduplication retains the first observation's call, event sequence and timeline position; admission requires matching ordinary settlement evidence or an identity-conflict clear, and every ordinary settlement requires its observation. It also retains the processed timeline position and ordered selection clears for turn resets and invalidations. The current frontier must agree with that retained lifecycle history and remain within the processed cut. Latest and editable runs are derived from the newest current-scope publication beyond that frontier; the success index is derived from retained successful publications. Edit targets and claim eligibility at dispatch are reconstructed from first-observed settlements and clears, using the same selection and target capture rules as the live transition. Their source must match the eligible ordinary or derived publication, and both current claim tables must match the reconstructed lifecycle. A late prune reconstruction cannot establish a target for an earlier dispatch. Selected fields and redundant target copies cannot certify their own provenance or chronology, and clones cannot revive a selection across an invalidation frontier. Normalized event facts retain call identity/source, result identity digests and formal source/replacement relations, public prune and turn inputs, journal presence, normalized settlement and recovery-boundary outcomes, and validated rewrites. They retain no result content. Checkpoint admission reconstructs the complete timeline with the same single-event transition used by live folding, then compares every materialized field. Journal/derived/binding facts, ordinary observations, settlements, selection, claims, transcript counters, unavailable evidence, pending/seen identities and the active prune window therefore share one lifecycle interpretation. Typed payload validation and the existing journal/derived/boundary owners validate the retained normalized inputs. The projection also retains presentation input facts: public append/replacement intents, context-step source categories and recognized runtime-message protocol inputs. Ordinary user and assistant content is omitted. These facts align with timeline event identity and drive the same projection transition at admission. The complete reconstructed projection must agree with the checkpoint, including ordered surface nodes, visible records/facts, message indexes, context steps and notice history. A historical catalog record therefore cannot certify its own visibility, and removing all visibility caches cannot suppress an actual append. Prompt consumers continue reading incremental state without raw-log scans. Missing settlements or valid-shaped journal divergences cannot be hidden by deleting their dependent caches. The timeline representation owner validates these relations together with typed table payloads, call/entry identities, normalized journals, derived runs and transcript counts before projection admission. Obsolete v1–v7 state requires refolding the complete log; a nonzero-start suffix alone is rejected with a seq-0 reread diagnostic. The Host owns watermark validation, suffix restore, fork inheritance and refolding. Raw journal ancestry and exact model-visible source relations still own recovery evidence. UI facts, cached state and matching recorded completions are not substitutes.
|
|
20
|
+
|
|
21
|
+
Submitting a cell reserves its memory configuration with the SessionRuntime owner before the first asynchronous observation on either the run or edit entry. The bridge and derived edit carry that same submission and its captured cut into execution rather than creating a second admission after reading. Runtime or session disposal invalidates that preparation, and an invalidated preparation cannot create a kernel or worker after the reader resumes. Reader failure releases the reservation; a genuinely new submission can use a fresh environment. Caller cancellation with an identified cut is settled by the existing cell owner as a no-op without starting a worker; it retains the caller's reason and does not create an unexplained recovery boundary.
|
|
22
|
+
|
|
23
|
+
## Consequences
|
|
24
|
+
|
|
25
|
+
pre-step and assembly read current projected facts rather than materializing history. Recovery and authoring receipt operations are explicit asynchronous reader consumers. Honest checkpoint restore and fork must preserve the same timeline, edit and runtime-message decisions as batch replay. Tests cover serialized transition boundaries, duplicate identities, prune replacement, observation/surface races, real SessionStore/query/registry composition and long unrelated histories.
|
|
26
|
+
|
|
27
|
+
This migration does not change tool names, journal generations, Host policy authority, output governance or the selected PTC language contract. Public execution-provider composition is owned by [ADR 0028](0028-attach-to-the-host-ptc-execution-seam.md), not this projection. Successful-result metadata and two-tool collapse integration remain separate boundaries.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Gate Client Visual Usability In A Browser
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
JSDOM can verify component classes and callbacks while the browser paints unusable controls. Optional smoke scripts and saved screenshots leave key style regressions outside normal verification and provide no automatic verdict for focus or disabled feedback.
|
|
6
|
+
|
|
7
|
+
## Decision
|
|
8
|
+
|
|
9
|
+
The standard local and CI verification entries run one Client suite followed by deterministic browser layout and visual assertions against fresh actual-renderer fixtures. A shared bounded usability oracle owns contrast, action dimensions, reachability and state feedback. Fault counterexamples retain actual DOM classes and handlers and must be rejected. Browser prerequisites are explicit and absence fails verification. The coverage inventory and exceptions are owned by [the Client visual contract](../client-visual-contract.md).
|
|
10
|
+
|
|
11
|
+
Packed official-DSH acceptance remains a separate integration obligation under [ADR 0017](0017-track-the-latest-dsh-public-surface.md). It reuses the oracle on actual Host theme surfaces; fixture palettes do not establish Host compatibility. These checks do not change DSH authority, runtime state, program values or the model's tool surface.
|
|
12
|
+
|
|
13
|
+
## Alternatives considered
|
|
14
|
+
|
|
15
|
+
**Keep browser checks opt-in.** This permits a standard green gate while CSS is absent or state feedback is lost, which does not satisfy the Client usability obligation.
|
|
16
|
+
|
|
17
|
+
**Freeze full-page screenshot baselines.** Such baselines couple plugin acceptance to upstream typography and rendering pixels. Bounded computed-style and hit assertions directly test the product obligation, while screenshots remain useful diagnostics.
|
|
18
|
+
|
|
19
|
+
**Run every browser script independently in the gate.** The layout script would rerun the complete Client suite. Sharing a single fresh fixture generation preserves current-source evidence without that duplication.
|
|
20
|
+
|
|
21
|
+
## Consequences
|
|
22
|
+
|
|
23
|
+
Contributors need the locked Playwright Chromium installation before the full gate. Browser checks add work to verification and fail when their prerequisites are unavailable. Their guarantee is bounded by the declared controls and states; extending a UI responsibility requires extending its inventory and counterexamples rather than promising all future styles.
|
package/docs/architecture.md
CHANGED
|
@@ -32,11 +32,11 @@ DSH 为一个 agent composition 固定选择 `native`、`ptc` 或 `both`。首
|
|
|
32
32
|
`run_code`。无目标或参数不合法时不执行,返回 `{ edited: false, reason }` 并保留原目标。
|
|
33
33
|
进程内 claim 区分 executing 与 settled:抛错、取消或缺少有效 PTC journal 的派生结果立即释放;已由 journal 证明进入 runtime 的派生执行继续占用旧 target,直到外层 result 的私有 metadata 通过最终 policy 并由 session log 投影为新 target。最终 result 丢失 metadata 时由 `tools/result` 释放。session log 投影在 edit call event 处记录 eligible target,只接受 target call sequence 匹配该快照且 journal 有效、非 noop 的派生源码,因此 live 与 cold recovery 从同一持久关系决定可编辑目标。
|
|
34
34
|
|
|
35
|
-
`internal/session-log-view.js`
|
|
36
|
-
|
|
35
|
+
`internal/session-log-view.js` 通过公开 `sessionProjections` 注册 host-only 的 `ptcPlusSessionLog` 单元。同步单事件转移维护最新执行、可编辑目标、rewrite metadata、规范 journal 的 Cordis transcript 计数、已投递提示身份与 cooldown/escalation 事实,以及按公开 surface operation 排序的当前 runtime messages。pre-step 与 assembly 只读该单元,不重新读取或折叠历史;异步恢复通过 `sessionQuery.observeSession` 取得不可变观察切点,派生 edit 与其内层执行共享该切点。旧的 array-backed session 使用同一转移的批量折叠,不修改 Host 状态。详见 [ADR 0032](adr/0032-own-session-log-facts-in-a-host-only-projection.md)。
|
|
36
|
+
`edit_run_code` 不产生专用 runtime context:真实 call/result 已完整表达操作身份和结果,额外 contribution
|
|
37
37
|
会重复已有事实;此类信息不进入独立 PTC 消息。只有缺少有效 journal、无法确认完成状态的 rewrite feedback 才保留独立生命周期;已结算失败的恢复指引由当前结果表达;成功的透明改写不产生 runtime context。
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
执行接入由 `internal/execution-provider-owner.js` 经公开 Loader/Cordis 组合:保留原 row 的模块与配置,将原服务置于 named isolation,另注册插件自有 global provider。`internal/execution-seam-compat.js` 选择该服务并拥有 request/spec 边界;主插件卸载只释放自有 provider 的私有 execution callback,恢复原生委托与能力 getter,不写原实例的 `run` 或描述符。移除完整 bundle 时,Loader 生命周期先同步撤销插件注册,再让原 provider 回到 global slot。`presentationMeta` 仍由 runtime bridge 单独还原;它不属于 provider composition(见 [ADR 0028](adr/0028-attach-to-the-host-ptc-execution-seam.md))。旧 provider generation 不能复活已释放的 session 状态。
|
|
40
40
|
稳定 REPL 指引与执行共同从 `binding-update-policy.js` 取得语言代际。新代际说明 TypeScript、顶层 await/return、静态 import/export 与所选绑定更新策略;旧兼容态才按其独立开关说明支持的模块语法。显式结果使用 return,日志使用 console;原生表达式 completion 同样可以提供结果值。失败恢复先按状态分类:result 已证明解析或 preflight 未执行且提供符合任务意图的 validated repair 时,
|
|
41
41
|
优先直接使用带目标保护的 `edit_run_code`,无需等待 recovery context;该验证只证明语法/preflight 接受。其他小型修正可用 edit 执行完整 cell;
|
|
42
42
|
已执行或可能产生外部 effect 的目标,则必须依据操作 owner 的 retry/idempotence 契约和执行事实判断重跑。短 `run_code` 可以复用仍存活的 binding,但缩短源码不能证明幂等。能力和命令执行依赖当前 request
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Binding 草稿在当前输入框上方展示
|
|
2
2
|
|
|
3
|
-
状态:完整草稿由已发布的 `conversation.input.dock`
|
|
3
|
+
状态:完整草稿由已发布的 `conversation.input.dock` 承载;历史命令位置只保留请求和只读来源。面板由公开 dock 内的零高度锚点悬浮承载,放大使用公共 Modal,不读取宿主内部几何结构,验收以正式打包后的浏览器实际行为为准。
|
|
4
4
|
|
|
5
5
|
## 产品目标与分发边界
|
|
6
6
|
|
|
@@ -25,7 +25,7 @@ PTC Plus 必须独立安装到未经修改的官方 DSH,不能修改宿主源
|
|
|
25
25
|
原生回答尾部、文件产物与操作
|
|
26
26
|
──────────────────────────
|
|
27
27
|
当前输入区
|
|
28
|
-
PTC Plus
|
|
28
|
+
PTC Plus 零高度草稿锚点(预览向上悬浮,不占正文高度)
|
|
29
29
|
名称、用途、导出信息
|
|
30
30
|
完整源码与模型上下文(默认展开,内部可滚动)
|
|
31
31
|
保存为停用 / 保存并启用 / 丢弃
|
|
@@ -33,14 +33,16 @@ PTC Plus 必须独立安装到未经修改的官方 DSH,不能修改宿主源
|
|
|
33
33
|
用户输入框
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
插件以独立 id `ptc-plus-binding-review`
|
|
36
|
+
插件以独立 id `ptc-plus-binding-review` 注册,`order: -30` 将本贡献置于普通 dock 卡片之前。自有锚点留在公开 slot 中但高度为零,面板在 Portal 内从锚点向上 fixed 展开;展开或折叠不改变对话或输入框几何。其他贡献保持各自顺序与布局,预览可覆盖其上方的历史内容,但不向下覆盖普通 dock 卡片或输入框。插件在预览可见时逐帧读取自有锚点,只有几何变化时更新位置与高度预算;只读取 visualViewport 和自有节点,不探测普通 composer 的祖先或宿主滚动容器。CSS 有效预算容不下实际标题、操作行和最小正文时仅呈现标题及放大、关闭按钮;若连完整标题也放不下,则让出预览,保留输入区和历史请求的审阅入口;用户从入口打开时直接放大,关闭放大后焦点回到输入区入口。扩大视口后按原有展示选择恢复。
|
|
37
|
+
|
|
38
|
+
“放大查看绑定草稿”通过公共 Modal 或既有回退组件展示同一候选与动作。该模式仅是 review controller 的展示选择,不新增 RPC、写资格或候选来源。弹窗正文独立滚动,标题和底部动作保持可见;Escape、遮罩或缩小按钮恢复展开预览,已确认保存或丢弃则关闭全部当前展示。
|
|
37
39
|
|
|
38
40
|
该落点不参与 Chat 节点排序,不占用 `turnTail` 的 chain,也不需要调用原生 renderer 再拆解其结果。宿主继续拥有正文、原生尾部、文件产物、分支和滚动容器;插件拥有面板内部渲染与样式。不得用额外的虚假事件把 UI 布局写进 session log。
|
|
39
41
|
|
|
40
42
|
| 方案 | 适用性与本次选择 |
|
|
41
43
|
| --- | --- |
|
|
42
|
-
| `conversation.input.dock`
|
|
43
|
-
|
|
|
44
|
+
| `conversation.input.dock` 中的悬浮预览 | 已发布的 session list 提供会话生命周期和输入区锚点;零高度锚点消除展开对对话高度的影响,内部滚动保留完整内容。 |
|
|
45
|
+
| 公共 Modal 的 Portal | 放大审阅采用此路径;仅在当前输入入口可见时打开,宿主接管时隐藏,保留同一候选与展示选择。 |
|
|
44
46
|
| 替换公开 renderer,再组合公开组件 | 公共契约支持时可以使用;本需求无需接管原生回答渲染。没有公开的“下一个 renderer”入口时,不假定可以组合任意注册项。 |
|
|
45
47
|
| 独立 Conversation 节点 | 适合需要历史位置的业务内容;当前目标不需要,而且同轮尾部节点可能改变原生分支资格。 |
|
|
46
48
|
| 命令位置或原生操作行 | 前者位置过早,后者是紧凑操作区;不作为当前完整审阅的落点。 |
|
|
@@ -79,7 +81,7 @@ PTC Plus 必须独立安装到未经修改的官方 DSH,不能修改宿主源
|
|
|
79
81
|
| 没有可展示的当前候选或已确认回执 | dock 不占空间;历史请求及其已有候选仍可只读查看,不从历史挑一份升级为当前草稿。 |
|
|
80
82
|
| 编写中 | 原命令条目保留已有编写状态;dock 不重复展示一份编写请求,也不把上一份草稿冒充本次结果。 |
|
|
81
83
|
| 已接受,正在确认操作资格 | 新候选首次在 dock 展开,操作按钮暂不可用并说明正在载入。目录读取慢不应让已知源码消失;用户主动折叠或关闭后,读取完成不强制展开。 |
|
|
82
|
-
| 当前草稿可用 |
|
|
84
|
+
| 当前草稿可用 | 按用户选择保持展开、放大、折叠或关闭;展开时显示完整内容和模型上下文,保留保存为停用、保存并启用、丢弃及既有 revision 冲突处理。 |
|
|
83
85
|
| 保存或丢弃成功 | 确认精确候选的处理结果后自动关闭面板;历史保留精确候选和有证据的 action。保存不等于会话已激活。 |
|
|
84
86
|
| 编写失败或旧草稿恢复 | 原请求只显示上述证据规则支持的状态;缺少证据时显示编写结果未知。没有已接受候选就不产生完整 dock 卡片。Host 恢复旧草稿时沿用该候选的展示选择,不自行改变 fallback 规则。 |
|
|
85
87
|
| 资格撤销、Host 重启或只剩历史证据 | 对仍能证明属于当前显示内容的候选保留只读查看;撤下写操作。没有当前身份时不把历史重新挑成活动草稿。 |
|
|
@@ -87,7 +89,7 @@ PTC Plus 必须独立安装到未经修改的官方 DSH,不能修改宿主源
|
|
|
87
89
|
| 切换会话、断线重连、分支或 seed | 按新会话 projection 重建;加载期间禁止沿用旧会话内容和写权限。历史可见性与当前资格分别判断。 |
|
|
88
90
|
| 禁用功能、释放 slot 或卸载插件 | 释放本功能拥有的订阅、计时器和面板;不自动保存、丢弃或执行候选。 |
|
|
89
91
|
|
|
90
|
-
同一会话只保留一个当前完整审阅 controller,按会话、请求、版本和 locator 隔离异步读取与动作。`conversation.chat.commandview` 的 `binding` key 继续渲染原有编写请求,不能因 dock 已注册、已出现或被关闭而返回空内容。保留 `BindingCommandCard`
|
|
92
|
+
同一会话只保留一个当前完整审阅 controller,按会话、请求、版本和 locator 隔离异步读取与动作。`conversation.chat.commandview` 的 `binding` key 继续渲染原有编写请求,不能因 dock 已注册、已出现或被关闭而返回空内容。保留 `BindingCommandCard` 的请求外观和状态区,只移走候选详细内容及写操作。所需展示能力可用且该请求精确对应尚未处理的当前候选时,必须提供“打开草稿”入口,直接进入同一候选的放大审阅,不重新执行 `/binding`;隐藏编写按钮的设置不影响该入口。历史主动查看仍可展开只读源码,但接受候选不得自动展开历史详情,也不能在历史中恢复保存或丢弃按钮。
|
|
91
93
|
|
|
92
94
|
现有页头 popover 的候选展示与保存/丢弃入口也应收拢:保留状态与管理入口,不再创建第二套当前草稿写入流程。历史只读内容可以复用展示组件,但不能恢复控制器或写权限。
|
|
93
95
|
|
|
@@ -95,49 +97,51 @@ PTC Plus 必须独立安装到未经修改的官方 DSH,不能修改宿主源
|
|
|
95
97
|
|
|
96
98
|
写操作仍使用 `save-draft` / `discard-draft`,传递现有 capability、version 及适用的 expected revision。请求切换、组件卸载或资格变动后的迟到响应不能恢复旧按钮;一次失败读取不证明候选已被撤销。待决写入按精确候选隔离:同一候选不重复提交,接受新候选后可独立读取资格和操作,旧响应不能阻塞新候选或清除其 busy 状态。已有必要的资格刷新可以复用,但不能为确定位置或等待回答结束新增轮询、事件订阅或第二套状态机。
|
|
97
99
|
|
|
98
|
-
##
|
|
100
|
+
## 折叠、展开、放大、关闭与重新打开
|
|
99
101
|
|
|
100
|
-
|
|
102
|
+
预览标题栏由折叠/展开按钮、独立放大按钮和独立关闭按钮组成。标题、状态与箭头属于同一个原生折叠/展开按钮,Enter 和 Space 使用原生按钮语义;放大和关闭动作不属于该切换区域,两个操作间距为 12px。放大窗口保留独立的缩小与关闭按钮:缩小恢复预览,关闭隐藏整个草稿面板。展开时箭头朝下表示收起,折叠时朝上表示展开,状态与 `aria-expanded` 一致,并遵循减少动画的系统偏好。完整内容默认展开不等于禁止用户收起。
|
|
101
103
|
|
|
102
104
|
| 用户操作 | 展示结果与草稿状态 |
|
|
103
105
|
| --- | --- |
|
|
104
|
-
| 折叠 |
|
|
106
|
+
| 折叠 | 悬浮预览保留名称、状态、展开、放大和关闭按钮,收起正文及保存/丢弃操作;不改变候选或编写事务。 |
|
|
105
107
|
| 展开 | 未处理候选在原 dock 位置恢复完整内容;已处理候选仅从历史请求查看。写操作仍以当前 Host 证据为准。 |
|
|
108
|
+
| 放大 | 公共 Modal 或既有回退组件显示同一候选;标题和操作保持可见,正文独立滚动。Escape、遮罩或缩小按钮明确恢复展开预览;预览无法完整显示时将焦点返回自有输入区入口。 |
|
|
106
109
|
| 关闭 | 隐藏整个 dock 面板,不保存、不丢弃、不取消编写,也不删除历史请求。 |
|
|
107
|
-
| 重新打开 |
|
|
110
|
+
| 重新打开 | 输入框星光按钮的草稿菜单或当前历史请求的“打开草稿”直接进入同一当前候选的放大审阅;不依赖隐藏期间缓存的预览几何,不重新发命令、生成候选或创建第二个操作 controller。 |
|
|
108
111
|
| 丢弃草稿 | 仅明确点击“丢弃”才调用既有 Host RPC;它与关闭面板是不同操作。 |
|
|
109
112
|
|
|
110
|
-
公开 `conversation.input.left` 只注册一个星光图标,统一插件设置快捷访问、全局绑定管理、编写与当前草稿访问。图标在悬浮或聚焦时以插件署名提示说明来源与用途,有未处理候选时改为提示草稿状态。首条消息前即可通过悬停、点击或方向键打开官方 `Menu
|
|
113
|
+
公开 `conversation.input.left` 只注册一个星光图标,统一插件设置快捷访问、全局绑定管理、编写与当前草稿访问。图标在悬浮或聚焦时以插件署名提示说明来源与用途,有未处理候选时改为提示草稿状态。首条消息前即可通过悬停、点击或方向键打开官方 `Menu`;设置条目直接打开复用完整设置表单的应用内窗口,悬浮提示保留宿主原生设置路径;全局绑定展示名称、用途及启用状态,点击条目切换对所有会话生效的启用配置,并可打开既有完整工作台。有未处理候选时显示数量角标,菜单中单独分组,按名称与状态选择候选后直接放大审阅。菜单中的“编写新绑定”沿用既有命令可用性与输入保护;“修改绑定”是同一个 `Menu` 的第二个步骤,列出已有全局条目,选择后以相同保护预填 `/binding edit <id> `。当前 Host 每会话只保留一份当前草稿,因此角标为 `1`,不把历史候选计为待处理草稿。草稿访问不依赖命令服务;隐藏编写快捷入口时保留已有草稿的星光图标,但不显示全局目录、管理与新建操作。插件与全局绑定功能开关仍统一控制整个入口。
|
|
111
114
|
|
|
112
|
-
|
|
115
|
+
当前宿主菜单使用公共 Portal 和 `getAnchorRect`,以触发按钮自身为锚点定位,按按钮上沿之上的实际可用空间限制插件内容节点的高度;插件通过公开 `Menu.children` 将绑定列表放入可收缩的独立滚动区,新建、修改、管理与设置操作留在不收缩的固定底栏;修改步骤的“返回”也放在底栏,不向宿主菜单节点写入样式。启用、停用分组显示数量,启用项优先,停用项每次打开菜单时默认折叠且隐藏行不渲染。短视口隐藏编写区的文字标题,保留可访问名称和全部按钮。悬停停留 150ms 的意图延迟后才打开菜单,指针扫过输入区不弹出菜单;点击与方向键路径不受延迟影响。菜单由外部点击或 Escape 关闭。悬停打开的菜单在指针离开触发器与列表 200ms 后关闭,重新进入列表或触发器即取消;该宽限覆盖指针短暂离开整个菜单的瞬间,因此越过输入区选择条目仍然可行。点击打开的菜单保持到显式关闭。点击与方向键打开时聚焦首个可用操作,Tab 可到达新建、修改和管理操作;进入“修改绑定”步骤后焦点移到第一个条目。候选变化、会话切换、功能关闭、卸载或普通输入区被接管时关闭菜单;普通刷新不关闭菜单。菜单选择必须向同一 review controller 传递精确候选,不能把旧项点击重定向到新候选。星光菜单和原请求的手动草稿入口直接放大审阅,避免依赖预览关闭期间的旧几何事实;返回预览明确选择 `expanded`,不会重新打开弹窗。原请求条目中的入口也只能打开其精确对应的当前候选;旧请求只允许查看自己的只读历史。展示能力暂不可用时,不提供实际无法打开面板的操作。
|
|
113
116
|
|
|
114
|
-
全局目录由现有 `list` Remote
|
|
117
|
+
全局目录由现有 `list` Remote 按菜单打开动作读取,不轮询;读取在后台进行,期间菜单沿用上一次已确认的目录并保持条目可操作。显式“重新加载”调用 `reload` 重新读取存储文件并清除已修复的读取错误。启停沿用 `enable`/`disable` 与 `expectedRevision`。catalog source 串行化写入并丢弃重复请求,写入期间行保持可用,关闭菜单不取消已发出的操作。启停后条目归入对应分组;菜单仍持有焦点时跟随原条目,原条目进入折叠停用组时回到组按钮。焦点已移出或菜单已关闭时不抢焦点。焦点资格由当前菜单的实际焦点事件拥有,不能沿用待决操作发起时的旧快照;待决写入期间重开菜单后取得的新焦点仍可恢复。打开、步骤切换和归组恢复共用自有列表内的显示操作:适合滚动区的目标靠近最近边缘显示,短窗口下更高的目标居中,只调整自有目录的 `scrollTop`,不滚动底栏或宿主对话。冲突或失败后撤下过期目录,用户重新读取后再决定是否重试,不自动重发写入。重连和组件释放使旧响应失效;菜单读取、显示和启停配置不执行绑定源码。菜单明确区分全局启用配置与待处理草稿,角标只统计草稿。
|
|
115
118
|
|
|
116
|
-
展示选择以 `(sessionId, requestId, candidateVersion)`
|
|
119
|
+
展示选择以 `(sessionId, requestId, candidateVersion)` 归属,包含 `expanded`、`enlarged`、`collapsed`、`hidden` 四种本地状态。当前 Client 内切换会话再返回、RPC 刷新、重连、普通消息追加以及审批临时接管,不重置同一候选的选择;真正接受的新候选默认展开,并从该候选的内容顶部开始阅读;同一候选的普通刷新保留滚动位置。刷新页面或重新加载插件后按当前有效候选恢复默认展开,不要求把展示偏好写入持久存储。共享此选择只协调插件视图,不承载 locator 或 Host 事务资格,也不增加 session log、模型消息或管理 RPC。
|
|
117
120
|
|
|
118
121
|
显隐选择不影响业务操作;精确候选一旦确认保存或丢弃成功,当前面板自动关闭。失败或结果待确认时保留用户的显隐选择:
|
|
119
122
|
|
|
120
123
|
| 结算时的展示选择 | 保存或丢弃已确认成功 | 写入失败或结果待确认 |
|
|
121
124
|
| --- | --- | --- |
|
|
122
125
|
| `expanded` | 自动关闭;回执与精确源码从原请求只读查看。 | 保留完整面板并展示错误或待确认状态;仅在重新证明可写后允许手动重试。 |
|
|
126
|
+
| `enlarged` | 释放弹窗;回执与精确源码从原请求只读查看。 | 保留放大窗口,错误和重试入口随正文滚动;仅在重新证明可写后允许手动重试。 |
|
|
123
127
|
| `collapsed` | 自动关闭;原请求显示处理结果。 | 保持折叠,标题提示有错误或结果待确认,允许用户展开查看。 |
|
|
124
128
|
| `hidden` | 保持关闭,不弹回执;原请求展示有证据的处理结果。 | 保持关闭,保留就近重新打开入口并提示有待查看状态,不自动展开或重试。 |
|
|
125
129
|
|
|
126
130
|
关闭或折叠待决操作中的面板不取消已发出的保存/丢弃 RPC;操作结算仍由同一 controller 接收。未确认处理结果时保留当前候选的访问入口,但入口不证明可以再次写入;一次网络错误不能触发重新提交。已确认保存或丢弃后移除两个当前草稿打开入口,结果和精确候选继续从原历史请求只读查看。确认结果统一由当前 controller 收敛:保存响应、精确 review RPC 或 projection 回执均关闭匹配候选,普通刷新不能重新打开;旧候选的迟到结果不能关闭新草稿。locator 撤销本身不证明处理成功。
|
|
127
131
|
|
|
128
|
-
|
|
132
|
+
用户关闭时,焦点移到就近且可见的星光按钮,聚焦本身不弹出菜单;按钮缺席时使用仍可见的插件自有入口。当前公开契约没有 composer 焦点接口,焦点恢复只操作这些自有返回目标;入口不可用时不查找宿主编辑器。成功后自动关闭仅在面板原本持有焦点时恢复焦点,不能打断用户在其他区域的操作。异步成功移除当前聚焦的打开入口时也应保持合理焦点,不能将其留在已移除节点;宿主接管时不从审批界面抢焦点。折叠按钮提供 `aria-expanded`,被隐藏的内容不得继续接受键盘焦点。
|
|
129
133
|
|
|
130
134
|
## 输入区接管与布局边界
|
|
131
135
|
|
|
132
136
|
官方普通 composer 是 `conversation.composer` chain 的 fallback。当前实现使用 `overlay: true`:其他 contribution 被选中时,fallback 保持挂载但被 `display:none` 隐藏,因此 input dock 也会隐藏。**注册成功不等于任何时候都可见;隐藏也不等于已卸载。**
|
|
133
137
|
|
|
134
|
-
|
|
138
|
+
审批或其他宿主交互接管输入区时,草稿区和重新打开入口随普通输入框一起暂时让位。放大弹窗由输入入口的自有 IntersectionObserver 可见性证明控制 open,入口不可见时释放 Portal 展示,但保留放大选择;不会把保存按钮强行叠到审批上。PTC Plus 的 REPL 视图接管 composer 时也按此规则隐藏;回到普通输入区后恢复同一份有效草稿及其原有展开、放大、折叠或关闭选择。重建时读取 projection 和 RPC,不依靠隐藏 DOM 保留权限。长驻 controller 必须能处理隐藏期间的撤销;用于刷新资格的任务仍受功能和会话生命周期约束,不能只依赖 unmount 清理。
|
|
135
139
|
|
|
136
140
|
普通对话中的正文继续流式输出、产生工具结果或开始下一轮,不是隐藏卡片的理由。所需边界是“普通输入区是否被宿主接管”,不能把 `input` 的任意 busy 状态当作隐藏条件,也不要求用户等待真实轮次结束。
|
|
137
141
|
|
|
138
|
-
|
|
142
|
+
面板采用不透明主题底色、细边框与阴影,明确表达临时浮层;插件拥有的标题、滚动正文和操作区以分隔线区分。名称只在标题出现,正文保留导出信息、用途、完整源码及模型上下文;丢弃与保存动作分置两侧,窄屏允许换行。预览以 dock 的插件自有零高度锚点为基准,宽度不超过 `44rem`;普通宽度两侧留 `16px`,窄屏两侧留 `8px`。预览通过 Portal 挂到 `document.body`,使用自有锚点与 visual viewport 的坐标定位;不读取或修改宿主祖先。
|
|
139
143
|
|
|
140
|
-
|
|
144
|
+
长内容必须保留完整文本并在内部滚动,不能以截断源码换取高度。预览以 `min(440px, 45dvh, 锚点上方可用高度)` 为上限;正文伸缩,保留至少 `40px` 的滚动窗口并以 `20rem` 为上限。CSS 拥有有效高度预算,以实际标题及面板边框判定预览是否可展示,不能为保留标题向下跨越锚点;正文最小高度计入分隔边框,保证至少 40px 的可滚动内容高度。若预算容不下标题、最小正文和实际操作行,预览只显示标题及放大、关闭入口,隐藏内容不可聚焦。放大弹窗使用独立的大尺寸预算,不继承预览和 `20rem` 限制;标题、操作行固定,完整源码、上下文及错误消息在正文内滚动。短视口使用更小外部留白,操作按钮按实际宽度换行。展开与折叠只改变零高度锚点上的插件浮层,不为定位读取宿主祖先、滚动容器或私有 CSS。隐藏、处理成功和卸载释放插件自己的交互状态,不持续滚动正文。浏览器验收同时检查实际点击命中、小视口下输入框与其他 dock 的可达性,不能仅凭注册成功或静态截图证明可用。
|
|
141
145
|
|
|
142
146
|
源码和模型上下文默认展开。历史详情和 dock 共用只读模型上下文区,以“接口声明”状态标签说明是否向模型提供,并单独呈现完整提示词或空状态;不使用禁用的表单控件表示配置。当前卡片不采用 hover 才显现的布局,不自动抢焦点或持续调用 `scrollIntoView`。键盘可进入内容滚动区和所有动作,窄屏操作行允许换行,动态视口下仍能访问输入框与审批。共享 list 的顺序只管理本插件贡献,不重排其他插件。
|
|
143
147
|
|
|
@@ -164,9 +168,9 @@ slot 的迟到、释放、再次声明和功能开关必须测试。缺少所需
|
|
|
164
168
|
| --- | --- |
|
|
165
169
|
| 官方安装 | 正式 tarball 安装成功,Host 源码和安装文件不变,实际加载最终插件 bundle。测试 fixture 自行声明 slot 不能替代此项。 |
|
|
166
170
|
| 请求与位置 | `/binding new`、`edit` 发出时保留历史中原有的绑定编写请求样式;接受后只更新请求状态,完整详情和写操作首次在 dock 展开,原条目不消失也不变成完整操作卡片。 |
|
|
167
|
-
| 展示控制 | 点击折叠态的标题文字即可展开,Enter/Space
|
|
171
|
+
| 展示控制 | 点击折叠态的标题文字即可展开,Enter/Space 同样可用,箭头随状态变化;展开/折叠不改变锚点、composer 和对话滚动范围;放大后正文具有更大阅读高度、独立滚动和固定动作,缩小返回预览,独立关闭按钮隐藏面板;浏览器验收比较完整 composer 几何与对话高度,并确认输入框、其他 dock 和面板操作可达。正文滚动范围继续由宿主布局决定。关闭仅隐藏,输入框旁与当前请求都能重新打开;同一候选的 RPC 更新、重连、普通消息和审批接管不覆盖用户选择,新候选首次展开。 |
|
|
168
172
|
| 内容与操作 | 精确源码和模型上下文默认可读;保存为停用、保存并启用、丢弃、busy、冲突、失败及回执正确。 |
|
|
169
|
-
| 结算与显隐 |
|
|
173
|
+
| 结算与显隐 | 保存或丢弃过程中分别保持展开、放大、折叠和关闭,验证成功、失败及结果待确认组合。已确认成功自动关闭面板并释放弹窗;已处理后的两个当前入口移除,回执与源码从原请求只读访问。 |
|
|
170
174
|
| 请求状态证据 | A 已有草稿,B 命令成功准入后未接受候选,projection 回到 A;B 在重新挂载、分页和重连后显示准入成功及编写结果未知,不能冒用 A 的 ready 或推断失败。命令处理错误、匹配 projection 的 failed、接受及 action 各自只归到对应请求。 |
|
|
171
175
|
| 候选与异步 | 新请求、旧请求恢复、跨会话、迟到 RPC、断线、重启、分支和 seed 不串候选,不以历史或旧 locator 恢复写权限。 |
|
|
172
176
|
| 唯一控制器 | 命令处和页头不再同时出现另一套当前保存控件;折叠或关闭期间的写操作不会丢失结算或重复提交。主动展开历史仅只读,分页不重新挂载活动控制器。 |
|
|
@@ -178,6 +182,10 @@ slot 的迟到、释放、再次声明和功能开关必须测试。缺少所需
|
|
|
178
182
|
|
|
179
183
|
按项目 ledger 流程记录实施发现,按预先声明的独立 review lanes 取得各 lane 的有效 verdict,最终在稳定树上依次运行 `npm run check`、用 `npm run review:finalize` 记录 composite verdict,再运行 `git diff --check HEAD --`。独立审查、确定性测试、实际 UI 验收是不同证据;不能把其中任一项替代其余。提交与发布仍遵循用户授权及独立审查条件。
|
|
180
184
|
|
|
185
|
+
悬浮预览可能随多行输入或其他 dock 而被宿主可视区域裁剪。预览只读取自有零高度锚点与 visualViewport,定位独立 Portal 并收紧自有 `max-block-size`,不遍历或读取宿主祖先来推算剩余空间。
|
|
186
|
+
预览关闭、放大、输入入口不可见或卸载时释放动画帧跟踪。
|
|
187
|
+
放大弹窗不沿用预览的尺寸预算,使用 Modal 的视口限额和内部 flex 正文。这种自有尺寸治理不声明可以重新布局其他贡献,也不取得宿主滚动权限。
|
|
188
|
+
|
|
181
189
|
## 公共契约与历史证据
|
|
182
190
|
|
|
183
191
|
已核对官方源码中的 slot 声明、原生根布局和贡献实例,以及已安装官方包的类型声明与实际 Client bundle 中的 dock 渲染。它们证明接口存在及设计落点可用,尚不证明 PTC Plus 面板已实现或完成浏览器验收。
|