dsh-ptc-plus 0.4.8 → 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.
Files changed (139) hide show
  1. package/README.en.md +61 -123
  2. package/README.md +61 -123
  3. package/assets/dsh-ptc-plus-banner-en.webp +0 -0
  4. package/assets/dsh-ptc-plus-banner-zh.webp +0 -0
  5. package/assets/ptc-plus-repl-workspace-en.png +0 -0
  6. package/assets/ptc-plus-repl-workspace-zh.png +0 -0
  7. package/assets/ptc-plus-settings-en.png +0 -0
  8. package/assets/ptc-plus-settings-zh.png +0 -0
  9. package/client.cjs +42336 -0
  10. package/cordis.patch.yml +13 -2
  11. package/docs/README.md +7 -2
  12. package/docs/adr/0005-temporary-rejected-cell-edit-transport.md +31 -179
  13. package/docs/adr/0008-define-agent-operating-contract.md +5 -1
  14. package/docs/adr/0009-bound-expensive-acceptance-default.md +2 -2
  15. package/docs/adr/0016-archive-resolved-review-findings.md +1 -1
  16. package/docs/adr/0017-track-the-latest-dsh-public-surface.md +2 -2
  17. package/docs/adr/0019-plugin-settings-and-kill-switch.md +14 -3
  18. package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
  19. package/docs/adr/0022-stage-npm-releases-with-oidc.md +4 -2
  20. package/docs/adr/0023-global-user-bindings.md +3 -1
  21. package/docs/adr/0026-persist-the-delivery-verdict-against-the-verified-candidate.md +2 -0
  22. package/docs/adr/0028-attach-to-the-host-ptc-execution-seam.md +101 -35
  23. package/docs/adr/0030-serve-both-typert-codec-generations-from-one-codec.md +3 -3
  24. package/docs/adr/0031-close-semantic-obligations-by-owner.md +1 -1
  25. package/docs/adr/0032-own-session-log-facts-in-a-host-only-projection.md +27 -0
  26. package/docs/adr/0033-gate-client-visual-usability-in-a-browser.md +23 -0
  27. package/docs/adr/0034-keep-program-values-separate-from-output-projections.md +29 -0
  28. package/docs/adr/0035-run-coverage-only-before-a-new-release.md +27 -0
  29. package/docs/adr/0036-separate-focused-development-from-delivery-verification.md +29 -0
  30. package/docs/adr/0037-keep-tool-hover-previews-passive.md +52 -0
  31. package/docs/adr/0038-freeze-session-capability-plans.md +71 -0
  32. package/docs/adr/0039-verify-documentation-without-runtime-suites.md +29 -0
  33. package/docs/adr/0040-separate-capability-configurations-from-session-observations.md +39 -0
  34. package/docs/adr/0041-record-cell-execution-directories.md +65 -0
  35. package/docs/adr/0042-persist-provider-availability-and-handback.md +41 -0
  36. package/docs/adr/0043-compose-capability-and-context-policies.md +37 -0
  37. package/docs/adr/README.md +6 -0
  38. package/docs/architecture.md +25 -27
  39. package/docs/binding-review-placement-design.md +29 -21
  40. package/docs/capability-planning-components.md +93 -0
  41. package/docs/capability-projection.md +7 -0
  42. package/docs/client-ui.md +88 -29
  43. package/docs/client-visual-contract.md +65 -0
  44. package/docs/context-management.md +22 -0
  45. package/docs/context-optimization-plan.md +353 -0
  46. package/docs/context-public-interface-coverage.md +25 -0
  47. package/docs/durability-design.md +31 -14
  48. package/docs/evaluation.md +41 -6
  49. package/docs/evaluations/command-goat-deepseek-v4.1-flash-20261006.md +126 -0
  50. package/docs/evaluations/command-goat-deepseek-v4.1-flash.md +281 -0
  51. package/docs/installation.md +50 -8
  52. package/docs/program-data-plane.md +5 -3
  53. package/docs/publishing.md +5 -5
  54. package/docs/release-coverage.md +73 -0
  55. package/docs/release-notes.md +1 -1
  56. package/docs/review-procedure.md +56 -0
  57. package/docs/runtime-reference.md +48 -16
  58. package/docs/semantic-validation.md +14 -2
  59. package/docs/stateful-binding-updates-proposal.md +2 -2
  60. package/docs/user-bindings.en.md +2 -2
  61. package/docs/user-bindings.md +3 -3
  62. package/docs/value-wire.md +11 -1
  63. package/docs/verification-optimization-work.md +52 -15
  64. package/docs/verification.md +30 -86
  65. package/index.js +147 -23
  66. package/internal/binding-toggle-receipt.js +24 -0
  67. package/internal/capability-command-receipt.js +29 -0
  68. package/internal/capability-environment.js +1247 -0
  69. package/internal/capability-plan.js +285 -0
  70. package/internal/capability-policy.js +96 -0
  71. package/internal/capability-statistics-store.js +180 -0
  72. package/internal/capability-statistics.js +210 -0
  73. package/internal/compiler-platform.js +5 -3
  74. package/internal/compiler-service.js +2 -9
  75. package/internal/config-spec.js +79 -9
  76. package/internal/cordis-tools-owner.js +22 -19
  77. package/internal/direct-surface-owner.js +29 -29
  78. package/internal/dynamic-environment-runtime.js +9 -9
  79. package/internal/edit-transport-owner.js +183 -139
  80. package/internal/execution-provider-owner.js +160 -0
  81. package/internal/execution-seam-compat.js +76 -120
  82. package/internal/isolated-worker.js +12 -8
  83. package/internal/kernel-worker.js +104 -32
  84. package/internal/native-root-dynamic.js +12 -13
  85. package/internal/program-bindings.js +190 -0
  86. package/internal/recovery-tips.js +53 -23
  87. package/internal/rejected-cell-editor.js +8 -8
  88. package/internal/repl-observation-interest.js +11 -3
  89. package/internal/rpc-contract.js +1 -0
  90. package/internal/runtime-bridge-owner.js +351 -82
  91. package/internal/runtime-config.js +58 -0
  92. package/internal/runtime-contexts.js +85 -16
  93. package/internal/runtime-intrinsics.js +1 -0
  94. package/internal/runtime-messages.js +41 -0
  95. package/internal/sdk-projection.js +10 -82
  96. package/internal/session-cell-executor.js +42 -19
  97. package/internal/session-events.js +74 -4
  98. package/internal/session-journal-recovery.js +904 -184
  99. package/internal/session-journal-schema.js +6 -3
  100. package/internal/session-journal.js +31 -2
  101. package/internal/session-log-view.js +189 -43
  102. package/internal/session-runtime.js +175 -23
  103. package/internal/settings-compat.js +23 -6
  104. package/internal/stateful-module-compiler.js +3 -2
  105. package/internal/stateful-module-runtime.js +7 -3
  106. package/internal/stateful-root-runtime.js +9 -4
  107. package/internal/user-binding-authoring.js +2 -7
  108. package/internal/user-bindings-owner.js +47 -7
  109. package/internal/validated-parse-repair.js +1 -1
  110. package/internal/value-wire.js +68 -21
  111. package/internal/worker-cwd-virtualization.js +20 -18
  112. package/internal/worker-realm-surfaces.js +3 -3
  113. package/locale/en.json +6 -0
  114. package/locale/zh.json +6 -0
  115. package/package.json +55 -38
  116. package/src/client-authoring-view.js +286 -168
  117. package/src/client-binding-review.js +4 -1
  118. package/src/client-binding-toggle.js +18 -0
  119. package/src/client-capabilities-view.js +1341 -0
  120. package/src/client-capability-sort.js +29 -0
  121. package/src/client-code-editor.js +6 -0
  122. package/src/client-copy.js +881 -8
  123. package/src/client-feature-gates.js +15 -5
  124. package/src/client-host-compat.js +23 -2
  125. package/src/client-indicator-view.js +4 -6
  126. package/src/client-primitives.js +280 -0
  127. package/src/client-repl-view.js +23 -16
  128. package/src/client-settings-view.js +412 -69
  129. package/src/client-styles.js +193 -41
  130. package/src/client-tool-hover.js +185 -0
  131. package/src/client-tool-view.js +45 -11
  132. package/src/client-transport.js +44 -9
  133. package/src/client-workbench.js +9 -10
  134. package/src/client.js +148 -68
  135. package/assets/ptc-plus-bindings-en.png +0 -0
  136. package/assets/ptc-plus-bindings-zh.png +0 -0
  137. package/assets/ptc-plus-repair-en.png +0 -0
  138. package/assets/ptc-plus-repair-zh.png +0 -0
  139. package/client.js +0 -31857
package/src/client.js CHANGED
@@ -1,16 +1,20 @@
1
1
  import { createClientRpc } from './client-rpc.js'
2
2
  import { RPC_CONTRACTS } from '../internal/rpc-contract.js'
3
- import { SETTINGS_NAMESPACE } from '../internal/config-spec.js'
3
+ import { CONFIG_DEFAULTS, SETTINGS_NAMESPACE } from '../internal/config-spec.js'
4
4
  import { createPtcToolView } from './client-tool-view.js'
5
5
  import { createPtcSettingsView } from './client-settings-view.js'
6
+ import { createCapabilityCommandCard, createCapabilityRefreshView, createSessionCapabilityControlsView } from './client-capabilities-view.js'
7
+ import { capabilityProfileConfiguration } from '../internal/runtime-config.js'
6
8
  import { createReplView } from './client-repl-view.js'
7
9
  import { createAuthoringView } from './client-authoring-view.js'
10
+ import { bindingToggleConversationDefinition } from './client-binding-toggle.js'
8
11
  import { createIndicatorView } from './client-indicator-view.js'
9
12
  import { createTypeScriptEditor } from './client-code-editor.js'
10
13
  import { createBindingConsole } from './client-console.js'
11
14
  import {
12
15
  createMenuChildrenEvidence,
13
16
  hostIconComponents,
17
+ isHostComponent,
14
18
  isHostIconComponent,
15
19
  isIdleSessionComposer,
16
20
  publishSettingsCard,
@@ -28,23 +32,84 @@ import { installStyles } from './client-styles.js'
28
32
  import { featureEnabled, registerGated } from './client-feature-gates.js'
29
33
  import { createCatalogOwner } from './client-catalog.js'
30
34
  import { createUserBindingsWorkbench } from './client-workbench.js'
31
- import { createBindingCommandAvailability, createReplObserver } from './client-transport.js'
35
+ import { createBindingCommandAvailability, createCommandAccess, createReplObserver } from './client-transport.js'
36
+ import { createActionButton, resolvePrimitives } from './client-primitives.js'
32
37
 
33
- window.__ModuleLoader__.load({
34
- // Replaced by the bundle entry with the package name from package.json.
35
- id: __PTC_PLUS_CLIENT_MODULE_ID__,
36
- factory: (require) => {
38
+ /** Settings snapshot used until the installed generation serves a transport. */
39
+ const UNAVAILABLE_PREFERENCE = Object.freeze({
40
+ status: 'unavailable',
41
+ writable: false,
42
+ value: CONFIG_DEFAULTS,
43
+ })
44
+
45
+ /**
46
+ * Resolve the settings preference scope of the running generation without
47
+ * depending on that generation publishing a particular transport name: the
48
+ * current one serves `configForms` and the preceding one served
49
+ * `settingsScope`. The plugin exposes the shipped Config defaults until a
50
+ * transport appears, prefers the current one, and retains live alternatives.
51
+ * A renamed or omitted transport degrades the settings surface instead of
52
+ * suspending apply() before any contribution is registered.
53
+ */
54
+ function createPreferenceScope(ctx) {
55
+ const listeners = new Set()
56
+ const registrations = new Map()
57
+ let bound
58
+ const notify = () => { for (const listener of [...listeners]) listener() }
59
+ const sync = () => {
60
+ const next = registrations.get('configForms') ?? registrations.get('settingsScope')
61
+ if (bound === next) return
62
+ bound = next
63
+ notify()
64
+ }
65
+ const adopt = (name, scope) => {
66
+ if (scope === undefined || scope === null) return undefined
67
+ const registration = { scope }
68
+ const unsubscribe = typeof scope.subscribe === 'function' ? scope.subscribe(() => {
69
+ if (bound === registration) notify()
70
+ }) : undefined
71
+ registrations.set(name, registration)
72
+ sync()
73
+ return () => {
74
+ unsubscribe?.()
75
+ if (registrations.get(name) !== registration) return
76
+ registrations.delete(name)
77
+ sync()
78
+ }
79
+ }
80
+ ctx.inject(['configForms'], scope => adopt('configForms', scope.configForms.get(SETTINGS_NAMESPACE)))
81
+ ctx.inject(['settingsScope'], scope => adopt('settingsScope', scope.settingsScope.bind({ namespace: SETTINGS_NAMESPACE })))
82
+ return Object.freeze({
83
+ getSnapshot: () => bound?.scope.getSnapshot() ?? UNAVAILABLE_PREFERENCE,
84
+ subscribe(listener) {
85
+ listeners.add(listener)
86
+ return () => listeners.delete(listener)
87
+ },
88
+ set: (key, value) => bound?.scope.set(key, value),
89
+ mutate: patch => bound?.scope.mutate(patch),
90
+ })
91
+ }
92
+
93
+ export function createClientPlugin(require) {
37
94
  const React = require('react')
38
- const primitives = require('@deepseek-ai/dsh-client-ui-primitives')
95
+ const { createPortal } = require('react-dom')
96
+ let primitives
97
+ try {
98
+ primitives = require('@deepseek-ai/dsh-client-ui-primitives') ?? {}
99
+ } catch {
100
+ primitives = {}
101
+ }
39
102
  const {
40
103
  Button,
41
104
  CodeBlock,
42
105
  DisclosureRow,
43
106
  Menu,
107
+ MenuFallback,
44
108
  Modal,
109
+ Select,
45
110
  Toast,
46
111
  Tooltip,
47
- } = primitives
112
+ } = resolvePrimitives(primitives, React, createPortal)
48
113
  const {
49
114
  check: IconCheckOutline14,
50
115
  chevron: IconChevronDownOutline14,
@@ -59,66 +124,27 @@ window.__ModuleLoader__.load({
59
124
  play: IconPlayOutline16,
60
125
  stop: IconStopFill16,
61
126
  } = hostIconComponents(primitives)
62
- const module = { exports: {} }
63
127
  const h = React.createElement
64
128
  const TypeScriptEditor = createTypeScriptEditor(React)
65
129
 
66
130
  function IconButton({ icon: Icon, label, ...props }) {
67
131
  const button = h('button', { ...props, type: 'button', className: 'ptcPlusIconButton',
68
132
  'aria-label': label, title: label }, isHostIconComponent(Icon) ? h(Icon, { size: 16 }) : label)
69
- return typeof Tooltip === 'function' ? h(Tooltip, { label, delayMs: 400 }, button) : button
133
+ return isHostComponent(Tooltip) ? h(Tooltip, { label, delayMs: 400 }, button) : button
70
134
  }
71
135
 
72
- function ActionButton({ className = '', 'data-kind': kind, ...props }) {
73
- return typeof Button === 'function'
74
- ? h(Button, {
75
- ...props, size: 'sm', variant: kind === 'primary' ? 'primary' : kind === 'ghost' ? 'ghost' : 'outline',
76
- className: className.split(' ').filter(name => name !== 'ptcPlusButton').join(' '),
77
- })
78
- : h('button', { ...props, className, 'data-kind': kind })
79
- }
136
+ const ActionButton = createActionButton(React, Button)
80
137
 
81
138
  const BindingConsole = createBindingConsole(React, { TypeScriptEditor, IconButton, ActionButton,
82
139
  icons: { play: IconPlayOutline16, stop: IconStopFill16, reset: IconRefreshOutline16, clear: IconTrashOutline16 } })
83
140
  const { PTCPlusToolRow } = createPtcToolView(React, {
84
- CodeBlock, DisclosureRow,
141
+ CodeBlock, DisclosureRow, createPortal,
85
142
  icons: { chevron: IconChevronDownOutline14, check: IconCheckOutline14, inspect: IconInspectOutline12 },
86
143
  })
87
144
 
88
- /**
89
- * Resolve the settings transport of the running generation. The current
90
- * release publishes `configForms`; the preceding one published
91
- * `settingsScope`. Both are optional child injections so the client entry
92
- * does not stay pending on the name the installed generation does not use.
93
- */
94
- function settingsPreferenceScope(ctx) {
95
- return new Promise((resolve, reject) => {
96
- let settled = false
97
- let configFormsWatcher
98
- let settingsScopeWatcher
99
- const take = (name, scope) => {
100
- if (settled) return
101
- settled = true
102
- if (name !== 'configForms' && typeof configFormsWatcher === 'function') configFormsWatcher()
103
- if (name !== 'settingsScope' && typeof settingsScopeWatcher === 'function') settingsScopeWatcher()
104
- resolve(name === 'configForms'
105
- ? scope.configForms.get(SETTINGS_NAMESPACE)
106
- : scope.settingsScope.bind({ namespace: SETTINGS_NAMESPACE }))
107
- }
108
- try {
109
- configFormsWatcher = ctx.inject(['configForms'], scope => take('configForms', scope))
110
- if (!settled) {
111
- settingsScopeWatcher = ctx.inject(['settingsScope'], scope => take('settingsScope', scope))
112
- }
113
- } catch (error) {
114
- reject(error)
115
- }
116
- })
117
- }
118
-
119
145
  async function apply(ctx) {
120
146
  const rpc = await createClientRpc(ctx)
121
- const preferenceScope = await settingsPreferenceScope(ctx)
147
+ const preferenceScope = createPreferenceScope(ctx)
122
148
  ctx.effect(() => ctx.locale.register(LOCALE_NS, SETTINGS_COPY), 'ptc-plus: settings dictionaries')
123
149
  ctx.effect(installStyles, 'ptc-plus: client styles')
124
150
 
@@ -141,7 +167,7 @@ window.__ModuleLoader__.load({
141
167
  const catalogOwner = createCatalogOwner({ callUserBindings })
142
168
  ctx.effect(() => () => catalogOwner.dispose(), 'ptc-plus: binding catalog sources')
143
169
  const { useWorkbenchController, UserBindingsWorkbench, BindingsDialog } = createUserBindingsWorkbench(React, {
144
- TypeScriptEditor, BindingConsole, IconButton, ActionButton, CodeBlock, Modal,
170
+ TypeScriptEditor, BindingConsole, IconButton, ActionButton, CodeBlock, Modal, Select,
145
171
  catalogOwner,
146
172
  icons: {
147
173
  refresh: IconRefreshOutline16, plus: IconPlusOutline16, check: IconCheckOutline14,
@@ -150,12 +176,43 @@ window.__ModuleLoader__.load({
150
176
  },
151
177
  })
152
178
  const { observeRepl } = createReplObserver({ rpc, ctx })
179
+ const capabilityCommands = createCommandAccess(ctx, 'capabilities')
180
+ const CapabilityCommandCard = createCapabilityCommandCard(React)
181
+ const CapabilityRefreshButton = createCapabilityRefreshView(React, capabilityCommands)
182
+ const SessionCapabilityControls = createSessionCapabilityControlsView(React, {
183
+ commands: capabilityCommands, Modal, Select,
184
+ async inspectSessionCatalog(sessionId, signal) {
185
+ const result = await rpc.call(RPC_CONTRACTS.capabilities, 'session-catalog', { sessionId }, signal)
186
+ if (result?.ok !== true) throw new Error(result?.error?.message ?? 'Session capability catalog unavailable')
187
+ return result.value
188
+ },
189
+ })
153
190
  const { PTCPlusSettingsCard, PTCPlusSettingsDialog } = createPtcSettingsView(React, {
154
- ActionButton, BindingsDialog, Modal, useWorkbenchController,
155
- icons: { chevron: IconChevronDownOutline14 },
191
+ ActionButton, BindingsDialog, Modal, Select, useWorkbenchController, CapabilityRefreshButton,
192
+ async inspectCapabilityTargets(signal) {
193
+ const result = await rpc.call(RPC_CONTRACTS.capabilities, 'targets', {}, signal)
194
+ if (result?.ok !== true) throw new Error(result?.error?.message ?? 'Capability refresh targets unavailable')
195
+ return result.value
196
+ },
197
+ async inspectCapabilityPlans(signal) {
198
+ const result = await rpc.call(RPC_CONTRACTS.capabilities, 'inspect', {}, signal)
199
+ if (result?.ok !== true) throw new Error(result?.error?.message ?? 'Capability plans unavailable')
200
+ return result.value
201
+ },
202
+ async inspectCapabilityCatalog(signal) {
203
+ const result = await rpc.call(RPC_CONTRACTS.capabilities, 'catalog', {}, signal)
204
+ if (result?.ok !== true) throw new Error(result?.error?.message ?? 'Capability catalog unavailable')
205
+ return result.value
206
+ },
207
+ async inspectCapabilityAllocation(payload, signal) {
208
+ const result = await rpc.call(RPC_CONTRACTS.capabilities, 'allocation', payload, signal)
209
+ if (result?.ok !== true) throw new Error(result?.error?.message ?? 'Capability allocation unavailable')
210
+ return result.value
211
+ },
212
+ icons: { search: IconSearchOutline16, chevron: IconChevronDownOutline14 },
156
213
  })
157
- const { ReplComposer, ReplConsole, ReplMemoryCard, replPopoverIsOpen, placeReplPopover } = createReplView(React, {
158
- CodeBlock, featureEnabled, normalizeReplMemorySnapshot, unavailableReplMemorySnapshot,
214
+ const { ReplComposer, ReplConsole, ReplMemoryCard, replPopoverIsOpen, placeReplPopover, useObservedReplMemory } = createReplView(React, {
215
+ CodeBlock, Select, featureEnabled, normalizeReplMemorySnapshot, unavailableReplMemorySnapshot,
159
216
  useSessionPreset, sessionUsesPtcPreset, useWorkbenchController, UserBindingsWorkbench,
160
217
  icons: { search: IconSearchOutline16, chevron: IconChevronDownOutline14 },
161
218
  })
@@ -178,6 +235,15 @@ window.__ModuleLoader__.load({
178
235
  && (key !== 'bindingUpdates' || after.value.legacyBindingSettings !== true)
179
236
  ? 'status.applied' : 'status.conflict'
180
237
  }
238
+ const updateCapabilityConfiguration = async configuration => {
239
+ const before = preferenceScope.getSnapshot()
240
+ if (before.status !== 'ready' || before.writable !== true || !featureEnabled(before, 'plugin')) throw new Error('Capability settings are not writable')
241
+ const validated = capabilityProfileConfiguration(configuration)
242
+ await preferenceScope.mutate(Object.entries(validated).map(([key, value]) => ({ op: 'set', path: [key], value })))
243
+ const after = preferenceScope.getSnapshot()
244
+ if (after.status !== 'ready' || Object.entries(validated).some(([key, value]) => after.value?.[key] !== value)) throw new Error('Capability configuration was not applied')
245
+ return 'status.applied'
246
+ }
181
247
  // One gated-registration shape for every settings-driven contribution.
182
248
  const settingsGate = (feature, register) => ({
183
249
  subscribe: listener => preferenceScope.subscribe(listener),
@@ -191,20 +257,25 @@ window.__ModuleLoader__.load({
191
257
  const settingsCard = publishSettingsCard(ctx, {
192
258
  bundleName: __PTC_PLUS_CLIENT_MODULE_ID__,
193
259
  locale: LOCALE_NS,
194
- injectProps: () => ({ ...settingsProps(), updateSetting }),
260
+ injectProps: () => ({ ...settingsProps(), updateSetting, updateCapabilityConfiguration }),
195
261
  component: PTCPlusSettingsCard,
196
262
  })
197
263
 
264
+ function ConfiguredToolRow(props) {
265
+ const snapshot = React.useSyncExternalStore(preferenceScope.subscribe, preferenceScope.getSnapshot)
266
+ return h(PTCPlusToolRow, { ...props, hoverEnabled: featureEnabled(snapshot, 'toolHover') })
267
+ }
268
+
198
269
  ctx.slots.inject('tool.call.toolview', () => registerGated(ctx, settingsGate('toolView', () => {
199
270
  // Two rows share one eligibility decision; roll both back if either fails.
200
271
  const disposers = []
201
272
  try {
202
273
  disposers.push(ctx.slots.register({
203
274
  name: 'tool.call.toolview', key: 'run_code', locale: LOCALE_NS,
204
- }, PTCPlusToolRow))
275
+ }, ConfiguredToolRow))
205
276
  disposers.push(ctx.slots.register({
206
277
  name: 'tool.call.toolview', key: 'edit_run_code', locale: LOCALE_NS,
207
- }, PTCPlusToolRow))
278
+ }, ConfiguredToolRow))
208
279
  } catch (error) {
209
280
  disposers.reverse().forEach(dispose => dispose())
210
281
  throw error
@@ -255,9 +326,9 @@ window.__ModuleLoader__.load({
255
326
  // One probe answer serves every session's composer entry for this Client.
256
327
  const menuChildren = createMenuChildrenEvidence()
257
328
  const { BindingAuthorButton, BindingReviewDock, BindingCommandCard } = createAuthoringView(React, {
258
- ActionButton, IconButton, Menu, Toast, Tooltip, CodeBlock, BindingsDialog, PTCPlusSettingsDialog,
329
+ ActionButton, IconButton, Menu, MenuFallback, Toast, Tooltip, CodeBlock, Modal, createPortal, BindingsDialog, PTCPlusSettingsDialog,
259
330
  useWorkbenchController, useBindingReview, catalogOwner, callUserBindings, subscribeReset,
260
- settingsCardSeat: settingsCard.seat, updateSetting, menuChildren,
331
+ settingsCardSeat: settingsCard.seat, updateSetting, updateCapabilityConfiguration, menuChildren, SessionCapabilityControls,
261
332
  icons: {
262
333
  sparkle: IconSparkle16, chevron: IconChevronDownOutline14,
263
334
  close: IconCloseOutline16, check: IconCheckOutline14,
@@ -268,6 +339,7 @@ window.__ModuleLoader__.load({
268
339
  normalizeReplMemorySnapshot, unavailableReplMemorySnapshot,
269
340
  ReplMemoryCard, replPopoverIsOpen, placeReplPopover,
270
341
  catalogOwner, subscribeReset,
342
+ useObservedReplMemory, observeRepl,
271
343
  })
272
344
 
273
345
  ctx.slots.inject('conversation.session.header.actions', () => registerGated(ctx, settingsGate('plugin', () => ctx.slots.register({
@@ -278,9 +350,18 @@ window.__ModuleLoader__.load({
278
350
  name: 'conversation.chat.commandview', key: 'binding', locale: LOCALE_NS,
279
351
  inject: settingsProps,
280
352
  }, props => h(BindingCommandCard, { ...props, key: props.node.commandId })))))
353
+ ctx.slots.inject('conversation.chat.commandview', () => registerGated(ctx, settingsGate('plugin', () => ctx.slots.register({
354
+ name: 'conversation.chat.commandview', key: 'capabilities', locale: LOCALE_NS,
355
+ }, props => h(CapabilityCommandCard, props)))))
356
+ ctx.inject(['uiConversation'], scope => scope.effect(() => scope.uiConversation.events.register(bindingToggleConversationDefinition),
357
+ 'ptc-plus binding configuration receipts'))
358
+ ctx.slots.inject('conversation.chat.node', () => ctx.effect(() => ctx.slots.register({
359
+ name: 'conversation.chat.node', key: 'ptc-plus-binding-toggle', locale: LOCALE_NS,
360
+ }, ({ node, t }) => h('p', { className: 'ptcPlusCapabilityReceipt', role: 'status' },
361
+ t(node.data.enabled ? 'bindings.toggleEnabled' : 'bindings.toggleDisabled', { name: node.data.name }))), 'ptc-plus binding configuration receipt renderer'))
281
362
  ctx.slots.inject('conversation.input.dock', () => ctx.slots.inject('conversation.input.left', () =>
282
363
  registerGated(ctx, settingsGate('bindings', () => ctx.slots.register({
283
- name: 'conversation.input.dock', id: 'ptc-plus-binding-review', order: 30, locale: LOCALE_NS,
364
+ name: 'conversation.input.dock', id: 'ptc-plus-binding-review', order: -30, locale: LOCALE_NS,
284
365
  }, props => typeof props.useProjection === 'function' && props.sessionId !== undefined
285
366
  ? h(BindingReviewDock, { ...props, key: props.sessionId }) : null)))))
286
367
  const availability = createBindingCommandAvailability(ctx)
@@ -300,21 +381,20 @@ window.__ModuleLoader__.load({
300
381
  return () => { unsubscribePreset(); unsubscribeSettings() }
301
382
  },
302
383
  isEnabled: () => sessionUsesPtcPreset(preset)
303
- && featureEnabled(preferenceScope.getSnapshot(), 'bindings'),
384
+ && featureEnabled(preferenceScope.getSnapshot(), 'plugin'),
304
385
  register: () => ctx.slots.register({
305
386
  name: 'conversation.input.left', id: 'ptc-plus-binding-author', order: 20, locale: LOCALE_NS,
306
387
  inject: sessionId => ({
307
- hooks: { ptcSettings: preferenceScope, bindingCommand: availability.source(sessionId) },
388
+ hooks: { ptcSettings: preferenceScope, bindingCommand: availability.source(sessionId),
389
+ capabilityCommand: capabilityCommands.source(sessionId) },
308
390
  }),
309
391
  }, props => props.sessionId === undefined ? null : h(BindingAuthorButton, { ...props, key: props.sessionId })),
310
392
  }))
311
393
  })
312
394
  }
313
395
 
314
- module.exports = {
396
+ return {
315
397
  apply,
316
398
  inject: ['slots', 'locale', 'connection', 'remote'],
317
399
  }
318
- return module.exports
319
- },
320
- })
400
+ }
Binary file
Binary file
Binary file
Binary file