dsh-ptc-plus 0.5.3 → 0.5.6
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 +3 -3
- package/README.md +3 -3
- package/client.cjs +3326 -2881
- package/compiler-core.cjs +127 -127
- package/compiler-core.cjs.map +2 -2
- package/docs/README.md +1 -0
- package/docs/adr/0005-temporary-rejected-cell-edit-transport.md +2 -2
- package/docs/adr/0017-track-the-latest-dsh-public-surface.md +4 -4
- package/docs/architecture.md +1 -1
- package/docs/capability-planning-components.md +6 -6
- package/docs/capability-projection.md +1 -1
- package/docs/capability-surface.md +133 -0
- package/docs/client-ui.md +17 -15
- package/docs/client-visual-contract.md +7 -7
- package/docs/installation.md +14 -7
- package/docs/panel-concept.md +171 -0
- package/docs/publishing.md +1 -1
- package/docs/release-notes.md +1 -1
- package/docs/releases/v0.5.4.md +79 -0
- package/docs/releases/v0.5.5.md +41 -0
- package/docs/releases/v0.5.6.md +41 -0
- package/docs/runtime-reference.md +14 -0
- package/docs/verification.md +1 -1
- package/index.js +117 -30
- package/internal/binding-adoption.js +103 -11
- package/internal/capability-command-receipt.js +99 -15
- package/internal/capability-environment.js +1108 -348
- package/internal/capability-plan.js +18 -2
- package/internal/capability-policy.js +13 -0
- package/internal/capability-selection.js +330 -0
- package/internal/direct-surface-owner.js +17 -4
- package/internal/edit-transport-owner.js +3 -2
- package/internal/host-tool-sdk.js +17 -29
- package/internal/message-sources.js +21 -0
- package/internal/program-bindings.js +13 -4
- package/internal/runtime-bridge-owner.js +9 -9
- package/internal/runtime-config.js +10 -0
- package/internal/session-log-view.js +47 -5
- package/internal/settings-compat.js +6 -0
- package/internal/user-bindings-owner.js +20 -3
- package/package.json +45 -31
- package/src/client-authoring-view.js +7 -8
- package/src/client-capabilities-view.js +871 -948
- package/src/client-capability-sort.js +22 -9
- package/src/client-copy.js +116 -294
- package/src/client-settings-view.js +90 -33
- package/src/client-styles.js +67 -19
- package/src/client.js +46 -21
- package/internal/capability-delivery-proof.js +0 -70
|
@@ -9,9 +9,38 @@ import { deepEqualJson, isJsonValue } from '@deepseek-ai/dsh-util-values'
|
|
|
9
9
|
import { deepFreeze, isRecord } from './record-utils.js'
|
|
10
10
|
import { advanceRuntimeHistory, createRuntimeHistory } from './recovery-tips.js'
|
|
11
11
|
|
|
12
|
-
import { isHostRuntimeContextSource } from './message-sources.js'
|
|
12
|
+
import { isHostRuntimeContextSource, isPtcMessageSource } from './message-sources.js'
|
|
13
|
+
import { BINDING_ADOPTION_FORM, readBindingAdoption } from './binding-adoption.js'
|
|
13
14
|
const SYSTEM_PROMPT_CLEARED = 'Current runtime context: none. Earlier runtime-context snapshots no longer apply.'
|
|
14
15
|
|
|
16
|
+
/**
|
|
17
|
+
* A PTC binding-adoption statement, readable or not.
|
|
18
|
+
*
|
|
19
|
+
* The fold has to recognize the statement even when this build cannot resolve its
|
|
20
|
+
* wording: the fact it keeps is what a restored checkpoint replays, so a fact that
|
|
21
|
+
* dropped the form could not reproduce the record the fold appended.
|
|
22
|
+
*/
|
|
23
|
+
function isBindingAdoptionStatement(message) {
|
|
24
|
+
const source = message?.source
|
|
25
|
+
return isPtcMessageSource(source) && source.form === BINDING_ADOPTION_FORM
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* An adoption statement this build cannot resolve, kept as the statement it is.
|
|
30
|
+
*
|
|
31
|
+
* Both the panel and the `/binding` command answer from this projection, and the
|
|
32
|
+
* answer has to be this session's *newest* statement. A projection that dropped a
|
|
33
|
+
* statement it could not resolve would let the record the session superseded answer
|
|
34
|
+
* instead, so the statement is retained with no declined list — the absence is what
|
|
35
|
+
* marks it unreadable. It never reaches the model-visible surface, which is built
|
|
36
|
+
* from resolvable runtime messages only.
|
|
37
|
+
*/
|
|
38
|
+
function unreadableBindingAdoption(message) {
|
|
39
|
+
if (!isBindingAdoptionStatement(message)) return undefined
|
|
40
|
+
if (readBindingAdoption(message) !== undefined) return undefined
|
|
41
|
+
return Object.freeze({ form: BINDING_ADOPTION_FORM })
|
|
42
|
+
}
|
|
43
|
+
|
|
15
44
|
/** DSH's empty aggregate uses an exact owner marker without a snapshot form. */
|
|
16
45
|
export function systemPromptSnapshotSections(message) {
|
|
17
46
|
const source = message?.source
|
|
@@ -72,7 +101,8 @@ export function runtimeMessageFacts(records, initial = {}) {
|
|
|
72
101
|
|
|
73
102
|
function presentationEvent(event) {
|
|
74
103
|
const recognized = event?.type === 'user/message'
|
|
75
|
-
&& (systemPromptSnapshotSections(event.data) !== undefined || readRuntimeMessage(event.data) !== undefined
|
|
104
|
+
&& (systemPromptSnapshotSections(event.data) !== undefined || readRuntimeMessage(event.data) !== undefined
|
|
105
|
+
|| isBindingAdoptionStatement(event.data))
|
|
76
106
|
const data = recognized ? { source: event.data.source, content: event.data.content }
|
|
77
107
|
: event?.type === 'user/message' && typeof event.data?.source?.kind === 'string'
|
|
78
108
|
? { source: { kind: event.data.source.kind } } : undefined
|
|
@@ -86,11 +116,14 @@ function applyLogEvent(state, event, index = event?.seq,
|
|
|
86
116
|
timeline = advanceSessionTimeline(state.timeline, event, index)) {
|
|
87
117
|
const sections = event?.type === 'user/message' ? systemPromptSnapshotSections(event.data) : undefined
|
|
88
118
|
const ptc = event?.type === 'user/message' ? readRuntimeMessage(event.data) : undefined
|
|
119
|
+
// An adoption statement this build cannot resolve is still this session's statement,
|
|
120
|
+
// so it stays in the projection as the newest one rather than disappearing.
|
|
121
|
+
const unresolvedAdoption = ptc === undefined ? unreadableBindingAdoption(event?.data) : undefined
|
|
89
122
|
const contextStep = state.contextStep + (isContextStep(event) ? 1 : 0)
|
|
90
123
|
const surfaceNodes = advanceSessionSurface(state.surfaceNodes, event)
|
|
91
124
|
let visibleRuntimeMessages = state.visibleRuntimeMessages
|
|
92
|
-
if (timeline === state.timeline && sections === undefined && ptc === undefined &&
|
|
93
|
-
&& surfaceNodes === state.surfaceNodes) return state
|
|
125
|
+
if (timeline === state.timeline && sections === undefined && ptc === undefined && unresolvedAdoption === undefined
|
|
126
|
+
&& contextStep === state.contextStep && surfaceNodes === state.surfaceNodes) return state
|
|
94
127
|
const next = { ...state, timeline, contextStep,
|
|
95
128
|
logFacts: [...state.logFacts, deepFreeze({ index, event: presentationEvent(event) })],
|
|
96
129
|
}
|
|
@@ -110,6 +143,11 @@ function applyLogEvent(state, event, index = event?.seq,
|
|
|
110
143
|
const record = Object.freeze({ ...ptc, index, contextStep: state.contextStep, producer: 'ptc-plus' })
|
|
111
144
|
next.ptcMessages = [...state.ptcMessages, record]
|
|
112
145
|
next.runtimeMessagesBySeq = { ...next.runtimeMessagesBySeq, [`k${event.seq}`]: record }
|
|
146
|
+
} else if (unresolvedAdoption !== undefined) {
|
|
147
|
+
// Listed as this session's newest statement, but not as a resolvable runtime
|
|
148
|
+
// message: the ordered surface below is built from `runtimeMessagesBySeq`.
|
|
149
|
+
next.ptcMessages = [...state.ptcMessages,
|
|
150
|
+
Object.freeze({ ...unresolvedAdoption, index, contextStep: state.contextStep, producer: 'ptc-plus' })]
|
|
113
151
|
}
|
|
114
152
|
if (event?.surfaceOp === 'append') {
|
|
115
153
|
const record = next.runtimeMessagesBySeq[`k${event.seq}`]
|
|
@@ -133,7 +171,11 @@ export function createSessionLogProjection(options = {}) {
|
|
|
133
171
|
const replayBudget = admissionReplayBudget(options.replayBudgetBytes)
|
|
134
172
|
return Object.freeze({
|
|
135
173
|
key: SESSION_LOG_PROJECTION_KEY,
|
|
136
|
-
|
|
174
|
+
// 14 records the binding-adoption statement this build cannot resolve: the fact it
|
|
175
|
+
// keeps now carries the form its own replay needs, and `ptcMessages` gained a record
|
|
176
|
+
// for it. A checkpoint written by an earlier fold answers a different question, so
|
|
177
|
+
// the version moves and stored checkpoints are refolded rather than admitted.
|
|
178
|
+
stateVersion: 14,
|
|
137
179
|
stateSchema: Object.freeze({ parse(value) {
|
|
138
180
|
if (!isJsonValue(value) || !isRecord(value) || !isRecord(value.timeline)
|
|
139
181
|
|| typeof value.timeline.openTurn !== 'boolean' || typeof value.timeline.found !== 'boolean'
|
|
@@ -74,6 +74,12 @@ export function installSettingsSectionCompat({
|
|
|
74
74
|
&& typeof writeNamespace === 'string' && writeNamespace.length > 0
|
|
75
75
|
? Object.freeze({
|
|
76
76
|
update: (patch, expectedRevision) => provider.update(writeNamespace, patch, expectedRevision),
|
|
77
|
+
// The service applies field edits as `{ op: 'set' | 'unset', path }`; `update` can only
|
|
78
|
+
// restate values, so expose the primitive when it exists instead of narrowing the callers
|
|
79
|
+
// to a writer that cannot remove a field.
|
|
80
|
+
...(typeof provider.mutate === 'function'
|
|
81
|
+
? { mutate: (ops, expectedRevision) => provider.mutate(writeNamespace, ops, expectedRevision) }
|
|
82
|
+
: {}),
|
|
77
83
|
read: () => provider.describe?.().find(descriptor => descriptor.ns === writeNamespace),
|
|
78
84
|
}) : undefined
|
|
79
85
|
const unbind = onProvider(provider, writer)
|
|
@@ -2,11 +2,14 @@ import { PTC_MESSAGE_SOURCE_KIND } from './message-sources.js'
|
|
|
2
2
|
import { sessionExecutionAvailable } from './host-tool-sdk.js'
|
|
3
3
|
import { bindingToggleMessage } from './binding-toggle-receipt.js'
|
|
4
4
|
import {
|
|
5
|
-
|
|
5
|
+
BINDING_ADOPTION_RECORD,
|
|
6
6
|
clearedBindingAdoption,
|
|
7
7
|
declinedBindingEntries,
|
|
8
8
|
withBindingAdoption,
|
|
9
9
|
} from './binding-adoption.js'
|
|
10
|
+
// Namespace import: the record writer is one public surface of the host, and the module
|
|
11
|
+
// load must not depend on a named export that a future release could rename.
|
|
12
|
+
import * as dshSession from '@deepseek-ai/dsh-session'
|
|
10
13
|
import { RPC_CONTRACTS } from './rpc-contract.js'
|
|
11
14
|
import { randomUUID } from 'node:crypto'
|
|
12
15
|
import { dirname } from 'node:path'
|
|
@@ -232,6 +235,11 @@ export function createUserBindingsOwner(ctx, options = {}) {
|
|
|
232
235
|
let disposed = false
|
|
233
236
|
const codeConsole = new UserBindingConsole(currentOptions)
|
|
234
237
|
const commandRegistrations = new Map()
|
|
238
|
+
// The host's writer for a fact that belongs in the log but not on the model-visible
|
|
239
|
+
// surface. Every supported release publishes it, so an adoption decision is taken when
|
|
240
|
+
// it is made instead of waiting for a step to carry a message.
|
|
241
|
+
const appendRecord = typeof options.appendRecord === 'function' ? options.appendRecord
|
|
242
|
+
: typeof dshSession.appendPluginRecord === 'function' ? dshSession.appendPluginRecord : undefined
|
|
235
243
|
const sessionAgents = new Map()
|
|
236
244
|
const sessionGenerations = new Map()
|
|
237
245
|
const agentLifecycles = new WeakMap()
|
|
@@ -331,8 +339,17 @@ export function createUserBindingsOwner(ctx, options = {}) {
|
|
|
331
339
|
if (session === undefined || typeof session.append !== 'function') {
|
|
332
340
|
throw new Error('binding adoption requires a live session')
|
|
333
341
|
}
|
|
334
|
-
if (
|
|
335
|
-
throw new Error('
|
|
342
|
+
if (appendRecord === undefined) {
|
|
343
|
+
throw new Error('ptc-plus: this DSH release publishes no plugin-record writer, so a binding adoption decision cannot be recorded')
|
|
344
|
+
}
|
|
345
|
+
// Adoption is this session's own statement and the catalog the model reads already
|
|
346
|
+
// reflects it, so it is taken the moment the control is used: durable through the log,
|
|
347
|
+
// outside the model-visible surface, and requiring no prior step. A session that cannot
|
|
348
|
+
// take the record reports that instead of a decision nothing stored.
|
|
349
|
+
try {
|
|
350
|
+
appendRecord(session, BINDING_ADOPTION_RECORD, adoption)
|
|
351
|
+
} catch (error) {
|
|
352
|
+
throw new Error(`the session did not record the binding adoption decision: ${error?.message ?? String(error)}`)
|
|
336
353
|
}
|
|
337
354
|
return { kind: 'success', text: adoptionReceipt(adoption) }
|
|
338
355
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-ptc-plus",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.6",
|
|
4
4
|
"icon": "assets/ptc-plus-icon.svg",
|
|
5
5
|
"description": "A session-bound agent-native REPL for DeepSeek Harness PTC mode.",
|
|
6
6
|
"type": "module",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
],
|
|
44
44
|
"engines": {
|
|
45
45
|
"node": "^22.19.0 || >=24.0.0",
|
|
46
|
-
"dsh": "
|
|
46
|
+
"dsh": ">=0.2.1-0 <0.2.3"
|
|
47
47
|
},
|
|
48
48
|
"allowScripts": {
|
|
49
49
|
"esbuild": false
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"@babel/code-frame": "^7.29.7",
|
|
53
53
|
"@babel/parser": "^7.29.0",
|
|
54
|
-
"@deepseek-ai/dsh-util-values": "^0.2.
|
|
55
|
-
"@deepseek-ai/schemastery": "
|
|
54
|
+
"@deepseek-ai/dsh-util-values": "^0.2.2-alpha.2",
|
|
55
|
+
"@deepseek-ai/schemastery": "~3.18.6-alpha.2",
|
|
56
56
|
"@jridgewell/trace-mapping": "^0.3.31",
|
|
57
57
|
"acorn": "^8.15.0"
|
|
58
58
|
},
|
|
@@ -174,36 +174,50 @@
|
|
|
174
174
|
"@codemirror/language": "^6.12.4",
|
|
175
175
|
"@codemirror/state": "^6.7.4",
|
|
176
176
|
"@codemirror/view": "^6.43.11",
|
|
177
|
-
"@deepseek-ai/
|
|
178
|
-
"@deepseek-ai/
|
|
179
|
-
"@deepseek-ai/
|
|
180
|
-
"@deepseek-ai/
|
|
181
|
-
"@deepseek-ai/
|
|
182
|
-
"@deepseek-ai/
|
|
183
|
-
"@deepseek-ai/dsh
|
|
184
|
-
"@deepseek-ai/dsh-
|
|
185
|
-
"@deepseek-ai/dsh-
|
|
186
|
-
"@deepseek-ai/dsh-
|
|
187
|
-
"@deepseek-ai/dsh-
|
|
188
|
-
"@deepseek-ai/dsh-
|
|
189
|
-
"@deepseek-ai/dsh-client-
|
|
190
|
-
"@deepseek-ai/dsh-
|
|
191
|
-
"@deepseek-ai/dsh-
|
|
192
|
-
"@deepseek-ai/dsh-
|
|
193
|
-
"@deepseek-ai/dsh-
|
|
194
|
-
"@deepseek-ai/dsh-
|
|
195
|
-
"@deepseek-ai/dsh-
|
|
196
|
-
"@deepseek-ai/dsh-
|
|
197
|
-
"@deepseek-ai/dsh-
|
|
198
|
-
"@deepseek-ai/dsh-
|
|
199
|
-
"@deepseek-ai/dsh-
|
|
200
|
-
"@deepseek-ai/dsh-
|
|
201
|
-
"@deepseek-ai/dsh-
|
|
202
|
-
"@deepseek-ai/dsh-
|
|
203
|
-
"@deepseek-ai/dsh-
|
|
177
|
+
"@deepseek-ai/cordis": "4.0.6-alpha.2",
|
|
178
|
+
"@deepseek-ai/cordis-plugin-group": "1.0.6-alpha.2",
|
|
179
|
+
"@deepseek-ai/cordis-plugin-include": "1.0.11-alpha.2",
|
|
180
|
+
"@deepseek-ai/cordis-plugin-loader": "1.0.7-alpha.2",
|
|
181
|
+
"@deepseek-ai/cordis-plugin-timer": "1.1.8-alpha.2",
|
|
182
|
+
"@deepseek-ai/cosmokit": "1.8.7-alpha.2",
|
|
183
|
+
"@deepseek-ai/dsh": "alpha",
|
|
184
|
+
"@deepseek-ai/dsh-agent-loop": "alpha",
|
|
185
|
+
"@deepseek-ai/dsh-agent-loop-testkit": "alpha",
|
|
186
|
+
"@deepseek-ai/dsh-api-gateway": "alpha",
|
|
187
|
+
"@deepseek-ai/dsh-api-remotes": "alpha",
|
|
188
|
+
"@deepseek-ai/dsh-atomic-write": "alpha",
|
|
189
|
+
"@deepseek-ai/dsh-client-locale": "alpha",
|
|
190
|
+
"@deepseek-ai/dsh-client-store": "alpha",
|
|
191
|
+
"@deepseek-ai/dsh-client-test-runtime": "alpha",
|
|
192
|
+
"@deepseek-ai/dsh-client-ui-conversation": "alpha",
|
|
193
|
+
"@deepseek-ai/dsh-client-ui-primitives": "alpha",
|
|
194
|
+
"@deepseek-ai/dsh-client-ui-renderer": "alpha",
|
|
195
|
+
"@deepseek-ai/dsh-client-ui-session": "alpha",
|
|
196
|
+
"@deepseek-ai/dsh-client-ui-slots": "alpha",
|
|
197
|
+
"@deepseek-ai/dsh-commands": "alpha",
|
|
198
|
+
"@deepseek-ai/dsh-compaction-image-offload": "alpha",
|
|
199
|
+
"@deepseek-ai/dsh-home-paths": "alpha",
|
|
200
|
+
"@deepseek-ai/dsh-llm": "alpha",
|
|
201
|
+
"@deepseek-ai/dsh-scope": "alpha",
|
|
202
|
+
"@deepseek-ai/dsh-session": "alpha",
|
|
203
|
+
"@deepseek-ai/dsh-session-format-catalog": "alpha",
|
|
204
|
+
"@deepseek-ai/dsh-session-format-v0-to-v1": "alpha",
|
|
205
|
+
"@deepseek-ai/dsh-session-persistence-jsonl": "alpha",
|
|
206
|
+
"@deepseek-ai/dsh-settings": "alpha",
|
|
207
|
+
"@deepseek-ai/dsh-skill": "alpha",
|
|
208
|
+
"@deepseek-ai/dsh-skill-filesystem": "alpha",
|
|
209
|
+
"@deepseek-ai/dsh-spill-policy": "alpha",
|
|
210
|
+
"@deepseek-ai/dsh-tool-cordis": "alpha",
|
|
211
|
+
"@deepseek-ai/dsh-tool-executor-native": "alpha",
|
|
212
|
+
"@deepseek-ai/dsh-tool-executor-ptc": "alpha",
|
|
213
|
+
"@deepseek-ai/dsh-tools": "alpha",
|
|
214
|
+
"@deepseek-ai/dsh-typert-protocol": "alpha",
|
|
215
|
+
"@deepseek-ai/dsh-typert-registry": "alpha",
|
|
216
|
+
"@deepseek-ai/dsh-util-workspace-path": "alpha",
|
|
204
217
|
"@lezer/highlight": "^1.2.3",
|
|
205
218
|
"@radix-ui/react-select": "^2.2.6",
|
|
206
219
|
"@shikijs/langs": "^4.3.1",
|
|
220
|
+
"@tanstack/react-virtual": "^3.14.24",
|
|
207
221
|
"@testing-library/react": "^16.3.3",
|
|
208
222
|
"amaro": "1.1.11",
|
|
209
223
|
"anser": "^2.3.5",
|
|
@@ -69,7 +69,11 @@ export function createAuthoringView(React, deps) {
|
|
|
69
69
|
}) {
|
|
70
70
|
const input = useInput?.(snapshot => snapshot)
|
|
71
71
|
const available = useBindingCommand(snapshot => snapshot)
|
|
72
|
-
|
|
72
|
+
// The capability command source publishes nothing until a session observes it, and
|
|
73
|
+
// this entry is the surface that keeps it observed while mounted. Its value decides
|
|
74
|
+
// no branch here: whether `/capabilities` is listed is the command's own answer when
|
|
75
|
+
// it runs, so the refresh shortcut stays usable and the refusal carries its reason.
|
|
76
|
+
useCapabilityCommand?.(() => undefined)
|
|
73
77
|
const settings = usePtcSettings(snapshot => snapshot)
|
|
74
78
|
const [review, view] = useBindingReview(sessionId)
|
|
75
79
|
const anchorRef = React.useRef(null)
|
|
@@ -113,8 +117,7 @@ export function createAuthoringView(React, deps) {
|
|
|
113
117
|
const pluginEnabled = featureEnabled(settings, 'plugin') && (hasDraft || featureEnabled(settings, 'ptcMenu'))
|
|
114
118
|
const canPrefill = typeof useInput === 'function' && typeof inputActions?.setDraft === 'function'
|
|
115
119
|
const canAuthor = quickAccess && available && canPrefill
|
|
116
|
-
const canRefresh = pluginEnabled && settings.status === 'ready' && settings.writable === true
|
|
117
|
-
&& capabilityAvailable && canPrefill
|
|
120
|
+
const canRefresh = pluginEnabled && settings.status === 'ready' && settings.writable === true && canPrefill
|
|
118
121
|
const menuOpen = pluginEnabled && view.reachable && !managing && !capabilitiesOpen && !settingsOpen
|
|
119
122
|
&& menu !== null && menu.key === view.candidateKey
|
|
120
123
|
// The dialog owns the management session; losing the input surface only
|
|
@@ -411,8 +414,7 @@ export function createAuthoringView(React, deps) {
|
|
|
411
414
|
const actionButton = (id, copy) => h('button', {
|
|
412
415
|
type: 'button', role: 'menuitem', className: 'ptcPlusMenuButton',
|
|
413
416
|
disabled: id === 'refresh' && !canRefresh,
|
|
414
|
-
title: id === '
|
|
415
|
-
: id === 'settings' ? settingsPath(t) : t(copy),
|
|
417
|
+
title: id === 'settings' ? settingsPath(t) : t(copy),
|
|
416
418
|
onClick: () => selectMenuItem(id),
|
|
417
419
|
}, actionCopy(id, copy))
|
|
418
420
|
const actionSections = [
|
|
@@ -496,7 +498,6 @@ export function createAuthoringView(React, deps) {
|
|
|
496
498
|
}) : null,
|
|
497
499
|
SessionCapabilityControls && capabilitiesOpen && view.reachable
|
|
498
500
|
? h(SessionCapabilityControls, { sessionId, open: true, t,
|
|
499
|
-
enabled: pluginEnabled && settings.status === 'ready' && settings.writable === true,
|
|
500
501
|
onClose: () => {
|
|
501
502
|
setCapabilitiesOpen(false)
|
|
502
503
|
queueMicrotask(() => anchorRef.current?.querySelector('.ptcPlusAuthorButton')
|
|
@@ -747,8 +748,6 @@ export function createAuthoringView(React, deps) {
|
|
|
747
748
|
node.outcome?.kind !== 'error' ? null : h('p', { className: 'ptcPlusMessage ptcPlusDanger' },
|
|
748
749
|
node.outcome.text ?? t('bindings.commandFailed')),
|
|
749
750
|
canOpen ? h(ActionButton, { onClick: () => openBindingReview(review) }, t('bindings.reviewOpen')) : null,
|
|
750
|
-
!current.mounted && (candidate !== null || matches && projection.phase === 'ready')
|
|
751
|
-
? h('p', { className: 'ptcPlusMessage' }, t('bindings.reviewUnavailable')) : null,
|
|
752
751
|
candidate === null ? null : h('details', { className: 'ptcPlusBindingSourceDetails' },
|
|
753
752
|
h('summary', null, t('tool.source')), h(BindingCandidateContent, { candidate, t })))
|
|
754
753
|
}
|