dsh-ptc-plus 0.5.2 → 0.5.4

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 (72) hide show
  1. package/README.en.md +4 -2
  2. package/README.md +4 -2
  3. package/client.cjs +3392 -2811
  4. package/compiler-core.cjs +127 -127
  5. package/compiler-core.cjs.map +2 -2
  6. package/docs/README.md +1 -0
  7. package/docs/adr/0017-track-the-latest-dsh-public-surface.md +4 -2
  8. package/docs/adr/0019-plugin-settings-and-kill-switch.md +2 -2
  9. package/docs/adr/0023-global-user-bindings.md +12 -0
  10. package/docs/adr/0028-attach-to-the-host-ptc-execution-seam.md +1 -1
  11. package/docs/adr/0030-serve-both-typert-codec-generations-from-one-codec.md +2 -2
  12. package/docs/adr/0044-coexist-with-the-official-persistent-repl.md +4 -4
  13. package/docs/adr/0046-gate-the-commit-with-the-semantic-evidence-tier.md +1 -1
  14. package/docs/adr/0048-supersede-a-rewritten-cell.md +48 -0
  15. package/docs/adr/0049-prove-a-settlement-against-its-published-record.md +53 -0
  16. package/docs/adr/0050-read-host-surfaces-through-their-published-contract.md +48 -0
  17. package/docs/adr/README.md +7 -1
  18. package/docs/architecture.md +1 -1
  19. package/docs/capability-planning-components.md +6 -6
  20. package/docs/capability-projection.md +1 -1
  21. package/docs/capability-surface.md +133 -0
  22. package/docs/client-ui.md +17 -15
  23. package/docs/client-visual-contract.md +7 -7
  24. package/docs/durability-design.md +9 -2
  25. package/docs/installation.md +17 -10
  26. package/docs/panel-concept.md +171 -0
  27. package/docs/releases/v0.5.2.md +26 -14
  28. package/docs/releases/v0.5.3.md +77 -0
  29. package/docs/releases/v0.5.4.md +75 -0
  30. package/docs/runtime-reference.md +21 -1
  31. package/docs/user-bindings.en.md +15 -0
  32. package/docs/user-bindings.md +15 -0
  33. package/docs/v0.5.3-goals.md +117 -0
  34. package/docs/verification.md +4 -4
  35. package/index.js +176 -41
  36. package/internal/binding-adoption.js +228 -0
  37. package/internal/capability-command-receipt.js +106 -8
  38. package/internal/capability-environment.js +1109 -312
  39. package/internal/capability-plan.js +18 -2
  40. package/internal/capability-policy.js +13 -0
  41. package/internal/capability-selection.js +330 -0
  42. package/internal/config-spec.js +14 -5
  43. package/internal/cordis-tools-owner.js +2 -1
  44. package/internal/direct-surface-owner.js +44 -17
  45. package/internal/edit-transport-owner.js +6 -5
  46. package/internal/execution-provider-owner.js +6 -0
  47. package/internal/execution-seam-compat.js +25 -0
  48. package/internal/host-tool-sdk.js +308 -0
  49. package/internal/message-sources.js +21 -0
  50. package/internal/official-repl-priority.js +31 -10
  51. package/internal/program-bindings.js +25 -5
  52. package/internal/repl-memory-projection.js +21 -2
  53. package/internal/runtime-bridge-owner.js +118 -9
  54. package/internal/runtime-config.js +10 -0
  55. package/internal/runtime-messages.js +5 -0
  56. package/internal/session-journal-recovery.js +210 -32
  57. package/internal/session-journal-schema.js +3 -0
  58. package/internal/session-journal.js +46 -9
  59. package/internal/session-log-view.js +69 -7
  60. package/internal/session-runtime.js +106 -39
  61. package/internal/settings-compat.js +6 -0
  62. package/internal/user-bindings-owner.js +126 -6
  63. package/package.json +59 -37
  64. package/src/client-authoring-view.js +7 -8
  65. package/src/client-capabilities-view.js +874 -909
  66. package/src/client-capability-sort.js +22 -9
  67. package/src/client-copy.js +118 -272
  68. package/src/client-indicator-view.js +2 -1
  69. package/src/client-repl-view.js +35 -16
  70. package/src/client-settings-view.js +90 -33
  71. package/src/client-styles.js +67 -19
  72. package/src/client.js +49 -22
package/src/client.js CHANGED
@@ -3,8 +3,9 @@ import { RPC_CONTRACTS } from '../internal/rpc-contract.js'
3
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'
6
+ import { createCapabilityCommandCard, createCapabilityRefreshView, createCapabilitySurfaceView } from './client-capabilities-view.js'
7
7
  import { capabilityProfileConfiguration } from '../internal/runtime-config.js'
8
+ import { capabilityPolicyForConfig } from '../internal/capability-policy.js'
8
9
  import { createReplView } from './client-repl-view.js'
9
10
  import { createAuthoringView } from './client-authoring-view.js'
10
11
  import { bindingToggleConversationDefinition } from './client-binding-toggle.js'
@@ -24,6 +25,7 @@ import {
24
25
  } from './client-host-compat.js'
25
26
  import {
26
27
  normalizeReplMemorySnapshot,
28
+ normalizeReplMemoryView,
27
29
  unavailableReplMemorySnapshot,
28
30
  } from '../internal/repl-memory-projection.js'
29
31
  import { createBindingReviews } from './client-binding-review.js'
@@ -177,18 +179,28 @@ export function createClientPlugin(require) {
177
179
  })
178
180
  const { observeRepl } = createReplObserver({ rpc, ctx })
179
181
  const capabilityCommands = createCommandAccess(ctx, 'capabilities')
182
+ // The panel's binding rows write through the same `/binding` command a human
183
+ // types, so they borrow its availability source instead of a second channel.
184
+ const bindingCommands = createBindingCommandAvailability(ctx)
180
185
  const CapabilityCommandCard = createCapabilityCommandCard(React)
181
186
  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
- },
187
+ // One read serves both entrances. A request that names a session states that
188
+ // session's declared face; a request that names none states the Host's own
189
+ // declaration, which is the process-scope object set this entrance can state — a
190
+ // preset's agent-scope entries exist only in a session's declared face.
191
+ async function inspectSessionCatalog(sessionId, signal) {
192
+ const result = await rpc.call(RPC_CONTRACTS.capabilities, 'session-catalog',
193
+ typeof sessionId === 'string' && sessionId ? { sessionId } : {}, signal)
194
+ if (result?.ok !== true) throw new Error(result?.error?.message ?? 'Session capability catalog unavailable')
195
+ return result.value
196
+ }
197
+ // The capability page has one renderer. The session entry and the settings entry
198
+ // both mount it; neither adds a column, a word, a control or a receipt of its own.
199
+ const CapabilitySurface = createCapabilitySurfaceView(React, {
200
+ commands: capabilityCommands, bindingCommands, Modal, Select, inspectSessionCatalog,
189
201
  })
190
202
  const { PTCPlusSettingsCard, PTCPlusSettingsDialog } = createPtcSettingsView(React, {
191
- ActionButton, BindingsDialog, Modal, Select, useWorkbenchController, CapabilityRefreshButton,
203
+ ActionButton, BindingsDialog, Modal, Select, useWorkbenchController, CapabilityRefreshButton, CapabilitySurface,
192
204
  async inspectCapabilityTargets(signal) {
193
205
  const result = await rpc.call(RPC_CONTRACTS.capabilities, 'targets', {}, signal)
194
206
  if (result?.ok !== true) throw new Error(result?.error?.message ?? 'Capability refresh targets unavailable')
@@ -199,20 +211,18 @@ export function createClientPlugin(require) {
199
211
  if (result?.ok !== true) throw new Error(result?.error?.message ?? 'Capability plans unavailable')
200
212
  return result.value
201
213
  },
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
214
  async inspectCapabilityAllocation(payload, signal) {
208
215
  const result = await rpc.call(RPC_CONTRACTS.capabilities, 'allocation', payload, signal)
209
216
  if (result?.ok !== true) throw new Error(result?.error?.message ?? 'Capability allocation unavailable')
210
217
  return result.value
211
218
  },
212
- icons: { search: IconSearchOutline16, chevron: IconChevronDownOutline14 },
219
+ // The settings page reads one icon: its navigation chevron. The search icon belonged to
220
+ // the second renderer's toolbar row, which this page no longer has.
221
+ icons: { chevron: IconChevronDownOutline14 },
213
222
  })
214
223
  const { ReplComposer, ReplConsole, ReplMemoryCard, replPopoverIsOpen, placeReplPopover, useObservedReplMemory } = createReplView(React, {
215
- CodeBlock, Select, featureEnabled, normalizeReplMemorySnapshot, unavailableReplMemorySnapshot,
224
+ CodeBlock, Select, featureEnabled, normalizeReplMemorySnapshot, normalizeReplMemoryView,
225
+ unavailableReplMemorySnapshot,
216
226
  useSessionPreset, sessionUsesPtcPreset, useWorkbenchController, UserBindingsWorkbench,
217
227
  icons: { search: IconSearchOutline16, chevron: IconChevronDownOutline14 },
218
228
  })
@@ -239,9 +249,24 @@ export function createClientPlugin(require) {
239
249
  const before = preferenceScope.getSnapshot()
240
250
  if (before.status !== 'ready' || before.writable !== true || !featureEnabled(before, 'plugin')) throw new Error('Capability settings are not writable')
241
251
  const validated = capabilityProfileConfiguration(configuration)
242
- await preferenceScope.mutate(Object.entries(validated).map(([key, value]) => ({ op: 'set', path: [key], value })))
252
+ const synthesized = JSON.stringify(capabilityPolicyForConfig({ ...validated, capabilityPolicy: undefined }))
253
+ const ops = Object.entries(validated)
254
+ .filter(([key]) => key !== 'capabilityPolicy')
255
+ .map(([key, value]) => ({ op: 'set', path: [key], value }))
256
+ // A policy the rest of this configuration would synthesize belongs to no record: writing it
257
+ // would freeze a synthesized bottom layer into the record and let the management switch
258
+ // reach cells that must read 自动 (capability-surface §8.1c). The record may still hold one
259
+ // from an earlier apply, so remove it with the service's own unset op instead of leaving it.
260
+ const policyWritten = validated.capabilityPolicy !== undefined && validated.capabilityPolicy !== synthesized
261
+ ops.push(policyWritten
262
+ ? { op: 'set', path: ['capabilityPolicy'], value: validated.capabilityPolicy }
263
+ : { op: 'unset', path: ['capabilityPolicy'] })
264
+ await preferenceScope.mutate(ops)
243
265
  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')
266
+ const unchanged = Object.entries(validated).every(([key, value]) => key === 'capabilityPolicy'
267
+ ? (policyWritten ? after.value?.capabilityPolicy === value : after.value?.capabilityPolicy === undefined)
268
+ : after.value?.[key] === value)
269
+ if (after.status !== 'ready' || !unchanged) throw new Error('Capability configuration was not applied')
245
270
  return 'status.applied'
246
271
  }
247
272
  // One gated-registration shape for every settings-driven contribution.
@@ -305,7 +330,10 @@ export function createClientPlugin(require) {
305
330
  isEnabled: () => featureEnabled(preferenceScope.getSnapshot(), 'replView')
306
331
  && sessionUsesPtcPreset(preset),
307
332
  register: () => viewScope.slots.register({
308
- name: 'conversation.view', id: 'ptc-plus-repl', label: 'REPL', order: 20,
333
+ // A plugin contribution trails the Host's own tabs: chat is 0 and the
334
+ // experimental statistics tab is 40, and a REPL tab that sorts before them
335
+ // pushes a Host tab to the right of a plugin's.
336
+ name: 'conversation.view', id: 'ptc-plus-repl', label: 'REPL', order: 50,
309
337
  locale: LOCALE_NS, inject: () => ({ ...settingsProps(), hideComposer, observeRepl }),
310
338
  }, props => typeof props.useProjection === 'function' ? h(ReplConsole, props) : null),
311
339
  })
@@ -328,7 +356,7 @@ export function createClientPlugin(require) {
328
356
  const { BindingAuthorButton, BindingReviewDock, BindingCommandCard } = createAuthoringView(React, {
329
357
  ActionButton, IconButton, Menu, MenuFallback, Toast, Tooltip, CodeBlock, Modal, createPortal, BindingsDialog, PTCPlusSettingsDialog,
330
358
  useWorkbenchController, useBindingReview, catalogOwner, callUserBindings, subscribeReset,
331
- settingsCardSeat: settingsCard.seat, updateSetting, updateCapabilityConfiguration, menuChildren, SessionCapabilityControls,
359
+ settingsCardSeat: settingsCard.seat, updateSetting, updateCapabilityConfiguration, menuChildren, SessionCapabilityControls: CapabilitySurface,
332
360
  icons: {
333
361
  sparkle: IconSparkle16, chevron: IconChevronDownOutline14,
334
362
  close: IconCloseOutline16, check: IconCheckOutline14,
@@ -364,7 +392,6 @@ export function createClientPlugin(require) {
364
392
  name: 'conversation.input.dock', id: 'ptc-plus-binding-review', order: -30, locale: LOCALE_NS,
365
393
  }, props => typeof props.useProjection === 'function' && props.sessionId !== undefined
366
394
  ? h(BindingReviewDock, { ...props, key: props.sessionId }) : null)))))
367
- const availability = createBindingCommandAvailability(ctx)
368
395
  // The composer binding entry belongs to the PTC surface, exactly like the
369
396
  // header indicator and the REPL tab. A non-PTC session keeps plugin
370
397
  // settings and `/binding` command cards, but shows no binding shortcut and
@@ -385,7 +412,7 @@ export function createClientPlugin(require) {
385
412
  register: () => ctx.slots.register({
386
413
  name: 'conversation.input.left', id: 'ptc-plus-binding-author', order: 20, locale: LOCALE_NS,
387
414
  inject: sessionId => ({
388
- hooks: { ptcSettings: preferenceScope, bindingCommand: availability.source(sessionId),
415
+ hooks: { ptcSettings: preferenceScope, bindingCommand: bindingCommands.source(sessionId),
389
416
  capabilityCommand: capabilityCommands.source(sessionId) },
390
417
  }),
391
418
  }, props => props.sessionId === undefined ? null : h(BindingAuthorButton, { ...props, key: props.sessionId })),