@puredesktop/puredesktop-ui-bridge 2.1.6 → 2.1.8
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/package.json +55 -1
- package/src/bridge/agentTypes.ts +21 -1
- package/src/bridge/collectionImagePaste.ts +19 -1
- package/src/bridge/context.mjs +32 -0
- package/src/bridge/documents.d.mts +76 -0
- package/src/bridge/documents.mjs +40 -0
- package/src/bridge/methods.d.mts +23 -0
- package/src/bridge/methods.mjs +23 -0
- package/src/bridge/pureRender/base.css +44 -0
- package/src/bridge/pureRender/document.ts +29 -2
- package/src/bridge/pureRender/index.ts +3 -0
- package/src/bridge/pureRender/normalize.ts +167 -0
- package/src/bridge/pureRender/sanitizeExportBody.test.ts +51 -0
- package/src/bridge/pureRender/sanitizeExportBody.ts +61 -0
- package/src/bridge/pureRender/styles.ts +125 -5
- package/src/bridge/pureRender/theme.test.ts +259 -0
- package/src/bridge/pureRender/theme.ts +19 -1
- package/src/bridge/pureRender/types.ts +33 -0
- package/src/bridge/pureRender/visualLayoutInspection.test.ts +26 -0
- package/src/bridge/pureRender/visualLayoutInspection.ts +75 -0
- package/src/bridge/react/useDocumentHotkeys.ts +41 -0
- package/src/bridge/react/useDocumentLifecycle.tsx +359 -0
- package/src/bridge/react/usePlatformAppSettings.test.tsx +105 -0
- package/src/bridge/react/usePlatformAppSettings.tsx +104 -0
- package/src/bridge/react/usePlatformJsonStore.test.tsx +152 -0
- package/src/bridge/react/usePlatformJsonStore.tsx +149 -0
- package/src/bridge/storage.d.mts +3 -1
- package/src/bridge/storage.test.ts +2 -2
- package/src/bridge/types.ts +7 -0
- package/src/components/agents/AgentDrawerPanel.tsx +2 -0
- package/src/components/agents/AgentMessageList.tsx +6 -1
- package/src/components/agents/AgentToolCallCard.tsx +20 -20
- package/src/components/agents/ContextPicker.tsx +239 -0
- package/src/components/agents/agentPanelStyles.ts +3 -4
- package/src/components/agents/agentTypes.ts +2 -0
- package/src/components/chrome/WorkspaceTabStrip.tsx +18 -1
- package/src/components/chrome/workspaceTabTypes.ts +2 -0
- package/src/components/common/containers/AppFrame.test.tsx +4 -4
- package/src/components/common/containers/AppFrame.tsx +10 -1
- package/src/components/common/containers/AppHeader.tsx +22 -0
- package/src/components/common/documents/DocumentHeaderActions.tsx +206 -0
- package/src/components/common/documents/DocumentSwitcher.tsx +1176 -0
- package/src/components/common/documents/index.ts +8 -0
- package/src/components/common/research/EvidenceDossier.tsx +1232 -150
- package/src/components/common/research/index.ts +2 -0
- package/src/components/print-design/PrintDesignPanel.test.tsx +430 -40
- package/src/components/print-design/PrintDesignPanel.tsx +1770 -207
- package/src/components/print-design/index.ts +2 -0
- package/src/components/print-design/previewContent.test.ts +32 -0
- package/src/components/print-design/previewContent.ts +31 -0
- package/src/context/buildContextDocument.test.ts +240 -0
- package/src/context/buildContextDocument.ts +309 -0
- package/src/context/contextAccess.ts +66 -0
- package/src/context/contextConfig.ts +72 -0
- package/src/context/contextDocument.test.ts +155 -0
- package/src/context/contextDocument.ts +300 -0
- package/src/context/contextSections.test.ts +88 -0
- package/src/context/contextSections.ts +84 -0
- package/src/context/htmlToContextMarkdown.test.ts +134 -0
- package/src/context/htmlToContextMarkdown.ts +369 -0
- package/src/theme/appAccents.test.ts +36 -35
- package/src/theme/appAccents.ts +87 -104
- package/src/theme/appIdentityCss.mjs +169 -231
- package/src/theme/appIdentityCss.ts +213 -233
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@puredesktop/puredesktop-ui-bridge",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.8",
|
|
4
4
|
"description": "PureScience plugin SDK — bridge client, theme, and shared UI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -113,6 +113,9 @@
|
|
|
113
113
|
"./bridge/dialog.mjs": "./src/bridge/dialog.mjs",
|
|
114
114
|
"./bridge/dialog": "./src/bridge/dialog.mjs",
|
|
115
115
|
"./bridge/dialog.js": "./src/bridge/dialog.mjs",
|
|
116
|
+
"./bridge/documents.mjs": "./src/bridge/documents.mjs",
|
|
117
|
+
"./bridge/documents": "./src/bridge/documents.mjs",
|
|
118
|
+
"./bridge/documents.js": "./src/bridge/documents.mjs",
|
|
116
119
|
"./bridge/events.mjs": "./src/bridge/events.mjs",
|
|
117
120
|
"./bridge/events": "./src/bridge/events.mjs",
|
|
118
121
|
"./bridge/events.js": "./src/bridge/events.mjs",
|
|
@@ -190,6 +193,9 @@
|
|
|
190
193
|
"./bridge/pureRender/samples.ts": "./src/bridge/pureRender/samples.ts",
|
|
191
194
|
"./bridge/pureRender/samples": "./src/bridge/pureRender/samples.ts",
|
|
192
195
|
"./bridge/pureRender/samples.js": "./src/bridge/pureRender/samples.ts",
|
|
196
|
+
"./bridge/pureRender/sanitizeExportBody.ts": "./src/bridge/pureRender/sanitizeExportBody.ts",
|
|
197
|
+
"./bridge/pureRender/sanitizeExportBody": "./src/bridge/pureRender/sanitizeExportBody.ts",
|
|
198
|
+
"./bridge/pureRender/sanitizeExportBody.js": "./src/bridge/pureRender/sanitizeExportBody.ts",
|
|
193
199
|
"./bridge/pureRender/styles.ts": "./src/bridge/pureRender/styles.ts",
|
|
194
200
|
"./bridge/pureRender/styles": "./src/bridge/pureRender/styles.ts",
|
|
195
201
|
"./bridge/pureRender/styles.js": "./src/bridge/pureRender/styles.ts",
|
|
@@ -207,6 +213,12 @@
|
|
|
207
213
|
"./bridge/react/useDebouncedEffect.ts": "./src/bridge/react/useDebouncedEffect.ts",
|
|
208
214
|
"./bridge/react/useDebouncedEffect": "./src/bridge/react/useDebouncedEffect.ts",
|
|
209
215
|
"./bridge/react/useDebouncedEffect.js": "./src/bridge/react/useDebouncedEffect.ts",
|
|
216
|
+
"./bridge/react/useDocumentHotkeys.ts": "./src/bridge/react/useDocumentHotkeys.ts",
|
|
217
|
+
"./bridge/react/useDocumentHotkeys": "./src/bridge/react/useDocumentHotkeys.ts",
|
|
218
|
+
"./bridge/react/useDocumentHotkeys.js": "./src/bridge/react/useDocumentHotkeys.ts",
|
|
219
|
+
"./bridge/react/useDocumentLifecycle.tsx": "./src/bridge/react/useDocumentLifecycle.tsx",
|
|
220
|
+
"./bridge/react/useDocumentLifecycle": "./src/bridge/react/useDocumentLifecycle.tsx",
|
|
221
|
+
"./bridge/react/useDocumentLifecycle.js": "./src/bridge/react/useDocumentLifecycle.tsx",
|
|
210
222
|
"./bridge/react/useIpc.tsx": "./src/bridge/react/useIpc.tsx",
|
|
211
223
|
"./bridge/react/useIpc": "./src/bridge/react/useIpc.tsx",
|
|
212
224
|
"./bridge/react/useIpc.js": "./src/bridge/react/useIpc.tsx",
|
|
@@ -225,6 +237,9 @@
|
|
|
225
237
|
"./bridge/react/usePlatformAppManifest.tsx": "./src/bridge/react/usePlatformAppManifest.tsx",
|
|
226
238
|
"./bridge/react/usePlatformAppManifest": "./src/bridge/react/usePlatformAppManifest.tsx",
|
|
227
239
|
"./bridge/react/usePlatformAppManifest.js": "./src/bridge/react/usePlatformAppManifest.tsx",
|
|
240
|
+
"./bridge/react/usePlatformAppSettings.tsx": "./src/bridge/react/usePlatformAppSettings.tsx",
|
|
241
|
+
"./bridge/react/usePlatformAppSettings": "./src/bridge/react/usePlatformAppSettings.tsx",
|
|
242
|
+
"./bridge/react/usePlatformAppSettings.js": "./src/bridge/react/usePlatformAppSettings.tsx",
|
|
228
243
|
"./bridge/react/usePlatformBridge.tsx": "./src/bridge/react/usePlatformBridge.tsx",
|
|
229
244
|
"./bridge/react/usePlatformBridge": "./src/bridge/react/usePlatformBridge.tsx",
|
|
230
245
|
"./bridge/react/usePlatformBridge.js": "./src/bridge/react/usePlatformBridge.tsx",
|
|
@@ -237,6 +252,9 @@
|
|
|
237
252
|
"./bridge/react/usePlatformFilePreview.tsx": "./src/bridge/react/usePlatformFilePreview.tsx",
|
|
238
253
|
"./bridge/react/usePlatformFilePreview": "./src/bridge/react/usePlatformFilePreview.tsx",
|
|
239
254
|
"./bridge/react/usePlatformFilePreview.js": "./src/bridge/react/usePlatformFilePreview.tsx",
|
|
255
|
+
"./bridge/react/usePlatformJsonStore.tsx": "./src/bridge/react/usePlatformJsonStore.tsx",
|
|
256
|
+
"./bridge/react/usePlatformJsonStore": "./src/bridge/react/usePlatformJsonStore.tsx",
|
|
257
|
+
"./bridge/react/usePlatformJsonStore.js": "./src/bridge/react/usePlatformJsonStore.tsx",
|
|
240
258
|
"./bridge/react/usePlatformPreferences.tsx": "./src/bridge/react/usePlatformPreferences.tsx",
|
|
241
259
|
"./bridge/react/usePlatformPreferences": "./src/bridge/react/usePlatformPreferences.tsx",
|
|
242
260
|
"./bridge/react/usePlatformPreferences.js": "./src/bridge/react/usePlatformPreferences.tsx",
|
|
@@ -360,6 +378,9 @@
|
|
|
360
378
|
"./components/agents/agentTypes.ts": "./src/components/agents/agentTypes.ts",
|
|
361
379
|
"./components/agents/agentTypes": "./src/components/agents/agentTypes.ts",
|
|
362
380
|
"./components/agents/agentTypes.js": "./src/components/agents/agentTypes.ts",
|
|
381
|
+
"./components/agents/ContextPicker.tsx": "./src/components/agents/ContextPicker.tsx",
|
|
382
|
+
"./components/agents/ContextPicker": "./src/components/agents/ContextPicker.tsx",
|
|
383
|
+
"./components/agents/ContextPicker.js": "./src/components/agents/ContextPicker.tsx",
|
|
363
384
|
"./components/agents/formatToolCallArguments.ts": "./src/components/agents/formatToolCallArguments.ts",
|
|
364
385
|
"./components/agents/formatToolCallArguments": "./src/components/agents/formatToolCallArguments.ts",
|
|
365
386
|
"./components/agents/formatToolCallArguments.js": "./src/components/agents/formatToolCallArguments.ts",
|
|
@@ -681,6 +702,17 @@
|
|
|
681
702
|
"./components/common/desk/index.js": "./src/components/common/desk/index.ts",
|
|
682
703
|
"./components/common/desk": "./src/components/common/desk/index.ts",
|
|
683
704
|
"./components/common/desk.js": "./src/components/common/desk/index.ts",
|
|
705
|
+
"./components/common/documents/DocumentHeaderActions.tsx": "./src/components/common/documents/DocumentHeaderActions.tsx",
|
|
706
|
+
"./components/common/documents/DocumentHeaderActions": "./src/components/common/documents/DocumentHeaderActions.tsx",
|
|
707
|
+
"./components/common/documents/DocumentHeaderActions.js": "./src/components/common/documents/DocumentHeaderActions.tsx",
|
|
708
|
+
"./components/common/documents/DocumentSwitcher.tsx": "./src/components/common/documents/DocumentSwitcher.tsx",
|
|
709
|
+
"./components/common/documents/DocumentSwitcher": "./src/components/common/documents/DocumentSwitcher.tsx",
|
|
710
|
+
"./components/common/documents/DocumentSwitcher.js": "./src/components/common/documents/DocumentSwitcher.tsx",
|
|
711
|
+
"./components/common/documents/index.ts": "./src/components/common/documents/index.ts",
|
|
712
|
+
"./components/common/documents/index": "./src/components/common/documents/index.ts",
|
|
713
|
+
"./components/common/documents/index.js": "./src/components/common/documents/index.ts",
|
|
714
|
+
"./components/common/documents": "./src/components/common/documents/index.ts",
|
|
715
|
+
"./components/common/documents.js": "./src/components/common/documents/index.ts",
|
|
684
716
|
"./components/common/dropdown/ContextMenu.tsx": "./src/components/common/dropdown/ContextMenu.tsx",
|
|
685
717
|
"./components/common/dropdown/ContextMenu": "./src/components/common/dropdown/ContextMenu.tsx",
|
|
686
718
|
"./components/common/dropdown/ContextMenu.js": "./src/components/common/dropdown/ContextMenu.tsx",
|
|
@@ -1044,6 +1076,9 @@
|
|
|
1044
1076
|
"./components/print-design/index.js": "./src/components/print-design/index.ts",
|
|
1045
1077
|
"./components/print-design": "./src/components/print-design/index.ts",
|
|
1046
1078
|
"./components/print-design.js": "./src/components/print-design/index.ts",
|
|
1079
|
+
"./components/print-design/previewContent.ts": "./src/components/print-design/previewContent.ts",
|
|
1080
|
+
"./components/print-design/previewContent": "./src/components/print-design/previewContent.ts",
|
|
1081
|
+
"./components/print-design/previewContent.js": "./src/components/print-design/previewContent.ts",
|
|
1047
1082
|
"./components/print-design/PrintDesignPanel.tsx": "./src/components/print-design/PrintDesignPanel.tsx",
|
|
1048
1083
|
"./components/print-design/PrintDesignPanel": "./src/components/print-design/PrintDesignPanel.tsx",
|
|
1049
1084
|
"./components/print-design/PrintDesignPanel.js": "./src/components/print-design/PrintDesignPanel.tsx",
|
|
@@ -1055,6 +1090,24 @@
|
|
|
1055
1090
|
"./components/proofing/PagedProofDialog.tsx": "./src/components/proofing/PagedProofDialog.tsx",
|
|
1056
1091
|
"./components/proofing/PagedProofDialog": "./src/components/proofing/PagedProofDialog.tsx",
|
|
1057
1092
|
"./components/proofing/PagedProofDialog.js": "./src/components/proofing/PagedProofDialog.tsx",
|
|
1093
|
+
"./context/buildContextDocument.ts": "./src/context/buildContextDocument.ts",
|
|
1094
|
+
"./context/buildContextDocument": "./src/context/buildContextDocument.ts",
|
|
1095
|
+
"./context/buildContextDocument.js": "./src/context/buildContextDocument.ts",
|
|
1096
|
+
"./context/contextAccess.ts": "./src/context/contextAccess.ts",
|
|
1097
|
+
"./context/contextAccess": "./src/context/contextAccess.ts",
|
|
1098
|
+
"./context/contextAccess.js": "./src/context/contextAccess.ts",
|
|
1099
|
+
"./context/contextConfig.ts": "./src/context/contextConfig.ts",
|
|
1100
|
+
"./context/contextConfig": "./src/context/contextConfig.ts",
|
|
1101
|
+
"./context/contextConfig.js": "./src/context/contextConfig.ts",
|
|
1102
|
+
"./context/contextDocument.ts": "./src/context/contextDocument.ts",
|
|
1103
|
+
"./context/contextDocument": "./src/context/contextDocument.ts",
|
|
1104
|
+
"./context/contextDocument.js": "./src/context/contextDocument.ts",
|
|
1105
|
+
"./context/contextSections.ts": "./src/context/contextSections.ts",
|
|
1106
|
+
"./context/contextSections": "./src/context/contextSections.ts",
|
|
1107
|
+
"./context/contextSections.js": "./src/context/contextSections.ts",
|
|
1108
|
+
"./context/htmlToContextMarkdown.ts": "./src/context/htmlToContextMarkdown.ts",
|
|
1109
|
+
"./context/htmlToContextMarkdown": "./src/context/htmlToContextMarkdown.ts",
|
|
1110
|
+
"./context/htmlToContextMarkdown.js": "./src/context/htmlToContextMarkdown.ts",
|
|
1058
1111
|
"./editor/DocumentEditor.tsx": "./src/editor/DocumentEditor.tsx",
|
|
1059
1112
|
"./editor/DocumentEditor": "./src/editor/DocumentEditor.tsx",
|
|
1060
1113
|
"./editor/DocumentEditor.js": "./src/editor/DocumentEditor.tsx",
|
|
@@ -1181,6 +1234,7 @@
|
|
|
1181
1234
|
"lucide-react": "^0.511.0",
|
|
1182
1235
|
"mermaid": "^11.15.0",
|
|
1183
1236
|
"styled-components": "^6.1.18",
|
|
1237
|
+
"yaml": "^2.9.0",
|
|
1184
1238
|
"@puredesktop/platform-editor": "2.1.0"
|
|
1185
1239
|
},
|
|
1186
1240
|
"peerDependencies": {
|
package/src/bridge/agentTypes.ts
CHANGED
|
@@ -24,7 +24,27 @@ export interface PlatformAgentImageAttachment {
|
|
|
24
24
|
name?: string
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
/**
|
|
28
|
+
* An object's markdown context document attached to a user message —
|
|
29
|
+
* output of the context picker (`context.read`). Mirrors the shell's
|
|
30
|
+
* `AgentContextAttachment`.
|
|
31
|
+
*/
|
|
32
|
+
export interface PlatformAgentContextAttachment {
|
|
33
|
+
type: 'context'
|
|
34
|
+
/** Object kind, e.g. 'manuscript' | 'book'. */
|
|
35
|
+
kind: string
|
|
36
|
+
appSlug: string
|
|
37
|
+
objectId: string
|
|
38
|
+
title: string
|
|
39
|
+
/** Full or section markdown from the object's context document. */
|
|
40
|
+
markdown: string
|
|
41
|
+
/** Durable section id when a segmented read was attached. */
|
|
42
|
+
section?: string
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type PlatformAgentMessageAttachment =
|
|
46
|
+
| PlatformAgentImageAttachment
|
|
47
|
+
| PlatformAgentContextAttachment
|
|
28
48
|
|
|
29
49
|
export interface PlatformAgentUiToolCall {
|
|
30
50
|
id: string
|
|
@@ -25,12 +25,29 @@ export interface CollectionImagePastePayload {
|
|
|
25
25
|
mimeType: string
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
export interface CollectionImageInsertPayload {
|
|
29
|
+
relativePath: string
|
|
30
|
+
alt: string
|
|
31
|
+
bytes: Uint8Array
|
|
32
|
+
mimeType: string
|
|
33
|
+
}
|
|
34
|
+
|
|
28
35
|
export interface CollectionImagePasteHandlerOptions {
|
|
29
36
|
collectionPath?: string
|
|
30
37
|
subdir?: string
|
|
31
38
|
onError?: (message: string) => void
|
|
32
39
|
getEditor: () => Editor | null | undefined
|
|
33
40
|
writeBinary: (absolutePath: string, bytes: Uint8Array) => Promise<void>
|
|
41
|
+
/**
|
|
42
|
+
* Override how the persisted image is placed into the document. Defaults to a
|
|
43
|
+
* bare image node; callers (e.g. the manuscript editor) can supply a handler
|
|
44
|
+
* that wraps it in a captioned `<figure>` so it is numbered and
|
|
45
|
+
* cross-referenceable. Returns `false` if the editor cannot accept the node.
|
|
46
|
+
*/
|
|
47
|
+
insertImage?: (
|
|
48
|
+
editor: Editor | null | undefined,
|
|
49
|
+
image: CollectionImageInsertPayload,
|
|
50
|
+
) => boolean
|
|
34
51
|
}
|
|
35
52
|
|
|
36
53
|
export function normalizeCollectionImageMimeType(
|
|
@@ -93,6 +110,7 @@ export function createCollectionImagePasteHandler(
|
|
|
93
110
|
onError,
|
|
94
111
|
getEditor,
|
|
95
112
|
writeBinary,
|
|
113
|
+
insertImage = insertCollectionImage,
|
|
96
114
|
} = options
|
|
97
115
|
|
|
98
116
|
return async ({ name, bytes, mimeType }) => {
|
|
@@ -117,7 +135,7 @@ export function createCollectionImagePasteHandler(
|
|
|
117
135
|
const stem = stemFromImageFileName(name)
|
|
118
136
|
const editor = getEditor()
|
|
119
137
|
if (
|
|
120
|
-
!
|
|
138
|
+
!insertImage(editor, {
|
|
121
139
|
relativePath,
|
|
122
140
|
alt: stem,
|
|
123
141
|
bytes,
|
package/src/bridge/context.mjs
CHANGED
|
@@ -10,3 +10,35 @@ import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
|
|
|
10
10
|
export async function publishContext(request) {
|
|
11
11
|
return bridge.call(PLATFORM_BRIDGE_METHODS.CONTEXT_PUBLISH, [request])
|
|
12
12
|
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Resolve one object's context document — generates or refreshes the
|
|
16
|
+
* `<name>.<kind>.md` file when missing or stale. Requires `filesystem`.
|
|
17
|
+
*
|
|
18
|
+
* @param {{ path?: string, appSlug?: string, objectId?: string }} ref
|
|
19
|
+
* @returns {Promise<import('../context/contextAccess.js').PlatformContextResolveResult>}
|
|
20
|
+
*/
|
|
21
|
+
export async function resolveContextDocument(ref) {
|
|
22
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.CONTEXT_RESOLVE, [ref])
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Read one object's context markdown — the whole document or one section by
|
|
27
|
+
* durable section id. Requires `filesystem`.
|
|
28
|
+
*
|
|
29
|
+
* @param {{ path?: string, appSlug?: string, objectId?: string, section?: string }} request
|
|
30
|
+
* @returns {Promise<import('../context/contextAccess.js').PlatformContextReadResult>}
|
|
31
|
+
*/
|
|
32
|
+
export async function readContextDocument(request) {
|
|
33
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.CONTEXT_READ, [request])
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Search context-enabled objects across apps. Requires `filesystem`.
|
|
38
|
+
*
|
|
39
|
+
* @param {{ query: string, kinds?: string[], appSlug?: string, limit?: number }} request
|
|
40
|
+
* @returns {Promise<import('../context/contextAccess.js').PlatformContextSearchHit[]>}
|
|
41
|
+
*/
|
|
42
|
+
export async function searchContextObjects(request) {
|
|
43
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.CONTEXT_SEARCH, [request])
|
|
44
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/** One file inside a document. `name: null` addresses a single-file document
|
|
2
|
+
* itself; a string is a path relative to a package directory. */
|
|
3
|
+
export interface PlatformDocumentFilePayload {
|
|
4
|
+
name: string | null
|
|
5
|
+
content: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface PlatformDocumentCreateDraftRequest {
|
|
9
|
+
appSlug: string
|
|
10
|
+
suffix: string
|
|
11
|
+
kind: 'package' | 'file'
|
|
12
|
+
title?: string
|
|
13
|
+
files: PlatformDocumentFilePayload[]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface PlatformDocumentListEntry {
|
|
17
|
+
path: string
|
|
18
|
+
name: string
|
|
19
|
+
mtimeMs: number
|
|
20
|
+
isDraft: boolean
|
|
21
|
+
kind: 'package' | 'file'
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface PlatformRecentDocumentEntry {
|
|
25
|
+
path: string
|
|
26
|
+
title: string
|
|
27
|
+
touchedAt: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function createPlatformDraft(
|
|
31
|
+
request: PlatformDocumentCreateDraftRequest,
|
|
32
|
+
): Promise<{ path: string }>
|
|
33
|
+
|
|
34
|
+
export function autosavePlatformDocument(request: {
|
|
35
|
+
path: string
|
|
36
|
+
files: PlatformDocumentFilePayload[]
|
|
37
|
+
}): Promise<{ savedAt: string }>
|
|
38
|
+
|
|
39
|
+
export function promotePlatformDocument(request: {
|
|
40
|
+
path: string
|
|
41
|
+
title: string
|
|
42
|
+
targetDir?: string
|
|
43
|
+
/** The document type's real suffix (e.g. `.chart.json`) — required for
|
|
44
|
+
* compound suffixes, which cannot be recovered from the path. */
|
|
45
|
+
suffix?: string
|
|
46
|
+
appSlug?: string
|
|
47
|
+
}): Promise<{ path: string }>
|
|
48
|
+
|
|
49
|
+
export function renamePlatformDocument(request: {
|
|
50
|
+
path: string
|
|
51
|
+
title: string
|
|
52
|
+
suffix?: string
|
|
53
|
+
appSlug?: string
|
|
54
|
+
}): Promise<{ path: string }>
|
|
55
|
+
|
|
56
|
+
export function duplicatePlatformDocument(request: {
|
|
57
|
+
path: string
|
|
58
|
+
suffix?: string
|
|
59
|
+
}): Promise<{ path: string }>
|
|
60
|
+
|
|
61
|
+
export function listPlatformDocumentsByType(request: {
|
|
62
|
+
suffixes: string[]
|
|
63
|
+
}): Promise<PlatformDocumentListEntry[]>
|
|
64
|
+
|
|
65
|
+
export function listPlatformRecentDocuments(request: {
|
|
66
|
+
appSlug: string
|
|
67
|
+
limit?: number
|
|
68
|
+
}): Promise<PlatformRecentDocumentEntry[]>
|
|
69
|
+
|
|
70
|
+
export function touchPlatformRecentDocument(request: {
|
|
71
|
+
appSlug: string
|
|
72
|
+
path: string
|
|
73
|
+
title: string
|
|
74
|
+
}): Promise<void>
|
|
75
|
+
|
|
76
|
+
export function suggestPlatformDocumentLocation(): Promise<{ dir: string }>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { bridge } from './client.mjs'
|
|
2
|
+
import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
|
|
3
|
+
|
|
4
|
+
/** Unified document lifecycle bridge: drafts, autosave, filing, recents. */
|
|
5
|
+
|
|
6
|
+
export async function createPlatformDraft(request) {
|
|
7
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.DOCUMENTS_CREATE_DRAFT, [request])
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export async function autosavePlatformDocument(request) {
|
|
11
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.DOCUMENTS_AUTOSAVE, [request])
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function promotePlatformDocument(request) {
|
|
15
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.DOCUMENTS_PROMOTE, [request])
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function renamePlatformDocument(request) {
|
|
19
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.DOCUMENTS_RENAME, [request])
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function duplicatePlatformDocument(request) {
|
|
23
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.DOCUMENTS_DUPLICATE, [request])
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function listPlatformDocumentsByType(request) {
|
|
27
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.DOCUMENTS_LIST_BY_TYPE, [request])
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export async function listPlatformRecentDocuments(request) {
|
|
31
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.DOCUMENTS_RECENTS_LIST, [request])
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export async function touchPlatformRecentDocument(request) {
|
|
35
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.DOCUMENTS_RECENTS_TOUCH, [request])
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function suggestPlatformDocumentLocation() {
|
|
39
|
+
return bridge.call(PLATFORM_BRIDGE_METHODS.DOCUMENTS_SUGGEST_LOCATION, [])
|
|
40
|
+
}
|
package/src/bridge/methods.d.mts
CHANGED
|
@@ -8,6 +8,7 @@ export declare const PLATFORM_BRIDGE_METHODS: {
|
|
|
8
8
|
readonly WORKSPACE_OPEN_APP: 'workspace.openApp'
|
|
9
9
|
readonly WORKSPACE_OPEN_PALETTE: 'workspace.openPalette'
|
|
10
10
|
readonly WORKSPACE_UPDATE_CURRENT_TAB: 'workspace.updateCurrentTab'
|
|
11
|
+
readonly WORKSPACE_SET_OVERLAY_OPEN: 'workspace.setOverlayOpen'
|
|
11
12
|
readonly SCHEDULER_REGISTER: 'scheduler.register'
|
|
12
13
|
readonly SCHEDULER_UNREGISTER: 'scheduler.unregister'
|
|
13
14
|
readonly CATALOG_CONSUME_PENDING_OPEN: 'catalog.consumePendingOpen'
|
|
@@ -60,17 +61,27 @@ export declare const PLATFORM_BRIDGE_METHODS: {
|
|
|
60
61
|
readonly ASSETS_TRANSFORM: 'assets.transform'
|
|
61
62
|
readonly ASSETS_GET_CONTEXT: 'assets.getContext'
|
|
62
63
|
readonly NETWORK_FETCH: 'network.fetch'
|
|
64
|
+
readonly RESEARCH_QUERY: 'research.query'
|
|
63
65
|
readonly VISION_GENERATE_IMAGE: 'vision.generateImage'
|
|
64
66
|
readonly OAUTH_LOOPBACK_AUTHORIZE: 'oauth.loopbackAuthorize'
|
|
65
67
|
readonly SECRETS_GET: 'secrets.get'
|
|
66
68
|
readonly SECRETS_SET: 'secrets.set'
|
|
67
69
|
readonly SECRETS_DELETE: 'secrets.delete'
|
|
68
70
|
readonly SECRETS_STATUS: 'secrets.status'
|
|
71
|
+
readonly MYTOOLS_LIST: 'mytools.list'
|
|
72
|
+
readonly MYTOOLS_SAVE: 'mytools.save'
|
|
73
|
+
readonly MYTOOLS_UPDATE: 'mytools.update'
|
|
74
|
+
readonly MYTOOLS_DELETE: 'mytools.delete'
|
|
75
|
+
readonly MYTOOLS_TEST: 'mytools.test'
|
|
76
|
+
readonly MYTOOLS_RESEARCH: 'mytools.research'
|
|
69
77
|
readonly DEBUG_EMIT_EVENT: 'debug.emitEvent'
|
|
70
78
|
readonly PLUGINS_INSTALL: 'plugins.install'
|
|
71
79
|
readonly PLUGINS_EVALUATE_BUILD: 'plugins.evaluateBuild'
|
|
72
80
|
readonly PLUGINS_PREPARE_REGISTRATION: 'plugins.prepareRegistration'
|
|
73
81
|
readonly CONTEXT_PUBLISH: 'context.publish'
|
|
82
|
+
readonly CONTEXT_RESOLVE: 'context.resolve'
|
|
83
|
+
readonly CONTEXT_READ: 'context.read'
|
|
84
|
+
readonly CONTEXT_SEARCH: 'context.search'
|
|
74
85
|
readonly PEOPLE_SUGGEST: 'people.suggest'
|
|
75
86
|
readonly PEOPLE_RESEARCH: 'people.research'
|
|
76
87
|
readonly CREDENTIALS_STORAGE_STATUS: 'credentials.storageStatus'
|
|
@@ -102,6 +113,15 @@ export declare const PLATFORM_BRIDGE_METHODS: {
|
|
|
102
113
|
readonly AGENTS_LOCAL_MODELS_STATUS: 'agents.localModels.status'
|
|
103
114
|
readonly AGENTS_TOOLS_REGISTER: 'agents.tools.register'
|
|
104
115
|
readonly AGENTS_TOOLS_COMPLETE: 'agents.tools.complete'
|
|
116
|
+
readonly DOCUMENTS_CREATE_DRAFT: 'documents.createDraft'
|
|
117
|
+
readonly DOCUMENTS_AUTOSAVE: 'documents.autosave'
|
|
118
|
+
readonly DOCUMENTS_PROMOTE: 'documents.promote'
|
|
119
|
+
readonly DOCUMENTS_RENAME: 'documents.rename'
|
|
120
|
+
readonly DOCUMENTS_DUPLICATE: 'documents.duplicate'
|
|
121
|
+
readonly DOCUMENTS_LIST_BY_TYPE: 'documents.listByType'
|
|
122
|
+
readonly DOCUMENTS_RECENTS_LIST: 'documents.recents.list'
|
|
123
|
+
readonly DOCUMENTS_RECENTS_TOUCH: 'documents.recents.touch'
|
|
124
|
+
readonly DOCUMENTS_SUGGEST_LOCATION: 'documents.suggestLocation'
|
|
105
125
|
}
|
|
106
126
|
|
|
107
127
|
export declare const PLATFORM_BRIDGE_METHOD_PREFIXES: {
|
|
@@ -119,12 +139,15 @@ export declare const PLATFORM_BRIDGE_METHOD_PREFIXES: {
|
|
|
119
139
|
readonly WATCH: 'watch.'
|
|
120
140
|
readonly ASSETS: 'assets.'
|
|
121
141
|
readonly NETWORK: 'network.'
|
|
142
|
+
readonly RESEARCH: 'research.'
|
|
122
143
|
readonly VISION: 'vision.'
|
|
123
144
|
readonly OAUTH: 'oauth.'
|
|
124
145
|
readonly SECRETS: 'secrets.'
|
|
146
|
+
readonly MYTOOLS: 'mytools.'
|
|
125
147
|
readonly AGENTS: 'agents.'
|
|
126
148
|
readonly PEOPLE: 'people.'
|
|
127
149
|
readonly DEBUG: 'debug.'
|
|
150
|
+
readonly DOCUMENTS: 'documents.'
|
|
128
151
|
}
|
|
129
152
|
|
|
130
153
|
export type PlatformBridgeMethodName =
|
package/src/bridge/methods.mjs
CHANGED
|
@@ -11,6 +11,7 @@ export const PLATFORM_BRIDGE_METHODS = {
|
|
|
11
11
|
WORKSPACE_OPEN_APP: 'workspace.openApp',
|
|
12
12
|
WORKSPACE_OPEN_PALETTE: 'workspace.openPalette',
|
|
13
13
|
WORKSPACE_UPDATE_CURRENT_TAB: 'workspace.updateCurrentTab',
|
|
14
|
+
WORKSPACE_SET_OVERLAY_OPEN: 'workspace.setOverlayOpen',
|
|
14
15
|
SCHEDULER_REGISTER: 'scheduler.register',
|
|
15
16
|
SCHEDULER_UNREGISTER: 'scheduler.unregister',
|
|
16
17
|
CATALOG_CONSUME_PENDING_OPEN: 'catalog.consumePendingOpen',
|
|
@@ -75,12 +76,19 @@ export const PLATFORM_BRIDGE_METHODS = {
|
|
|
75
76
|
ASSETS_GET_CONTEXT: 'assets.getContext',
|
|
76
77
|
|
|
77
78
|
NETWORK_FETCH: 'network.fetch',
|
|
79
|
+
RESEARCH_QUERY: 'research.query',
|
|
78
80
|
VISION_GENERATE_IMAGE: 'vision.generateImage',
|
|
79
81
|
OAUTH_LOOPBACK_AUTHORIZE: 'oauth.loopbackAuthorize',
|
|
80
82
|
SECRETS_GET: 'secrets.get',
|
|
81
83
|
SECRETS_SET: 'secrets.set',
|
|
82
84
|
SECRETS_DELETE: 'secrets.delete',
|
|
83
85
|
SECRETS_STATUS: 'secrets.status',
|
|
86
|
+
MYTOOLS_LIST: 'mytools.list',
|
|
87
|
+
MYTOOLS_SAVE: 'mytools.save',
|
|
88
|
+
MYTOOLS_UPDATE: 'mytools.update',
|
|
89
|
+
MYTOOLS_DELETE: 'mytools.delete',
|
|
90
|
+
MYTOOLS_TEST: 'mytools.test',
|
|
91
|
+
MYTOOLS_RESEARCH: 'mytools.research',
|
|
84
92
|
|
|
85
93
|
DEBUG_EMIT_EVENT: 'debug.emitEvent',
|
|
86
94
|
|
|
@@ -88,6 +96,9 @@ export const PLATFORM_BRIDGE_METHODS = {
|
|
|
88
96
|
PLUGINS_EVALUATE_BUILD: 'plugins.evaluateBuild',
|
|
89
97
|
PLUGINS_PREPARE_REGISTRATION: 'plugins.prepareRegistration',
|
|
90
98
|
CONTEXT_PUBLISH: 'context.publish',
|
|
99
|
+
CONTEXT_RESOLVE: 'context.resolve',
|
|
100
|
+
CONTEXT_READ: 'context.read',
|
|
101
|
+
CONTEXT_SEARCH: 'context.search',
|
|
91
102
|
PEOPLE_SUGGEST: 'people.suggest',
|
|
92
103
|
PEOPLE_RESEARCH: 'people.research',
|
|
93
104
|
|
|
@@ -124,6 +135,15 @@ export const PLATFORM_BRIDGE_METHODS = {
|
|
|
124
135
|
AGENTS_LOCAL_MODELS_STATUS: 'agents.localModels.status',
|
|
125
136
|
AGENTS_TOOLS_REGISTER: 'agents.tools.register',
|
|
126
137
|
AGENTS_TOOLS_COMPLETE: 'agents.tools.complete',
|
|
138
|
+
DOCUMENTS_CREATE_DRAFT: 'documents.createDraft',
|
|
139
|
+
DOCUMENTS_AUTOSAVE: 'documents.autosave',
|
|
140
|
+
DOCUMENTS_PROMOTE: 'documents.promote',
|
|
141
|
+
DOCUMENTS_RENAME: 'documents.rename',
|
|
142
|
+
DOCUMENTS_DUPLICATE: 'documents.duplicate',
|
|
143
|
+
DOCUMENTS_LIST_BY_TYPE: 'documents.listByType',
|
|
144
|
+
DOCUMENTS_RECENTS_LIST: 'documents.recents.list',
|
|
145
|
+
DOCUMENTS_RECENTS_TOUCH: 'documents.recents.touch',
|
|
146
|
+
DOCUMENTS_SUGGEST_LOCATION: 'documents.suggestLocation',
|
|
127
147
|
}
|
|
128
148
|
|
|
129
149
|
export const PLATFORM_BRIDGE_METHOD_PREFIXES = {
|
|
@@ -141,10 +161,13 @@ export const PLATFORM_BRIDGE_METHOD_PREFIXES = {
|
|
|
141
161
|
WATCH: 'watch.',
|
|
142
162
|
ASSETS: 'assets.',
|
|
143
163
|
NETWORK: 'network.',
|
|
164
|
+
RESEARCH: 'research.',
|
|
144
165
|
VISION: 'vision.',
|
|
145
166
|
OAUTH: 'oauth.',
|
|
146
167
|
SECRETS: 'secrets.',
|
|
168
|
+
MYTOOLS: 'mytools.',
|
|
147
169
|
AGENTS: 'agents.',
|
|
148
170
|
PEOPLE: 'people.',
|
|
149
171
|
DEBUG: 'debug.',
|
|
172
|
+
DOCUMENTS: 'documents.',
|
|
150
173
|
}
|
|
@@ -16,6 +16,46 @@ body {
|
|
|
16
16
|
max-width: 30rem;
|
|
17
17
|
string-set: doctitle content(text);
|
|
18
18
|
}
|
|
19
|
+
/* Metadata eyebrow above the title — driven purely by theme tokens. */
|
|
20
|
+
.doc-title::before {
|
|
21
|
+
content: var(--eyebrow-text, '');
|
|
22
|
+
display: var(--eyebrow-display, none);
|
|
23
|
+
font: 600 8pt / 1.3 var(--sans);
|
|
24
|
+
letter-spacing: 0.14em;
|
|
25
|
+
text-transform: uppercase;
|
|
26
|
+
color: var(--accent);
|
|
27
|
+
margin: 0 0 calc(var(--rhythm) * 0.6);
|
|
28
|
+
}
|
|
29
|
+
/* Drop cap on the opening paragraph — inert unless the theme enables it.
|
|
30
|
+
THREE separate rules on purpose: Paged.js crashes on comma-lists of
|
|
31
|
+
::first-letter selectors ("item doesn't belong to list"). */
|
|
32
|
+
.doc-title + p::first-letter {
|
|
33
|
+
float: var(--drop-cap-float, none);
|
|
34
|
+
font-family: var(--drop-cap-font, inherit);
|
|
35
|
+
font-size: var(--drop-cap-size, 1em);
|
|
36
|
+
line-height: var(--drop-cap-lh, inherit);
|
|
37
|
+
font-weight: var(--drop-cap-weight, inherit);
|
|
38
|
+
padding: var(--drop-cap-pad, 0);
|
|
39
|
+
color: var(--drop-cap-ink, inherit);
|
|
40
|
+
}
|
|
41
|
+
.doc-title + section > p:first-child::first-letter {
|
|
42
|
+
float: var(--drop-cap-float, none);
|
|
43
|
+
font-family: var(--drop-cap-font, inherit);
|
|
44
|
+
font-size: var(--drop-cap-size, 1em);
|
|
45
|
+
line-height: var(--drop-cap-lh, inherit);
|
|
46
|
+
font-weight: var(--drop-cap-weight, inherit);
|
|
47
|
+
padding: var(--drop-cap-pad, 0);
|
|
48
|
+
color: var(--drop-cap-ink, inherit);
|
|
49
|
+
}
|
|
50
|
+
section:first-of-type > p:first-child::first-letter {
|
|
51
|
+
float: var(--drop-cap-float, none);
|
|
52
|
+
font-family: var(--drop-cap-font, inherit);
|
|
53
|
+
font-size: var(--drop-cap-size, 1em);
|
|
54
|
+
line-height: var(--drop-cap-lh, inherit);
|
|
55
|
+
font-weight: var(--drop-cap-weight, inherit);
|
|
56
|
+
padding: var(--drop-cap-pad, 0);
|
|
57
|
+
color: var(--drop-cap-ink, inherit);
|
|
58
|
+
}
|
|
19
59
|
.authors {
|
|
20
60
|
font: 500 11.5pt/1.4 var(--sans);
|
|
21
61
|
margin: 0 0 0.4rem;
|
|
@@ -83,6 +123,10 @@ h2 {
|
|
|
83
123
|
line-height: 1.15;
|
|
84
124
|
margin: calc(var(--rhythm) * 1.5) 0 calc(var(--rhythm) * 0.4);
|
|
85
125
|
string-set: sectitle content(text);
|
|
126
|
+
/* Optional accent rule beneath section headings (theme token). */
|
|
127
|
+
border-bottom: var(--heading-rule-width, 0) solid var(--accent);
|
|
128
|
+
padding-bottom: var(--heading-rule-pad, 0);
|
|
129
|
+
max-width: var(--measure);
|
|
86
130
|
}
|
|
87
131
|
section:not([data-type='abstract']):not([data-type='frontmatter']):not(
|
|
88
132
|
[data-type='backmatter']
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { buildPrintHtmlDocument } from '../printDocument.js'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
injectCoverSection,
|
|
4
|
+
injectGeneratedToc,
|
|
5
|
+
normalizePureRenderHtml,
|
|
6
|
+
wrapLooseBodyRun,
|
|
7
|
+
} from './normalize.js'
|
|
3
8
|
import { buildPureRenderStylesheet } from './styles.js'
|
|
4
9
|
import type { PureRenderRequest } from './types.js'
|
|
5
10
|
|
|
@@ -22,6 +27,28 @@ export function buildPureRenderHtmlDocument(options: {
|
|
|
22
27
|
)
|
|
23
28
|
}
|
|
24
29
|
|
|
30
|
+
// Theme-driven structure: cover first (title block onto its own named
|
|
31
|
+
// page), then a generated table of contents from the normalized
|
|
32
|
+
// article's sections (ids are assigned during normalization).
|
|
33
|
+
const setting = options.request.theme?.setting
|
|
34
|
+
let bodyHtml = normalized.html
|
|
35
|
+
if (setting?.coverPage) {
|
|
36
|
+
bodyHtml = injectCoverSection(bodyHtml, {
|
|
37
|
+
author: setting.coverAuthor,
|
|
38
|
+
date: setting.coverDate,
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
// Contents implies a cover: without one, a toc page before the title
|
|
42
|
+
// reads as clutter rather than structure.
|
|
43
|
+
if (setting?.coverPage && setting?.toc) {
|
|
44
|
+
bodyHtml = injectGeneratedToc(bodyHtml)
|
|
45
|
+
}
|
|
46
|
+
if (options.request.theme?.page?.columns === 2) {
|
|
47
|
+
// Columns attach to body sections; unsectioned (writer) articles need
|
|
48
|
+
// their loose body run wrapped so there is a section to columnize.
|
|
49
|
+
bodyHtml = wrapLooseBodyRun(bodyHtml)
|
|
50
|
+
}
|
|
51
|
+
|
|
25
52
|
return buildPrintHtmlDocument({
|
|
26
53
|
rootPath: options.rootPath,
|
|
27
54
|
title: options.title ?? normalized.title,
|
|
@@ -30,6 +57,6 @@ export function buildPureRenderHtmlDocument(options: {
|
|
|
30
57
|
theme: options.request.theme,
|
|
31
58
|
}),
|
|
32
59
|
bodyClass: `pure-render pure-render-${options.request.profile}`,
|
|
33
|
-
bodyHtml
|
|
60
|
+
bodyHtml,
|
|
34
61
|
})
|
|
35
62
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { compilePrintTheme } from './compiler.js'
|
|
2
|
+
export { sanitizeBodyForPureRenderExport } from './sanitizeExportBody.js'
|
|
2
3
|
export {
|
|
3
4
|
buildBookPureRenderRequest,
|
|
4
5
|
buildWriterPureRenderRequest,
|
|
@@ -46,7 +47,9 @@ export {
|
|
|
46
47
|
} from './samples.js'
|
|
47
48
|
export {
|
|
48
49
|
inspectPureRenderVisualLayout,
|
|
50
|
+
relevantPagedSnapshotPages,
|
|
49
51
|
visualIssuesForMetrics,
|
|
52
|
+
type PureRenderSnapshotRole,
|
|
50
53
|
type PureRenderVisualCandidate,
|
|
51
54
|
type PureRenderVisualDecision,
|
|
52
55
|
type PureRenderVisualInspection,
|