dsh-ptc-plus 0.3.1 → 0.4.1

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 (200) hide show
  1. package/README.en.md +66 -73
  2. package/README.md +66 -73
  3. package/assets/ptc-plus-bindings-en.png +0 -0
  4. package/assets/ptc-plus-bindings-zh.png +0 -0
  5. package/assets/ptc-plus-repair-en.png +0 -0
  6. package/assets/ptc-plus-repair-zh.png +0 -0
  7. package/assets/ptc-plus-repl-workspace-en.png +0 -0
  8. package/assets/ptc-plus-repl-workspace-zh.png +0 -0
  9. package/assets/ptc-plus-settings-en.png +0 -0
  10. package/assets/ptc-plus-settings-zh.png +0 -0
  11. package/client.js +30610 -722
  12. package/compiler-amaro.cjs +5 -0
  13. package/compiler-amaro.cjs.map +6 -0
  14. package/compiler-asset-124f80c1bba92ff5fe79cfec6e8ad518f476de4a42514cae3919538887f510e8.txt +1 -0
  15. package/compiler-assets.json +3 -0
  16. package/compiler-core.cjs +554 -0
  17. package/compiler-core.cjs.map +6 -0
  18. package/compiler-platform.cjs +2 -0
  19. package/compiler-platform.cjs.map +6 -0
  20. package/compiler-typescript.cjs +388 -0
  21. package/compiler-typescript.cjs.map +6 -0
  22. package/docs/README.md +6 -0
  23. package/docs/adr/0004-declare-program-bindings-at-the-host.md +1 -1
  24. package/docs/adr/0006-rewrite-module-syntax-with-an-ast.md +6 -4
  25. package/docs/adr/0007-separate-worker-transport-from-session-semantics.md +15 -3
  26. package/docs/adr/0009-bound-expensive-acceptance-default.md +2 -0
  27. package/docs/adr/0010-session-log-derived-recovery-tips.md +59 -5
  28. package/docs/adr/0011-isolate-the-local-recovery-tip-provider.md +1 -1
  29. package/docs/adr/0012-preserve-mixed-destructuring-initialization.md +3 -1
  30. package/docs/adr/0013-isolate-repl-redeclaration-convenience.md +9 -3
  31. package/docs/adr/0014-persist-cell-rewrite-policy.md +11 -5
  32. package/docs/adr/0015-preserve-source-positions-through-rewrites.md +1 -1
  33. package/docs/adr/0016-archive-resolved-review-findings.md +1 -1
  34. package/docs/adr/0017-track-the-latest-dsh-public-surface.md +49 -0
  35. package/docs/adr/0018-use-versioned-fixture-for-ab-benchmark.md +3 -3
  36. package/docs/adr/0019-plugin-settings-and-kill-switch.md +8 -6
  37. package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
  38. package/docs/adr/0021-separate-host-bootstrap-from-session-runtime.md +17 -3
  39. package/docs/adr/0023-global-user-bindings.md +104 -0
  40. package/docs/adr/0024-repl-console-observation.md +33 -0
  41. package/docs/adr/0025-use-versioned-logical-binding-identities.md +119 -0
  42. package/docs/adr/0026-persist-the-delivery-verdict-against-the-verified-candidate.md +21 -0
  43. package/docs/adr/0027-run-the-session-kernel-in-a-killable-helper-process.md +37 -0
  44. package/docs/adr/0028-attach-to-the-host-ptc-execution-seam.md +103 -0
  45. package/docs/adr/0029-keep-plugin-unavailability-out-of-the-host-agent-lifecycle.md +27 -0
  46. package/docs/adr/0030-serve-both-typert-codec-generations-from-one-codec.md +27 -0
  47. package/docs/architecture.md +82 -22
  48. package/docs/binding-review-placement-design.md +200 -0
  49. package/docs/capability-projection.md +1 -1
  50. package/docs/client-ui.md +96 -20
  51. package/docs/durability-design.md +61 -24
  52. package/docs/evaluation.md +78 -6
  53. package/docs/installation.md +41 -6
  54. package/docs/program-data-plane.md +6 -0
  55. package/docs/publishing.md +5 -3
  56. package/docs/runtime-reference.md +79 -25
  57. package/docs/semantic-validation.md +29 -0
  58. package/docs/stateful-binding-updates-proposal.md +755 -0
  59. package/docs/user-bindings.en.md +64 -0
  60. package/docs/user-bindings.md +64 -0
  61. package/docs/value-wire.md +3 -3
  62. package/docs/verification.md +57 -0
  63. package/index.js +374 -92
  64. package/internal/ast-traversal.js +5 -2
  65. package/internal/binding-descriptors.js +1 -0
  66. package/internal/binding-pattern-traversal.js +25 -0
  67. package/internal/binding-pattern.js +26 -29
  68. package/internal/binding-source-analysis.js +391 -0
  69. package/internal/binding-update-policy.js +66 -0
  70. package/internal/bounded-worker-round.js +56 -0
  71. package/internal/callable-definition-environment.js +42 -0
  72. package/internal/callable-source-catalog.js +129 -0
  73. package/internal/callable-source-encoding.js +47 -0
  74. package/internal/callable-source-facts.js +459 -0
  75. package/internal/callable-source-format.js +2 -0
  76. package/internal/callable-source-lowering.js +123 -0
  77. package/internal/cell-analysis-contract.js +25 -0
  78. package/internal/cell-analysis.js +252 -242
  79. package/internal/cell-completion.js +15 -0
  80. package/internal/cell-error.js +7 -0
  81. package/internal/cell-parser.js +66 -0
  82. package/internal/cell-rewriter.js +3 -553
  83. package/internal/commonjs-export-evidence.js +63 -0
  84. package/internal/commonjs-source-evidence.js +72 -0
  85. package/internal/compiler-amaro.cjs +2 -0
  86. package/internal/compiler-compression.js +12 -0
  87. package/internal/compiler-data.js +58 -0
  88. package/internal/compiler-descriptors.js +54 -0
  89. package/internal/compiler-dynamic-cache.js +48 -0
  90. package/internal/compiler-entry.js +35 -0
  91. package/internal/compiler-generated-names.js +17 -0
  92. package/internal/compiler-intrinsics.js +84 -0
  93. package/internal/compiler-module-links.js +34 -0
  94. package/internal/compiler-operations.js +61 -0
  95. package/internal/compiler-platform-factory.js +84 -0
  96. package/internal/compiler-platform.js +136 -0
  97. package/internal/compiler-record-roles.js +53 -0
  98. package/internal/compiler-region-output.js +259 -0
  99. package/internal/compiler-resource-lowering.js +103 -0
  100. package/internal/compiler-scope-facts.js +115 -0
  101. package/internal/compiler-service.js +109 -0
  102. package/internal/compiler-source-cache.js +32 -0
  103. package/internal/compiler-source-pieces.js +93 -0
  104. package/internal/compiler-source-regions.js +132 -0
  105. package/internal/compiler-storage-source.js +54 -0
  106. package/internal/compiler-text.js +15 -0
  107. package/internal/compiler-typescript.cjs +2 -0
  108. package/internal/config-spec.js +91 -25
  109. package/internal/cordis-tools-owner.js +130 -21
  110. package/internal/diagnostic.js +27 -1
  111. package/internal/direct-surface-owner.js +76 -23
  112. package/internal/dynamic-binding-evidence.js +16 -0
  113. package/internal/dynamic-environment-compiler.js +779 -0
  114. package/internal/dynamic-environment-integration.js +87 -0
  115. package/internal/dynamic-environment-runtime.js +362 -0
  116. package/internal/dynamic-native-calls.js +150 -0
  117. package/internal/dynamic-native-runtime.js +248 -0
  118. package/internal/dynamic-scope-analysis.js +90 -0
  119. package/internal/edit-transport-owner.js +28 -3
  120. package/internal/execution-seam-compat.js +193 -0
  121. package/internal/failure-reporting.js +118 -18
  122. package/internal/host-rpc.js +66 -0
  123. package/internal/isolated-worker.js +548 -0
  124. package/internal/kernel-child.js +139 -0
  125. package/internal/kernel-worker.js +911 -116
  126. package/internal/language-semantics.js +14 -0
  127. package/internal/legacy-binding-catalog.js +48 -0
  128. package/internal/legacy-cell-analysis.js +600 -0
  129. package/internal/legacy-cell-parser.js +50 -0
  130. package/internal/legacy-cell-rewriter.js +631 -0
  131. package/internal/legacy-repl-convenience.js +291 -0
  132. package/internal/managed-module-operations.js +170 -0
  133. package/internal/module-compilation.js +321 -0
  134. package/internal/module-runtime-platform.js +19 -0
  135. package/internal/module-transform-contract.js +12 -0
  136. package/internal/native-await-declarations.js +68 -0
  137. package/internal/native-root-compilation.js +54 -0
  138. package/internal/native-root-dynamic.js +67 -0
  139. package/internal/recovery-tips.js +27 -15
  140. package/internal/rejected-cell-editor.js +13 -8
  141. package/internal/repl-convenience.js +2 -201
  142. package/internal/repl-memory-projection.js +81 -12
  143. package/internal/repl-observation-interest.js +70 -0
  144. package/internal/repl-rewrite-contract.js +21 -0
  145. package/internal/repl-scope-normalizer.js +2091 -0
  146. package/internal/repl-value-observer.js +114 -0
  147. package/internal/rpc-contract.js +52 -0
  148. package/internal/runtime-bridge-owner.js +172 -28
  149. package/internal/runtime-config.js +48 -51
  150. package/internal/runtime-contexts.js +82 -10
  151. package/internal/runtime-messages.js +111 -0
  152. package/internal/session-cell-executor.js +455 -91
  153. package/internal/session-journal-recovery.js +684 -0
  154. package/internal/session-journal-schema.js +106 -0
  155. package/internal/session-journal.js +237 -440
  156. package/internal/session-log-view.js +42 -9
  157. package/internal/session-runtime.js +325 -80
  158. package/internal/session-state.js +249 -40
  159. package/internal/source-position-map.js +211 -71
  160. package/internal/stateful-module-compiler.js +154 -0
  161. package/internal/stateful-module-runtime.js +303 -0
  162. package/internal/stateful-root-compiler.js +598 -0
  163. package/internal/stateful-root-runtime.js +340 -0
  164. package/internal/typert-codec-compat.js +28 -0
  165. package/internal/typescript-transform.js +29 -0
  166. package/internal/user-binding-authoring.js +70 -0
  167. package/internal/user-binding-console-worker.js +184 -0
  168. package/internal/user-binding-console.js +148 -0
  169. package/internal/user-binding-draft-projection.js +335 -0
  170. package/internal/user-binding-model-context.js +31 -0
  171. package/internal/user-binding-runner.js +56 -0
  172. package/internal/user-bindings-owner.js +1065 -0
  173. package/internal/user-bindings-store.js +293 -0
  174. package/internal/user-bindings.js +353 -0
  175. package/internal/value-wire-schema.js +28 -0
  176. package/internal/value-wire.js +29 -20
  177. package/internal/worker-client.js +57 -67
  178. package/internal/worker-environment.js +45 -0
  179. package/internal/worker-output-relay.js +29 -0
  180. package/internal/worker-shutdown.js +14 -0
  181. package/package.json +81 -11
  182. package/src/client-activity.js +109 -45
  183. package/src/client-authoring-view.js +580 -0
  184. package/src/client-binding-review.js +230 -0
  185. package/src/client-bindings-data.js +29 -0
  186. package/src/client-catalog.js +127 -0
  187. package/src/client-code-editor.js +84 -0
  188. package/src/client-console.js +112 -0
  189. package/src/client-copy.js +370 -0
  190. package/src/client-feature-gates.js +62 -0
  191. package/src/client-host-compat.js +150 -0
  192. package/src/client-indicator-view.js +267 -0
  193. package/src/client-repl-view.js +292 -0
  194. package/src/client-rpc.js +20 -0
  195. package/src/client-settings-view.js +221 -0
  196. package/src/client-styles.js +106 -0
  197. package/src/client-tool-view.js +108 -0
  198. package/src/client-transport.js +159 -0
  199. package/src/client-workbench.js +521 -0
  200. package/src/client.js +233 -615
@@ -1,5 +1,9 @@
1
1
  import { latestRecoveryTip } from './recovery-tips.js'
2
- import { projectSessionLog } from './session-log-view.js'
2
+ import { projectSessionLog, systemPromptSnapshotSections } from './session-log-view.js'
3
+ import {
4
+ PTC_BINDING_CATALOG, PTC_DELIVERY_CONTEXT, PTC_STATE_NAMES, readRuntimeMessage,
5
+ runtimeBindingCatalogMessage, runtimeNoticeMessage, runtimeStateMessage,
6
+ } from './runtime-messages.js'
3
7
 
4
8
  const REWRITE_FEEDBACK = 'tools:ptc-plus-rewrite-info'
5
9
  const CORDIS_RECOVERY = 'tools:ptc-plus-cordis-recovery'
@@ -8,15 +12,11 @@ const CORDIS_RECOVERY_TEXT = 'Recorded Cordis values in the recovered REPL are h
8
12
  function continuationFeedback(view) {
9
13
  const run = view.latestRun
10
14
  const rewrites = run?.rewrites
11
- if (rewrites === undefined || rewrites.length === 0) return undefined
12
- const details = rewrites.map(rewrite => rewrite.description).join('; ')
13
- if (run.journal === undefined) {
14
- return `The preceding run_code cell had these source adjustments: ${details}. Its completion is unknown because no valid execution journal is available. Inspect its tool result and live bindings before continuing; do not assume it completed or failed, and do not replay it automatically.`
15
- }
16
- if (run.journal.completion?.kind !== 'return') {
17
- return `The preceding run_code cell failed after a source adjustment: ${details}. Treat it as failed; inspect its tool result and live bindings before continuing, and do not replay it automatically.`
18
- }
19
- return undefined
15
+ if (rewrites === undefined || rewrites.length === 0 || run.journal !== undefined) return undefined
16
+ const descriptions = rewrites.map(rewrite => rewrite.description).join('; ')
17
+ const details = descriptions.length <= 2048 ? descriptions
18
+ : `${descriptions.slice(0, 2048)}... (source-adjustment list truncated)`
19
+ return `The preceding run_code cell had these source adjustments: ${details}. Its completion is unknown because no valid execution journal is available. Inspect its tool result and live bindings before continuing; do not assume it completed or failed, and do not replay it automatically.`
20
20
  }
21
21
 
22
22
  /** Build all dynamic PTC contexts from one session-log projection. */
@@ -35,3 +35,75 @@ export function sessionRuntimeContexts(agent, tipConfig, options = {}) {
35
35
  ]),
36
36
  })
37
37
  }
38
+
39
+ /** Project messages without treating an uncommitted proposal as delivery. */
40
+ export function projectRuntimeMessages(view, contexts, pending = []) {
41
+ if (view.visibleRuntimeMessages === undefined) return []
42
+ const sections = contexts.filter(context => PTC_STATE_NAMES.includes(context.name) && context.name !== PTC_BINDING_CATALOG)
43
+ const catalog = contexts.find(context => context.name === PTC_BINDING_CATALOG)
44
+ const records = view.visibleRuntimeMessages
45
+ const owned = records.filter(record => record.producer === 'ptc-plus' && record.form === 'snapshot').at(-1)
46
+ const legacy = records.filter(record => record.producer === 'aggregate').at(-1)
47
+ const pendingAggregate = pending.map(systemPromptSnapshotSections).filter(sections => sections !== undefined).at(-1)
48
+ const retained = owned?.sections
49
+ ?? (pendingAggregate ?? legacy?.sections)?.filter(section => PTC_STATE_NAMES.includes(section.name))
50
+ const hadState = view.ptcMessages.some(record => record.form === 'snapshot')
51
+ || view.systemPromptSnapshots.some(record => record.sections.some(section => PTC_STATE_NAMES.includes(section.name)))
52
+ const messages = []
53
+ const proposed = pending.map(readRuntimeMessage).filter(record => record !== undefined)
54
+ const pendingState = proposed.filter(record => record.form === 'snapshot').at(-1)
55
+ const previous = pendingState?.sections ?? retained
56
+ if ((sections.length > 0 || (previous !== undefined && previous.length > 0) || (previous === undefined && hadState))
57
+ && JSON.stringify(previous) !== JSON.stringify(sections)) {
58
+ messages.push(runtimeStateMessage(sections))
59
+ }
60
+ const previousCatalog = proposed.filter(record => record.form === 'catalog').at(-1)
61
+ ?? records.filter(record => record.form === 'catalog').at(-1)
62
+ const hadCatalog = view.ptcMessages.some(record => record.form === 'catalog')
63
+ if ((catalog !== undefined || previousCatalog !== undefined || hadCatalog)
64
+ && JSON.stringify(previousCatalog?.sections) !== JSON.stringify(catalog === undefined ? [] : [catalog])) {
65
+ messages.push(runtimeBindingCatalogMessage(catalog))
66
+ }
67
+ for (const tip of contexts.filter(context => context.name.startsWith('tools:ptc-plus-tip/'))) {
68
+ if (proposed.some(record => record.form === 'notice' && record.name === tip.name)) continue
69
+ if (view.ptcMessages.some(record => record.form === 'notice' && record.name === tip.name)
70
+ || view.systemPromptSnapshots.some(snapshot => snapshot.sections.some(section => section.name === tip.name))) continue
71
+ messages.push(runtimeNoticeMessage(tip))
72
+ }
73
+ return messages
74
+ }
75
+
76
+ /** Passive message delivery follows the actual public assembly and accepted step. */
77
+ export function createRuntimeMessageOwner(contextsForRequest) {
78
+ const requests = new WeakMap()
79
+ const disposedAgents = new WeakSet()
80
+ let disposed = false
81
+ const hasWitness = assembly => assembly.contexts?.some(context => (
82
+ context.name === PTC_DELIVERY_CONTEXT && context.text === ''
83
+ )) === true
84
+ return Object.freeze({
85
+ async assemble(initial, context, next) {
86
+ const assembly = await next()
87
+ if (!disposed && context?.agent !== null && typeof context?.agent === 'object'
88
+ && !disposedAgents.has(context.agent)) requests.set(context.agent, {
89
+ context,
90
+ allowed: hasWitness(initial) && hasWitness(assembly),
91
+ })
92
+ return hasWitness(assembly) ? {
93
+ ...assembly, contexts: assembly.contexts.filter(item => item.name !== PTC_DELIVERY_CONTEXT),
94
+ } : assembly
95
+ },
96
+ async preStep(payload, next) {
97
+ const decision = await next()
98
+ const request = requests.get(payload.agent)
99
+ if (disposed || decision.kind !== 'enter' || payload.signal?.aborted === true
100
+ || request?.allowed !== true || request.context.signal !== payload.signal) return decision
101
+ const messages = projectRuntimeMessages(
102
+ projectSessionLog(payload.agent), contextsForRequest(request.context), decision.messages,
103
+ )
104
+ return messages.length === 0 ? decision : { ...decision, messages: [...decision.messages, ...messages] }
105
+ },
106
+ disposeAgent(agent) { disposedAgents.add(agent); requests.delete(agent) },
107
+ dispose() { disposed = true },
108
+ })
109
+ }
@@ -0,0 +1,111 @@
1
+ import { createUserMessage } from '@deepseek-ai/dsh-llm'
2
+
3
+ export const PTC_DELIVERY_CONTEXT = 'tools:ptc-plus-message-delivery'
4
+ export const PTC_BINDING_CATALOG = 'tools:ptc-plus-user-binding-defaults'
5
+ export const PTC_STATE_NAMES = Object.freeze([
6
+ 'tools:ptc-plus-rewrite-info',
7
+ 'tools:ptc-plus-cordis-recovery',
8
+ 'tools:ptc-plus-user-binding-defaults',
9
+ // Historical active declarations remain readable so a new snapshot can withdraw them.
10
+ 'tools:ptc-plus-user-bindings',
11
+ ])
12
+ const MAX_STATE_CODE_UNITS = 65536
13
+ const MAX_NOTICE_CODE_UNITS = 8192
14
+ const LEGACY_STATE_PREFIX = 'PTC Plus current state. This replaces only earlier PTC state snapshots and PTC sections in historical aggregate snapshots; it does not replace tasks, Skill instructions, tool results, or other producers.'
15
+ const PREVIOUS_STATE_PREFIX = 'PTC Plus runtime recovery state. This replaces only earlier PTC state snapshots and PTC sections in historical aggregate snapshots; it does not replace the global binding API catalog, tasks, Skill instructions, tool results, or other producers.'
16
+ const PREVIOUS_CATALOG_PREFIXES = [
17
+ 'Global binding API catalog (PTC Plus). Only a later global binding API catalog replaces this catalog. Host runtime-context snapshots and PTC recovery snapshots do not withdraw it. This describes configured APIs, not successful initialization or current runtime values.',
18
+ 'Global binding API catalog (PTC Plus). Replaces earlier binding catalogs only; remains applicable until the next binding catalog.',
19
+ ]
20
+ const STATE_PREFIX = 'PTC Plus recovery status. Replaces earlier PTC recovery status, including PTC state in runtime-context snapshots. Global binding APIs are unchanged.'
21
+ const CATALOG_PREFIX = 'Global binding API reference for run_code (replaces the previous global binding reference):'
22
+ const EMPTY_CATALOG = 'No entries documented.'
23
+ const PREVIOUS_EMPTY_CATALOG = 'No global binding API documentation is currently configured. Earlier binding catalogs no longer apply.'
24
+
25
+ export function recoveryTipIdentity(name) {
26
+ if (typeof name !== 'string') return undefined
27
+ const match = /^tools:ptc-plus-tip\/(repeated-binding-failure|platform-command-failure)\/([1-9][0-9]*)$/.exec(name)
28
+ if (match === null || !Number.isSafeInteger(Number(match[2]))) return undefined
29
+ return { id: match[1], ordinal: Number(match[2]) }
30
+ }
31
+
32
+ function stateSections(value) {
33
+ if (!Array.isArray(value) || value.length > PTC_STATE_NAMES.length) return undefined
34
+ const sections = []
35
+ const names = new Set()
36
+ let size = 0
37
+ for (const section of value) {
38
+ if (!PTC_STATE_NAMES.includes(section?.name) || names.has(section.name)
39
+ || typeof section.text !== 'string' || section.text.length === 0) return undefined
40
+ size += section.text.length
41
+ if (size > MAX_STATE_CODE_UNITS) return undefined
42
+ names.add(section.name)
43
+ sections.push(Object.freeze({ name: section.name, text: section.text }))
44
+ }
45
+ return Object.freeze(sections)
46
+ }
47
+
48
+ function stateText(sections, prefix = STATE_PREFIX) {
49
+ return `${prefix}\n\n${sections.length === 0
50
+ ? 'No current PTC state declarations remain. Earlier PTC state claims no longer apply.'
51
+ : sections.map(section => section.text).join('\n\n')}`
52
+ }
53
+
54
+ /** Recognize only bounded, formed PTC records, never authoring tasks or Skills. */
55
+ export function readRuntimeMessage(message) {
56
+ const source = message?.source
57
+ if (source?.kind !== 'plugin' || source.plugin !== 'ptc-plus'
58
+ || !Array.isArray(message.content) || message.content.length !== 1
59
+ || message.content[0]?.type !== 'text') return undefined
60
+ const text = message.content[0].text
61
+ if (source.form === 'snapshot') {
62
+ const sections = stateSections(source.sections)
63
+ if (sections !== undefined && [STATE_PREFIX, PREVIOUS_STATE_PREFIX, LEGACY_STATE_PREFIX]
64
+ .some(prefix => text === stateText(sections, prefix))) {
65
+ return { form: 'snapshot', sections }
66
+ }
67
+ } else if (source.form === 'catalog' && typeof text === 'string') {
68
+ const prefix = [CATALOG_PREFIX, ...PREVIOUS_CATALOG_PREFIXES].find(prefix => text.startsWith(`${prefix}\n\n`))
69
+ if (prefix === undefined) return undefined
70
+ const body = text.slice(prefix.length + 2)
71
+ if (body.length > 0 && body.length <= MAX_STATE_CODE_UNITS) {
72
+ const empty = body === (prefix === CATALOG_PREFIX ? EMPTY_CATALOG : PREVIOUS_EMPTY_CATALOG)
73
+ return { form: 'catalog', sections: stateSections(empty ? [] : [{ name: PTC_BINDING_CATALOG, text: body }]) }
74
+ }
75
+ } else if (source.form === 'notice' && recoveryTipIdentity(source.summary) !== undefined
76
+ && typeof text === 'string' && text.length > 0 && text.length <= MAX_NOTICE_CODE_UNITS) {
77
+ return { form: 'notice', name: source.summary, text }
78
+ }
79
+ return undefined
80
+ }
81
+
82
+ /** One literal configuration document, independent of runtime recovery state. */
83
+ export function runtimeBindingCatalogMessage(context) {
84
+ if (context !== undefined && (context?.name !== PTC_BINDING_CATALOG
85
+ || typeof context.text !== 'string' || context.text.length === 0
86
+ || context.text.length > MAX_STATE_CODE_UNITS || context.text === EMPTY_CATALOG || context.text === PREVIOUS_EMPTY_CATALOG)) {
87
+ throw new Error('invalid PTC binding catalog')
88
+ }
89
+ return createUserMessage({
90
+ source: { kind: 'plugin', plugin: 'ptc-plus', form: 'catalog' },
91
+ content: [{ type: 'text', text: `${CATALOG_PREFIX}\n\n${context?.text ?? EMPTY_CATALOG}` }],
92
+ })
93
+ }
94
+
95
+ export function runtimeStateMessage(value) {
96
+ const sections = stateSections(value)
97
+ if (sections === undefined) throw new Error('invalid PTC runtime state sections')
98
+ return createUserMessage({
99
+ source: { kind: 'plugin', plugin: 'ptc-plus', form: 'snapshot', sections },
100
+ content: [{ type: 'text', text: stateText(sections) }],
101
+ })
102
+ }
103
+
104
+ export function runtimeNoticeMessage(tip) {
105
+ const message = createUserMessage({
106
+ source: { kind: 'plugin', plugin: 'ptc-plus', form: 'notice', summary: tip.name },
107
+ content: [{ type: 'text', text: tip.text }],
108
+ })
109
+ if (readRuntimeMessage(message) === undefined) throw new Error('invalid PTC recovery notice')
110
+ return message
111
+ }