dsh-ptc-plus 0.4.10 → 0.5.0
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 +60 -130
- package/README.md +60 -130
- package/assets/dsh-ptc-plus-banner-en.webp +0 -0
- package/assets/dsh-ptc-plus-banner-zh.webp +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.cjs +42336 -0
- package/cordis.patch.yml +1 -0
- package/docs/README.md +6 -2
- package/docs/adr/0005-temporary-rejected-cell-edit-transport.md +31 -198
- package/docs/adr/0008-define-agent-operating-contract.md +5 -1
- package/docs/adr/0009-bound-expensive-acceptance-default.md +2 -2
- package/docs/adr/0016-archive-resolved-review-findings.md +1 -1
- package/docs/adr/0017-track-the-latest-dsh-public-surface.md +2 -2
- package/docs/adr/0019-plugin-settings-and-kill-switch.md +1 -1
- package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +1 -1
- package/docs/adr/0022-stage-npm-releases-with-oidc.md +4 -2
- package/docs/adr/0023-global-user-bindings.md +2 -0
- package/docs/adr/0026-persist-the-delivery-verdict-against-the-verified-candidate.md +2 -0
- package/docs/adr/0028-attach-to-the-host-ptc-execution-seam.md +25 -23
- package/docs/adr/0031-close-semantic-obligations-by-owner.md +1 -1
- package/docs/adr/0034-keep-program-values-separate-from-output-projections.md +29 -0
- package/docs/adr/0035-run-coverage-only-before-a-new-release.md +27 -0
- package/docs/adr/0036-separate-focused-development-from-delivery-verification.md +29 -0
- package/docs/adr/0037-keep-tool-hover-previews-passive.md +52 -0
- package/docs/adr/0038-freeze-session-capability-plans.md +71 -0
- package/docs/adr/0039-verify-documentation-without-runtime-suites.md +29 -0
- package/docs/adr/0040-separate-capability-configurations-from-session-observations.md +39 -0
- package/docs/adr/0041-record-cell-execution-directories.md +65 -0
- package/docs/adr/0042-persist-provider-availability-and-handback.md +41 -0
- package/docs/adr/0043-compose-capability-and-context-policies.md +37 -0
- package/docs/adr/README.md +6 -0
- package/docs/architecture.md +23 -25
- package/docs/capability-planning-components.md +93 -0
- package/docs/capability-projection.md +7 -0
- package/docs/client-ui.md +70 -23
- package/docs/client-visual-contract.md +26 -9
- package/docs/context-management.md +22 -0
- package/docs/context-optimization-plan.md +353 -0
- package/docs/context-public-interface-coverage.md +25 -0
- package/docs/durability-design.md +20 -15
- package/docs/evaluation.md +41 -6
- package/docs/evaluations/command-goat-deepseek-v4.1-flash-20261006.md +126 -0
- package/docs/evaluations/command-goat-deepseek-v4.1-flash.md +281 -0
- package/docs/installation.md +31 -10
- package/docs/program-data-plane.md +5 -3
- package/docs/publishing.md +5 -5
- package/docs/release-coverage.md +73 -0
- package/docs/release-notes.md +1 -1
- package/docs/review-procedure.md +56 -0
- package/docs/runtime-reference.md +48 -16
- package/docs/semantic-validation.md +14 -2
- package/docs/stateful-binding-updates-proposal.md +2 -2
- package/docs/user-bindings.md +1 -1
- package/docs/value-wire.md +11 -1
- package/docs/verification-optimization-work.md +26 -15
- package/docs/verification.md +30 -88
- package/index.js +123 -20
- package/internal/binding-toggle-receipt.js +24 -0
- package/internal/capability-command-receipt.js +29 -0
- package/internal/capability-environment.js +1247 -0
- package/internal/capability-plan.js +285 -0
- package/internal/capability-policy.js +96 -0
- package/internal/capability-statistics-store.js +180 -0
- package/internal/capability-statistics.js +210 -0
- package/internal/config-spec.js +79 -9
- package/internal/direct-surface-owner.js +27 -29
- package/internal/dynamic-environment-runtime.js +9 -9
- package/internal/edit-transport-owner.js +180 -139
- package/internal/execution-provider-owner.js +15 -12
- package/internal/execution-seam-compat.js +8 -8
- package/internal/kernel-worker.js +104 -32
- package/internal/native-root-dynamic.js +12 -13
- package/internal/program-bindings.js +190 -0
- package/internal/recovery-tips.js +3 -2
- package/internal/rejected-cell-editor.js +8 -8
- package/internal/repl-observation-interest.js +11 -3
- package/internal/rpc-contract.js +1 -0
- package/internal/runtime-bridge-owner.js +272 -34
- package/internal/runtime-config.js +58 -0
- package/internal/runtime-contexts.js +74 -5
- package/internal/runtime-intrinsics.js +1 -0
- package/internal/runtime-messages.js +41 -0
- package/internal/sdk-projection.js +10 -82
- package/internal/session-cell-executor.js +42 -19
- package/internal/session-events.js +34 -0
- package/internal/session-journal-recovery.js +234 -11
- package/internal/session-journal-schema.js +6 -3
- package/internal/session-journal.js +31 -2
- package/internal/session-log-view.js +1 -1
- package/internal/session-runtime.js +119 -15
- package/internal/settings-compat.js +12 -5
- package/internal/stateful-module-compiler.js +3 -2
- package/internal/stateful-module-runtime.js +7 -3
- package/internal/stateful-root-runtime.js +9 -4
- package/internal/user-binding-authoring.js +2 -7
- package/internal/user-bindings-owner.js +41 -2
- package/internal/validated-parse-repair.js +1 -1
- package/internal/value-wire.js +68 -21
- package/internal/worker-cwd-virtualization.js +20 -18
- package/internal/worker-realm-surfaces.js +3 -3
- package/package.json +47 -29
- package/src/client-authoring-view.js +67 -30
- package/src/client-binding-review.js +2 -1
- package/src/client-binding-toggle.js +18 -0
- package/src/client-capabilities-view.js +1341 -0
- package/src/client-capability-sort.js +29 -0
- package/src/client-copy.js +871 -8
- package/src/client-feature-gates.js +3 -0
- package/src/client-indicator-view.js +4 -6
- package/src/client-primitives.js +33 -2
- package/src/client-repl-view.js +20 -13
- package/src/client-settings-view.js +411 -41
- package/src/client-styles.js +108 -15
- package/src/client-tool-hover.js +185 -0
- package/src/client-tool-view.js +37 -8
- package/src/client-transport.js +44 -9
- package/src/client-workbench.js +6 -7
- package/src/client.js +76 -22
- package/client.js +0 -32479
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { bindingDraftProjection, bindingReviewStatus } from './client-binding-review.js'
|
|
2
2
|
import { bindingModelPreferences } from '../internal/user-binding-model-context.js'
|
|
3
|
+
import { capabilityCommandText } from './client-capabilities-view.js'
|
|
3
4
|
import { featureEnabled } from './client-feature-gates.js'
|
|
4
5
|
import {
|
|
5
6
|
MENU_CHILDREN_PROBE_SENTINEL,
|
|
@@ -25,7 +26,7 @@ export function createAuthoringView(React, deps) {
|
|
|
25
26
|
const {
|
|
26
27
|
ActionButton, IconButton, Menu, MenuFallback, Toast, Tooltip, CodeBlock, Modal, createPortal, BindingsDialog, PTCPlusSettingsDialog,
|
|
27
28
|
useWorkbenchController, useBindingReview, catalogOwner, callUserBindings, subscribeReset,
|
|
28
|
-
settingsCardSeat, updateSetting, menuChildren,
|
|
29
|
+
settingsCardSeat, updateSetting, updateCapabilityConfiguration, menuChildren, SessionCapabilityControls,
|
|
29
30
|
icons: {
|
|
30
31
|
sparkle: IconSparkle16, chevron: IconChevronDownOutline14,
|
|
31
32
|
close: IconCloseOutline16, check: IconCheckOutline14,
|
|
@@ -64,10 +65,11 @@ export function createAuthoringView(React, deps) {
|
|
|
64
65
|
}[settingsCardSeat?.()] ?? 'settings.menuEntry')
|
|
65
66
|
|
|
66
67
|
function BindingAuthorButton({
|
|
67
|
-
sessionId, t, useInput, inputActions, usePtcSettings, useBindingCommand,
|
|
68
|
+
sessionId, t, useInput, inputActions, usePtcSettings, useBindingCommand, useCapabilityCommand,
|
|
68
69
|
}) {
|
|
69
70
|
const input = useInput?.(snapshot => snapshot)
|
|
70
71
|
const available = useBindingCommand(snapshot => snapshot)
|
|
72
|
+
const capabilityAvailable = useCapabilityCommand?.(snapshot => snapshot) === true
|
|
71
73
|
const settings = usePtcSettings(snapshot => snapshot)
|
|
72
74
|
const [review, view] = useBindingReview(sessionId)
|
|
73
75
|
const anchorRef = React.useRef(null)
|
|
@@ -84,6 +86,7 @@ export function createAuthoringView(React, deps) {
|
|
|
84
86
|
const hoverTimer = React.useRef(undefined)
|
|
85
87
|
const [menu, setMenu] = React.useState(null)
|
|
86
88
|
const [managing, setManaging] = React.useState(false)
|
|
89
|
+
const [capabilitiesOpen, setCapabilitiesOpen] = React.useState(false)
|
|
87
90
|
const [settingsOpen, setSettingsOpen] = React.useState(false)
|
|
88
91
|
// The composer entry's four actions live in the host Menu's `children`
|
|
89
92
|
// region. Preceding Clients accept that prop and mount nothing, so the entry
|
|
@@ -105,16 +108,25 @@ export function createAuthoringView(React, deps) {
|
|
|
105
108
|
const catalogFocus = React.useRef(null)
|
|
106
109
|
const toastSequence = React.useRef(0)
|
|
107
110
|
const [toast, setToast] = React.useState(null)
|
|
108
|
-
const hasDraft = view.mounted && view.candidate !== null && view.action === null
|
|
111
|
+
const hasDraft = featureEnabled(settings, 'bindings') && view.mounted && view.candidate !== null && view.action === null
|
|
109
112
|
const quickAccess = featureEnabled(settings, 'authorButton')
|
|
110
|
-
const
|
|
111
|
-
const
|
|
113
|
+
const pluginEnabled = featureEnabled(settings, 'plugin') && (hasDraft || featureEnabled(settings, 'ptcMenu'))
|
|
114
|
+
const canPrefill = typeof useInput === 'function' && typeof inputActions?.setDraft === 'function'
|
|
115
|
+
const canAuthor = quickAccess && available && canPrefill
|
|
116
|
+
const canRefresh = pluginEnabled && settings.status === 'ready' && settings.writable === true
|
|
117
|
+
&& capabilityAvailable && canPrefill
|
|
118
|
+
const menuOpen = pluginEnabled && view.reachable && !managing && !capabilitiesOpen && !settingsOpen
|
|
112
119
|
&& menu !== null && menu.key === view.candidateKey
|
|
113
120
|
// The dialog owns the management session; losing the input surface only
|
|
114
121
|
// suspends reads, so a draft survives a temporary Host takeover.
|
|
115
122
|
const workbench = useWorkbenchController({
|
|
116
123
|
enabled: quickAccess && managing, active: view.reachable, callUserBindings,
|
|
117
124
|
})
|
|
125
|
+
React.useEffect(() => {
|
|
126
|
+
if (!quickAccess) {
|
|
127
|
+
setManaging(false)
|
|
128
|
+
}
|
|
129
|
+
}, [quickAccess])
|
|
118
130
|
const refreshCatalog = React.useCallback(async (reload = false) => {
|
|
119
131
|
if (reload) captureCatalogFocus()
|
|
120
132
|
await catalogSource.read({ reload })
|
|
@@ -124,6 +136,7 @@ export function createAuthoringView(React, deps) {
|
|
|
124
136
|
catalogSource.reset()
|
|
125
137
|
setMenu(null)
|
|
126
138
|
setManaging(false)
|
|
139
|
+
setCapabilitiesOpen(false)
|
|
127
140
|
setSettingsOpen(false)
|
|
128
141
|
}
|
|
129
142
|
const unsubscribe = subscribeReset(reset)
|
|
@@ -135,9 +148,14 @@ export function createAuthoringView(React, deps) {
|
|
|
135
148
|
const toggleBinding = async entry => {
|
|
136
149
|
if (!catalogReady || !quickAccess) return
|
|
137
150
|
captureCatalogFocus()
|
|
138
|
-
await catalogSource.write(() => callUserBindings(entry.enabled ? 'disable' : 'enable', {
|
|
151
|
+
const next = await catalogSource.write(() => callUserBindings(entry.enabled ? 'disable' : 'enable', {
|
|
139
152
|
id: entry.id, expectedRevision: catalog.revision,
|
|
140
153
|
}))
|
|
154
|
+
const saved = next?.entries.find(item => item.id === entry.id)
|
|
155
|
+
if (saved) {
|
|
156
|
+
toastSequence.current++
|
|
157
|
+
setToast({ sequence: toastSequence.current, key: saved.enabled ? 'bindings.toggleEnabled' : 'bindings.toggleDisabled', params: { name: saved.name } })
|
|
158
|
+
}
|
|
141
159
|
}
|
|
142
160
|
const cancelHoverOpen = React.useCallback(() => {
|
|
143
161
|
if (hoverTimer.current === undefined) return
|
|
@@ -260,13 +278,12 @@ export function createAuthoringView(React, deps) {
|
|
|
260
278
|
return () => clearTimeout(timer)
|
|
261
279
|
}, [toast])
|
|
262
280
|
const label = hasDraft ? t('bindings.reviewMenuLabel', { count: 1 })
|
|
263
|
-
+ (view.message ? ` · ${t('bindings.reviewAttention')}` : '') : t('bindings.open')
|
|
264
|
-
const hint = t(hasDraft ? 'bindings.draftHint' : 'bindings.openHint')
|
|
265
|
-
//
|
|
266
|
-
|
|
267
|
-
const prefillAuthoring = value => {
|
|
281
|
+
+ (view.message ? ` · ${t('bindings.reviewAttention')}` : '') : t(quickAccess ? 'bindings.open' : 'settings.toolsMenu')
|
|
282
|
+
const hint = t(hasDraft ? 'bindings.draftHint' : quickAccess ? 'bindings.openHint' : 'settings.toolsMenu')
|
|
283
|
+
// Command shortcuts share the composer guard; submission remains the user's action.
|
|
284
|
+
const prefillCommand = (value, allowed) => {
|
|
268
285
|
hideMenu()
|
|
269
|
-
if (!
|
|
286
|
+
if (!allowed) return
|
|
270
287
|
if (typeof input?.draft === 'string' && input.draft.trim() !== '') {
|
|
271
288
|
toastSequence.current += 1
|
|
272
289
|
setToast({ sequence: toastSequence.current, text: t('bindings.composerBusy') })
|
|
@@ -274,8 +291,8 @@ export function createAuthoringView(React, deps) {
|
|
|
274
291
|
}
|
|
275
292
|
inputActions.setDraft(value)
|
|
276
293
|
}
|
|
277
|
-
const openAuthoring = () =>
|
|
278
|
-
const openAuthoringEdit = entry =>
|
|
294
|
+
const openAuthoring = () => prefillCommand('/binding new ', canAuthor)
|
|
295
|
+
const openAuthoringEdit = entry => prefillCommand(`/binding edit ${entry.id} `, canAuthor)
|
|
279
296
|
const starButton = h('button', {
|
|
280
297
|
type: 'button', className: 'ptcPlusAuthorButton', 'aria-label': label,
|
|
281
298
|
// Older UI-kit lines ship no Tooltip primitive; the native title carries the hint there.
|
|
@@ -309,7 +326,6 @@ export function createAuthoringView(React, deps) {
|
|
|
309
326
|
const enabledEntries = (catalog?.entries ?? []).filter(entry => entry.enabled)
|
|
310
327
|
const disabledEntries = (catalog?.entries ?? []).filter(entry => !entry.enabled)
|
|
311
328
|
const catalogItems = !quickAccess ? [] : [
|
|
312
|
-
{ id: 'global-heading', type: 'label', text: t('bindings.quickHeading') },
|
|
313
329
|
...(catalog === null || catalog.entries.length === 0 ? [] : [
|
|
314
330
|
{ id: 'enabled-heading', type: 'label', text: t('bindings.quickEnabled', { count: enabledEntries.length }) },
|
|
315
331
|
...enabledEntries.map(catalogRow),
|
|
@@ -335,14 +351,7 @@ export function createAuthoringView(React, deps) {
|
|
|
335
351
|
// submenu here would lose the bounded, scrollable catalog this step needs.
|
|
336
352
|
const editItems = [
|
|
337
353
|
{ id: 'edit-heading', type: 'label', text: t('bindings.quickEditHeading') },
|
|
338
|
-
...(catalog?.entries ?? []).map(entry => ({
|
|
339
|
-
id: `edit:${entry.id}`,
|
|
340
|
-
disabled: catalog === null,
|
|
341
|
-
label: h('span', { className: 'ptcPlusBindingQuickRow' },
|
|
342
|
-
h('span', { className: 'ptcPlusBindingQuickName' }, h('strong', { title: entry.name }, entry.name),
|
|
343
|
-
h('span', { className: 'ptcPlusBindingQuickState' }, t(entry.enabled ? 'bindings.enabled' : 'bindings.disabledEntry'))),
|
|
344
|
-
h('span', { className: 'ptcPlusBindingQuickPurpose', title: entry.purpose }, entry.purpose)),
|
|
345
|
-
})),
|
|
354
|
+
...(catalog?.entries ?? []).map(entry => ({ ...catalogRow(entry), id: `edit:${entry.id}` })),
|
|
346
355
|
]
|
|
347
356
|
const selectMenuItem = id => {
|
|
348
357
|
if (!anchorRef.current?.getClientRects().length) return
|
|
@@ -371,6 +380,8 @@ export function createAuthoringView(React, deps) {
|
|
|
371
380
|
setSettingsOpen(true)
|
|
372
381
|
return
|
|
373
382
|
}
|
|
383
|
+
if (id === 'capabilities') { hideMenu(); setCapabilitiesOpen(true); return }
|
|
384
|
+
if (id === 'refresh') { prefillCommand('/capabilities refresh', canRefresh); return }
|
|
374
385
|
hideMenu()
|
|
375
386
|
if (id === 'new') openAuthoring()
|
|
376
387
|
else if (id === 'manage') {
|
|
@@ -381,12 +392,27 @@ export function createAuthoringView(React, deps) {
|
|
|
381
392
|
}
|
|
382
393
|
// One copy of each action label serves the grid the plugin renders itself,
|
|
383
394
|
// in whichever carrier the installed Menu publishes for it.
|
|
384
|
-
const
|
|
395
|
+
const actionPaths = {
|
|
396
|
+
new: 'M8 3v10M3 8h10',
|
|
397
|
+
edit: 'm10 3 3 3M3 13l3-.7 7-7a1.4 1.4 0 0 0-3-3l-7 7L3 13Z',
|
|
398
|
+
refresh: 'M13 6a5 5 0 0 0-9-2L2 6m0-3v3h3M3 10a5 5 0 0 0 9 2l2-2m0 3v-3h-3',
|
|
399
|
+
manage: 'M2 4h5l1.5 2H14v7H2V4Z',
|
|
400
|
+
capabilities: 'M3 4h10M3 8h10M3 12h10M6 2v4M10 6v4M6 10v4',
|
|
401
|
+
settings: 'M6 2h4l.5 2 1.5 1.5 2 .5v4l-2 .5-1.5 1.5-.5 2H6l-.5-2L4 10.5 2 10V6l2-.5L5.5 4 6 2ZM10 8a2 2 0 1 0-4 0 2 2 0 0 0 4 0Z',
|
|
402
|
+
'edit-back': 'm7 3-5 5 5 5M2 8h12',
|
|
403
|
+
}
|
|
404
|
+
const actionCopy = (id, copy) => h(React.Fragment, null,
|
|
405
|
+
h('svg', { className: 'ptcPlusMenuActionIcon', width: 16, height: 16, viewBox: '0 0 16 16',
|
|
406
|
+
fill: 'none', 'aria-hidden': true }, h('path', { d: actionPaths[id], stroke: 'currentColor',
|
|
407
|
+
strokeWidth: 1.4, strokeLinecap: 'round', strokeLinejoin: 'round' })), h('span', {
|
|
385
408
|
className: 'ptcPlusBindingMenuAction',
|
|
386
409
|
title: id === 'settings' ? settingsPath(t) : undefined,
|
|
387
|
-
}, t(copy))
|
|
410
|
+
}, t(copy)))
|
|
388
411
|
const actionButton = (id, copy) => h('button', {
|
|
389
412
|
type: 'button', role: 'menuitem', className: 'ptcPlusMenuButton',
|
|
413
|
+
disabled: id === 'refresh' && !canRefresh,
|
|
414
|
+
title: id === 'refresh' && !capabilityAvailable ? t('capabilities.refreshUnavailable')
|
|
415
|
+
: id === 'settings' ? settingsPath(t) : t(copy),
|
|
390
416
|
onClick: () => selectMenuItem(id),
|
|
391
417
|
}, actionCopy(id, copy))
|
|
392
418
|
const actionSections = [
|
|
@@ -396,7 +422,9 @@ export function createAuthoringView(React, deps) {
|
|
|
396
422
|
actionButton('new', 'bindings.authorNewDraft'),
|
|
397
423
|
(catalog?.entries?.length ?? 0) > 0 ? actionButton('edit', 'bindings.authorEdit') : null)) : null,
|
|
398
424
|
h('div', { key: 'utilities', className: 'ptcPlusMenuUtilities' },
|
|
425
|
+
actionButton('refresh', 'capabilities.applySession'),
|
|
399
426
|
quickAccess ? actionButton('manage', 'bindings.manage') : null,
|
|
427
|
+
SessionCapabilityControls ? actionButton('capabilities', 'capabilities.quick.title') : null,
|
|
400
428
|
actionButton('settings', 'settings.menuEntry')),
|
|
401
429
|
]
|
|
402
430
|
const menuEntries = menu?.step === 'edit' ? editItems : [
|
|
@@ -421,7 +449,8 @@ export function createAuthoringView(React, deps) {
|
|
|
421
449
|
: entry.type === 'label'
|
|
422
450
|
? h('div', { key: entry.id, className: 'ptcPlusMenuGroupLabel' }, entry.text)
|
|
423
451
|
: h('button', {
|
|
424
|
-
key: entry.id, type: 'button', role: 'menuitem',
|
|
452
|
+
key: entry.id, type: 'button', role: 'menuitem',
|
|
453
|
+
className: entry.id === 'disabled-group' ? 'ptcPlusOwnedMenuRow ptcPlusMenuDisclosure' : 'ptcPlusOwnedMenuRow',
|
|
425
454
|
disabled: entry.disabled, 'data-binding-id': entry.bindingId,
|
|
426
455
|
ref: entry.id === 'reload' ? reloadItemRef : entry.id === 'disabled-group' ? disabledGroupRef : undefined,
|
|
427
456
|
'aria-expanded': entry.id === 'disabled-group' ? disabledOpen : undefined,
|
|
@@ -435,7 +464,7 @@ export function createAuthoringView(React, deps) {
|
|
|
435
464
|
'data-text': isHostIconComponent(IconSparkle16) ? undefined : true,
|
|
436
465
|
ref: attachAnchor,
|
|
437
466
|
},
|
|
438
|
-
!
|
|
467
|
+
!pluginEnabled ? null : h(menuChildrenRegion ? Menu : MenuFallback, {
|
|
439
468
|
className: 'ptcPlusAuthorButtonShell', open: menuOpen,
|
|
440
469
|
anchor: isHostComponent(Tooltip)
|
|
441
470
|
? h(Tooltip, { label: hint, delayMs: 700, disabled: menuOpen || managing || settingsOpen }, starButton) : starButton,
|
|
@@ -465,9 +494,17 @@ export function createAuthoringView(React, deps) {
|
|
|
465
494
|
controller: workbench, t, onClose: () => setManaging(false), returnFocusRef: dialogReturnFocus,
|
|
466
495
|
getReturnFocus: () => anchorRef.current?.querySelector('.ptcPlusAuthorButton'),
|
|
467
496
|
}) : null,
|
|
497
|
+
SessionCapabilityControls && capabilitiesOpen && view.reachable
|
|
498
|
+
? h(SessionCapabilityControls, { sessionId, open: true, t,
|
|
499
|
+
enabled: pluginEnabled && settings.status === 'ready' && settings.writable === true,
|
|
500
|
+
onClose: () => {
|
|
501
|
+
setCapabilitiesOpen(false)
|
|
502
|
+
queueMicrotask(() => anchorRef.current?.querySelector('.ptcPlusAuthorButton')
|
|
503
|
+
?.focus({ preventScroll: true }))
|
|
504
|
+
} }) : null,
|
|
468
505
|
settingsOpen && view.reachable
|
|
469
506
|
? h(PTCPlusSettingsDialog, {
|
|
470
|
-
t, usePtcSettings, updateSetting, callUserBindings,
|
|
507
|
+
t, usePtcSettings, updateSetting, updateCapabilityConfiguration, callUserBindings,
|
|
471
508
|
onClose: () => {
|
|
472
509
|
setSettingsOpen(false)
|
|
473
510
|
queueMicrotask(() => anchorRef.current?.querySelector('.ptcPlusAuthorButton')
|
|
@@ -477,13 +514,13 @@ export function createAuthoringView(React, deps) {
|
|
|
477
514
|
toast === null ? null : isHostComponent(Toast)
|
|
478
515
|
? h(Toast, {
|
|
479
516
|
key: toast.sequence,
|
|
480
|
-
text: toast.text,
|
|
517
|
+
text: toast.key ? t(toast.key, toast.params) : capabilityCommandText(t, toast.text),
|
|
481
518
|
anchor: anchorRef.current,
|
|
482
519
|
onDone: () => setToast(null),
|
|
483
520
|
})
|
|
484
521
|
: h('span', {
|
|
485
522
|
key: toast.sequence, className: 'ptcPlusComposerNotice', role: 'status',
|
|
486
|
-
}, toast.text))
|
|
523
|
+
}, toast.key ? t(toast.key, toast.params) : capabilityCommandText(t, toast.text)))
|
|
487
524
|
}
|
|
488
525
|
|
|
489
526
|
function BindingCandidateContent({ candidate, t, showName = true }) {
|
|
@@ -202,7 +202,8 @@ export function createBindingReviews(call) {
|
|
|
202
202
|
return () => {
|
|
203
203
|
attached = false
|
|
204
204
|
invalidate()
|
|
205
|
-
|
|
205
|
+
// The composer observer owns reachability independently of draft mounting.
|
|
206
|
+
publish({ mounted: false, writable: false })
|
|
206
207
|
}
|
|
207
208
|
},
|
|
208
209
|
reset() {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { readBindingToggle } from '../internal/binding-toggle-receipt.js'
|
|
2
|
+
|
|
3
|
+
/** A separate Chat node keeps configuration receipts distinct from ordinary hidden contexts. */
|
|
4
|
+
export const bindingToggleConversationDefinition = Object.freeze({
|
|
5
|
+
kind: 'ptc-plus-binding-toggle', target: 'chat',
|
|
6
|
+
match(event) {
|
|
7
|
+
return event.type === 'user/message' && event.surfaceOp === 'append' && readBindingToggle(event.data)
|
|
8
|
+
? { id: event.data.id, role: 'start' } : null
|
|
9
|
+
},
|
|
10
|
+
start(_context, match) { return { seq: match.event.seq, receipt: readBindingToggle(match.event.data) } },
|
|
11
|
+
update(context) { return context.state },
|
|
12
|
+
buildViewNode(context) {
|
|
13
|
+
if (!context.state?.receipt) return null
|
|
14
|
+
return { key: context.key, id: context.id, kind: 'ptc-plus-binding-toggle', target: 'chat',
|
|
15
|
+
anchorSeq: context.state.seq, location: context.start?.location ?? { kind: 'unresolved' },
|
|
16
|
+
visibility: 'visible', data: context.state.receipt }
|
|
17
|
+
},
|
|
18
|
+
})
|