@aryacode/dsh-engineering 0.4.7 → 0.4.21
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/CHANGELOG.md +202 -0
- package/README.md +40 -26
- package/cordis.patch.yml +7 -6
- package/entries/config.js +62 -0
- package/entries/ftview.js +5 -4
- package/entries/l5x.js +47 -15
- package/entries/mwi.js +26 -6
- package/entries/optix.js +105 -0
- package/lib/client.js +335 -6
- package/package.json +11 -10
- package/vendor/ftview/SKILL.md +17 -0
- package/vendor/l5x/SKILL.md +17 -0
- package/vendor/l5x/studio-bridge/NuGet.Config +1 -1
- package/vendor/mwi/README.md +41 -18
- package/vendor/mwi/SKILL.md +39 -20
- package/vendor/mwi/bridge/mw_bridge.ps1 +2768 -2763
- package/vendor/mwi/bridge/sdk-interop-importer.cs +30 -30
- package/vendor/mwi/bridge/sdk-variable-reader.cs +22 -22
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/__init__.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/errors.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/staging.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/build.py +339 -339
- package/vendor/mwi/code/engine/motionworks_iec_mcp/cfb.py +765 -765
- package/vendor/mwi/code/engine/motionworks_iec_mcp/declarations.py +399 -399
- package/vendor/mwi/code/engine/motionworks_iec_mcp/ide.py +313 -313
- package/vendor/mwi/code/engine/motionworks_iec_mcp/manuals.py +520 -520
- package/vendor/mwi/code/engine/motionworks_iec_mcp/mwt_bind.py +133 -133
- package/vendor/mwi/code/engine/motionworks_iec_mcp/reference_data/catalog.json +672 -672
- package/vendor/mwi/code/engine/motionworks_iec_mcp/reference_data/patterns.json +86 -86
- package/vendor/mwi/code/engine/motionworks_iec_mcp/restore.py +208 -208
- package/vendor/mwi/code/engine/motionworks_iec_mcp/staging.py +134 -130
- package/vendor/mwi/code/engine/motionworks_iec_mcp/stlint.py +673 -673
- package/vendor/mwi/code/engine/motionworks_iec_mcp/tree_writer.py +790 -790
- package/vendor/mwi/code/engine/motionworks_iec_mcp/writer.py +642 -642
- package/vendor/mwi/lib/core/code-engine.d.ts +13 -0
- package/vendor/mwi/lib/core/code-engine.js +18 -1
- package/vendor/mwi/lib/edit.d.ts +1 -1
- package/vendor/mwi/lib/edit.js +1 -1
- package/vendor/mwi/lib/read/service.js +8 -1
- package/vendor/mwi/lib/session/backup.d.ts +72 -0
- package/vendor/mwi/lib/session/backup.js +257 -0
- package/vendor/mwi/lib/session/project.d.ts +4 -1
- package/vendor/mwi/lib/session/project.js +13 -2
- package/vendor/mwi/lib/session/service.d.ts +13 -6
- package/vendor/mwi/lib/session/service.js +127 -36
- package/vendor/mwi/lib/session/workspace.d.ts +10 -0
- package/vendor/mwi/lib/session/workspace.js +53 -3
- package/vendor/mwi/lib/skill.d.ts +2 -2
- package/vendor/mwi/lib/skill.js +2 -2
- package/vendor/mwi/lib/tools/edit.d.ts +3 -3
- package/vendor/mwi/lib/tools/edit.js +14 -15
- package/vendor/mwi/lib/tools/read.js +1 -1
- package/vendor/mwi/lib/tools/session.js +13 -9
- package/vendor/optix/templates/arya-optix-ipc/project/AryaNewHMIProject_IPC.optix +81 -81
- package/vendor/optix/templates/arya-optix-ipc/project/AryaNewHMIProject_IPC.optix.design +38 -38
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/Alarms/Alarms.yaml +3 -3
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/AryaNewHMIProject_IPC.yaml +67 -67
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/CommDrivers/CommDrivers.yaml +2 -2
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/Converters/Converters.yaml +2 -2
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/DataStores/DataStores.yaml +2 -2
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/Loggers/Loggers.yaml +2 -2
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/MQTT/MQTT.yaml +2 -2
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/Model/Model.yaml +2 -2
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/NetLogic/NetLogic.yaml +26 -26
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/OPC-UA/OPC-UA.yaml +2 -2
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/Recipes/Recipes.yaml +2 -2
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/Reports/Reports.yaml +2 -2
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/Retentivity/Retentivity.yaml +57 -57
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/Security/Groups/Groups.yaml +3 -3
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/Security/Roles/Roles.yaml +3 -3
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/Security/Security.yaml +7 -7
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/Security/Users/Users.yaml +3 -3
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/System/System.yaml +2 -2
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/Translations/Translations.yaml +16 -16
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/UI/Keyboards/Keyboards.yaml +2 -2
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/UI/Screens/Screens.yaml +2 -2
- package/vendor/optix/templates/arya-optix-ipc/project/Nodes/UI/UI.yaml +250 -250
- package/vendor/optix/templates/arya-optix-ipc/project/ProjectFiles/NetSolution/.vscode/launch.json +18 -18
- package/vendor/optix/templates/arya-optix-ipc/project/ProjectFiles/NetSolution/AryaNewHMIProject_IPC.code-workspace +9 -9
- package/vendor/optix/templates/arya-optix-ipc/project/ProjectFiles/NetSolution/AryaNewHMIProject_IPC.csproj +19 -19
- package/vendor/optix/templates/arya-optix-ipc/project/ProjectFiles/NetSolution/AryaNewHMIProject_IPC.references +172 -172
- package/vendor/optix/templates/arya-optix-ipc/project/ProjectFiles/NetSolution/AryaNewHMIProject_IPC.sln +21 -21
- package/vendor/optix/templates/arya-optix-ipc/project/ProjectFiles/NetSolution/Private/TypeConstants.cs +20 -20
- package/vendor/optix/templates/arya-optix-ipc/project/ProjectFiles/NetSolution/Private/UITypeDefinitions.cs +11 -11
- package/vendor/optix/templates/arya-optix-ipc/project/ProjectFiles/NetSolution/StudioMCPBridge.cs +4340 -4340
- package/vendor/optix/templates/arya-optix-ipc/project/ProjectFiles/UserDefinedModule.xml +26 -26
- package/vendor/optix/templates/arya-optix-panel/project/AryaNewHMIProject_OptixPanel.optix +97 -97
- package/vendor/optix/templates/arya-optix-panel/project/AryaNewHMIProject_OptixPanel.optix.design +38 -38
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/Alarms/Alarms.yaml +3 -3
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/AryaNewHMIProject_OptixPanel.yaml +67 -67
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/CommDrivers/CommDrivers.yaml +2 -2
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/Converters/Converters.yaml +2 -2
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/DataStores/DataStores.yaml +2 -2
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/Loggers/Loggers.yaml +2 -2
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/MQTT/MQTT.yaml +2 -2
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/Model/Model.yaml +2 -2
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/NetLogic/NetLogic.yaml +26 -26
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/OPC-UA/OPC-UA.yaml +2 -2
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/Recipes/Recipes.yaml +2 -2
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/Reports/Reports.yaml +2 -2
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/Retentivity/Retentivity.yaml +57 -57
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/Security/Groups/Groups.yaml +3 -3
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/Security/Roles/Roles.yaml +3 -3
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/Security/Security.yaml +7 -7
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/Security/Users/Users.yaml +3 -3
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/System/System.yaml +444 -444
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/Translations/Translations.yaml +81 -81
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/UI/Keyboards/Keyboards.yaml +2 -2
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/UI/Screens/Screens.yaml +2 -2
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/UI/SettingsWidgets/DeviceSettingsWidget/DeviceSettingsWidget.yaml +163 -163
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/UI/SettingsWidgets/DeviceSettingsWidget/DeviceSettingsWidgetComponents/DeviceSettingsWidgetComponents.yaml +1663 -1663
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/UI/SettingsWidgets/FactoryTalkRemoteAccessWidget/FTRemoteAccessWidgetComponents/FTRemoteAccessWidgetComponents.yaml +2471 -2471
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/UI/SettingsWidgets/FactoryTalkRemoteAccessWidget/FactoryTalkRemoteAccessWidget.yaml +218 -218
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/UI/SettingsWidgets/NetworkSettingsWidget/NetworkSettingsWidget.yaml +524 -524
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/UI/SettingsWidgets/NetworkSettingsWidget/NetworkSettingsWidgetComponents/NetworkSettingsWidgetComponents.yaml +690 -690
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/UI/SettingsWidgets/SettingsWidgets.yaml +1265 -1265
- package/vendor/optix/templates/arya-optix-panel/project/Nodes/UI/UI.yaml +252 -252
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/.vscode/launch.json +18 -18
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/ApplicationNameLogic.cs +19 -19
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/AryaNewHMIProject_OptixPanel.code-workspace +9 -9
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/AryaNewHMIProject_OptixPanel.csproj +19 -19
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/AryaNewHMIProject_OptixPanel.references +172 -172
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/AryaNewHMIProject_OptixPanel.sln +21 -21
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/ConnectionSwitchLogic.cs +74 -74
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/DateAndTimeWidgetLogic.cs +420 -420
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/DeviceSettingsWidgetLogic.cs +34 -34
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/FTOptixStudioVersionLogic.cs +47 -47
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/FTRemoteAccessWidgetSetupLogic.cs +153 -153
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/IncomingConnectionApprovalLogic.cs +118 -118
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/IncomingConnectionReceiverLogic.cs +166 -166
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/NetworkConfiguratorEditModelsLogic.cs +56 -56
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/NetworkInterfaceLogic.cs +138 -138
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/NetworkInterfacesEditModelReaderLogic.cs +87 -87
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/NetworkInterfacesEditModelToSystemWriterLogic.cs +139 -139
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/NetworkSettingsLogic.cs +168 -168
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/Private/FTRemoteAccessWidgetDataObject.cs +106 -106
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/Private/TypeConstants.cs +37 -37
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/Private/UITypeDefinitions.cs +91 -91
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/RequestAssistanceSwitchLogic.cs +93 -93
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/StudioMCPBridge.cs +4340 -4340
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/NetSolution/SystemToNetworkInterfacesEditModelWriterLogic.cs +77 -77
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/UserDefinedModule.xml +111 -111
- package/vendor/optix/templates/arya-optix-panel/project/ProjectFiles/WarningIcon.svg +4 -4
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/block_interfaces.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/cfb.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/datatypes.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/declarations.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/graphical_listing.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/grid.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/knowledge.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/mwt_bind.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/navigation.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/program_checks.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/project.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/structure.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/task_bindings.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/tasks.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/tree.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/validation.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/variable_edit.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/variables.cpython-312.pyc +0 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/workflow.cpython-312.pyc +0 -0
package/entries/optix.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The FactoryTalk Optix product row.
|
|
3
|
+
*
|
|
4
|
+
* The Optix engine ships prebuilt. This entry owns the row's configuration so
|
|
5
|
+
* the Plugins page can render it, resolves the volatile references the settings
|
|
6
|
+
* page writes, and hands the prebuilt plugin a plain options object.
|
|
7
|
+
*
|
|
8
|
+
* Authoring ships on by default. The prebuilt plugin registers the tools, and
|
|
9
|
+
* each capability can be switched off from the row's config form.
|
|
10
|
+
*/
|
|
11
|
+
import z from '@deepseek-ai/schemastery'
|
|
12
|
+
import { dirname, join } from 'node:path'
|
|
13
|
+
import * as optix from '../vendor/optix/lib/index.js'
|
|
14
|
+
import { flag, list, text } from './config.js'
|
|
15
|
+
|
|
16
|
+
export const name = 'engineering-optix'
|
|
17
|
+
export const inject = ['tools']
|
|
18
|
+
|
|
19
|
+
export const Config = z.object({
|
|
20
|
+
bridgeUrls: z.array(z.string()).default(['http://127.0.0.1:8768']).volatile().description(
|
|
21
|
+
'Loopback origins of the Studio bridge. One per entry; the bridge runs inside FactoryTalk Optix Studio.',
|
|
22
|
+
),
|
|
23
|
+
bridgeToken: z.string().default('').volatile().description(
|
|
24
|
+
'Bearer token configured on the Studio bridge, if it requires one.',
|
|
25
|
+
),
|
|
26
|
+
allowWrites: z.boolean().default(true).volatile().description(
|
|
27
|
+
'Live authoring through optix_edit and optix_action. Dry-run validation works without it.',
|
|
28
|
+
),
|
|
29
|
+
allowDestructive: z.boolean().default(true).volatile().description(
|
|
30
|
+
'Delete, move, reorder, retype, replace and convert operations.',
|
|
31
|
+
),
|
|
32
|
+
allowInvoke: z.boolean().default(true).volatile().description(
|
|
33
|
+
'Invoke exported methods on a session-safe bridge build.',
|
|
34
|
+
),
|
|
35
|
+
preview: z.boolean().default(true).volatile().description(
|
|
36
|
+
'Register the direct-CDP preview and screenshot tools. Needs the emulator browser open.',
|
|
37
|
+
),
|
|
38
|
+
cdpUrl: z.string().default('http://127.0.0.1:9223').volatile().description(
|
|
39
|
+
'Chromium DevTools endpoint used only when preview is on.',
|
|
40
|
+
),
|
|
41
|
+
previewUrl: z.string().default('http://127.0.0.1:8081/').volatile().description(
|
|
42
|
+
'Already-open emulator tab, matched by exact origin, path and query.',
|
|
43
|
+
),
|
|
44
|
+
allowPreviewInput: z.boolean().default(true).volatile().description(
|
|
45
|
+
'Pointer and keyboard input into the emulator preview. Input can change runtime values.',
|
|
46
|
+
),
|
|
47
|
+
ocrExecutable: z.string().default('').volatile().description(
|
|
48
|
+
'Full path to tesseract.exe for optix_ocr. Leave empty to keep OCR unregistered.',
|
|
49
|
+
),
|
|
50
|
+
ocrLanguage: z.string().default('eng').volatile().description(
|
|
51
|
+
'Tesseract language code or + separated list, for example eng or eng+deu.',
|
|
52
|
+
),
|
|
53
|
+
ocrTessdataDirectory: z.string().default('').volatile().description(
|
|
54
|
+
'Folder holding the .traineddata files. Empty derives tessdata beside tesseract.exe.',
|
|
55
|
+
),
|
|
56
|
+
requestTimeoutMs: z.natural().min(1).max(2147483647).default(20000),
|
|
57
|
+
maxResponseBytes: z.natural().min(1).default(2000000),
|
|
58
|
+
maxBatchOps: z.natural().min(1).default(40),
|
|
59
|
+
maxMapNodes: z.natural().min(1).default(800),
|
|
60
|
+
maxMapDepth: z.natural().min(1).default(8),
|
|
61
|
+
maxPreviewPixels: z.natural().min(1).default(8000000),
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Mount the Optix surface with resolved, plain options.
|
|
66
|
+
* @param ctx - plugin context.
|
|
67
|
+
* @param config - the Studio bridge, authoring gates and preview settings.
|
|
68
|
+
*/
|
|
69
|
+
export function apply(ctx, config = {}) {
|
|
70
|
+
const options = () => {
|
|
71
|
+
const ocrExecutable = text(config.ocrExecutable)
|
|
72
|
+
return {
|
|
73
|
+
bridgeUrls: list(config.bridgeUrls),
|
|
74
|
+
bridgeToken: text(config.bridgeToken),
|
|
75
|
+
allowWrites: flag(config.allowWrites),
|
|
76
|
+
allowDestructive: flag(config.allowDestructive),
|
|
77
|
+
allowInvoke: flag(config.allowInvoke),
|
|
78
|
+
preview: flag(config.preview),
|
|
79
|
+
cdpUrl: text(config.cdpUrl) || 'http://127.0.0.1:9223',
|
|
80
|
+
previewUrl: text(config.previewUrl) || 'http://127.0.0.1:8081/',
|
|
81
|
+
allowPreviewInput: flag(config.allowPreviewInput),
|
|
82
|
+
ocr: ocrExecutable === '' ? null : {
|
|
83
|
+
executable: ocrExecutable,
|
|
84
|
+
language: text(config.ocrLanguage, 'eng'),
|
|
85
|
+
tessdataDirectory: text(config.ocrTessdataDirectory) || join(dirname(ocrExecutable), 'tessdata'),
|
|
86
|
+
},
|
|
87
|
+
requestTimeoutMs: config.requestTimeoutMs ?? 20000,
|
|
88
|
+
maxResponseBytes: config.maxResponseBytes ?? 2000000,
|
|
89
|
+
maxBatchOps: config.maxBatchOps ?? 40,
|
|
90
|
+
maxMapNodes: config.maxMapNodes ?? 800,
|
|
91
|
+
maxMapDepth: config.maxMapDepth ?? 8,
|
|
92
|
+
maxPreviewPixels: config.maxPreviewPixels ?? 8000000,
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
let mounted
|
|
96
|
+
// Volatile-only config changes are committed into the live references and
|
|
97
|
+
// emit `loader/volatile-update` instead of re-running apply(). The prebuilt
|
|
98
|
+
// plugin reads its options once, so remount it to pick up a switch change.
|
|
99
|
+
const sync = () => {
|
|
100
|
+
if (mounted !== undefined) void mounted.dispose()
|
|
101
|
+
mounted = ctx.plugin(optix, options())
|
|
102
|
+
}
|
|
103
|
+
sync()
|
|
104
|
+
ctx.on('loader/volatile-update', sync)
|
|
105
|
+
}
|
package/lib/client.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The engineering bundle's one browser half: the ladder viewer
|
|
3
|
-
* FactoryTalk View ME display preview
|
|
2
|
+
* The engineering bundle's one browser half: the ladder viewer, the
|
|
3
|
+
* FactoryTalk View ME display preview and the product-row settings pages inside
|
|
4
|
+
* a single module registration.
|
|
4
5
|
*
|
|
5
6
|
* Generated by scripts/build-client.mjs from the committed face bundles
|
|
6
|
-
* (packages/viewer/lib/client.js, packages/ftview-viewer/lib/client.js).
|
|
7
|
+
* (packages/viewer/lib/client.js, packages/ftview-viewer/lib/client.js, scripts/faces/settings.js).
|
|
7
8
|
* Do not edit: change a face in its own package and rebuild.
|
|
8
9
|
*
|
|
9
10
|
* The package name is the registration id because the shell keys a client
|
|
@@ -3425,23 +3426,351 @@ window.__ModuleLoader__.load({
|
|
|
3425
3426
|
apply,
|
|
3426
3427
|
}
|
|
3427
3428
|
|
|
3429
|
+
})()
|
|
3430
|
+
const settings = (() => {
|
|
3431
|
+
|
|
3432
|
+
const React = require('react')
|
|
3433
|
+
const { Button, Checkbox } = require('@deepseek-ai/dsh-client-ui-primitives')
|
|
3434
|
+
|
|
3435
|
+
const intro = {
|
|
3436
|
+
margin: 0,
|
|
3437
|
+
color: 'var(--dsw-alias-text-secondary, #6b7280)',
|
|
3438
|
+
fontSize: '13px',
|
|
3439
|
+
lineHeight: '1.6',
|
|
3440
|
+
}
|
|
3441
|
+
const hint = {
|
|
3442
|
+
color: 'var(--dsw-alias-text-secondary, #6b7280)',
|
|
3443
|
+
fontSize: '12px',
|
|
3444
|
+
lineHeight: '1.5',
|
|
3445
|
+
}
|
|
3446
|
+
|
|
3447
|
+
/**
|
|
3448
|
+
* Render one row's boolean switches, staged until Save.
|
|
3449
|
+
*
|
|
3450
|
+
* The Plugins page snapshots the form once when it opens the row page and
|
|
3451
|
+
* does not subscribe to it, so a form that is still loading at that moment
|
|
3452
|
+
* would stay "Loading configuration…" forever. Read the live controller
|
|
3453
|
+
* from the client `configForms` service instead: its `get` starts the one
|
|
3454
|
+
* describe fetch, and subscribing makes the switches appear when it settles.
|
|
3455
|
+
*
|
|
3456
|
+
* @param props - the slot owner's `view`, plus this entry's `spec` and the
|
|
3457
|
+
* client `configForms` service.
|
|
3458
|
+
* @returns the row's configuration page, its summary, or a status line.
|
|
3459
|
+
*/
|
|
3460
|
+
function RowConfig(props) {
|
|
3461
|
+
const { form, spec, view } = props
|
|
3462
|
+
const [draft, setDraft] = React.useState(null)
|
|
3463
|
+
const [saving, setSaving] = React.useState(false)
|
|
3464
|
+
const [notice, setNotice] = React.useState('')
|
|
3465
|
+
|
|
3466
|
+
// Resolve the service lazily: it is provided by the Settings page's own
|
|
3467
|
+
// client half, which may load after this bundle's face.
|
|
3468
|
+
const configForms = typeof props.configForms === 'function' ? props.configForms() : props.configForms
|
|
3469
|
+
const live = configForms === undefined ? undefined : configForms.get(spec.id)
|
|
3470
|
+
const subscribe = React.useCallback(
|
|
3471
|
+
listener => (live === undefined ? () => {} : live.subscribe(listener)),
|
|
3472
|
+
[live],
|
|
3473
|
+
)
|
|
3474
|
+
const snapshot = React.useCallback(
|
|
3475
|
+
() => (live === undefined ? form?.state : live.getSnapshot()),
|
|
3476
|
+
[live, form],
|
|
3477
|
+
)
|
|
3478
|
+
const state = React.useSyncExternalStore(subscribe, snapshot)
|
|
3479
|
+
const value = state === undefined ? undefined : state.value
|
|
3480
|
+
|
|
3481
|
+
if (view === 'summary') return React.createElement('span', null, spec.summary)
|
|
3482
|
+
if (state === undefined) {
|
|
3483
|
+
return React.createElement('p', { style: intro }, 'This row does not expose its configuration to the Plugins page.')
|
|
3484
|
+
}
|
|
3485
|
+
if (value === undefined) {
|
|
3486
|
+
return React.createElement('p', { style: intro },
|
|
3487
|
+
state.status === 'unavailable'
|
|
3488
|
+
? 'This row has no configuration to change.'
|
|
3489
|
+
: 'Loading configuration…')
|
|
3490
|
+
}
|
|
3491
|
+
|
|
3492
|
+
const current = draft === null ? value : draft
|
|
3493
|
+
const isText = field => field.type === 'text'
|
|
3494
|
+
const isList = field => field.type === 'list'
|
|
3495
|
+
const listText = input => (Array.isArray(input) ? input.join(', ') : String(input ?? ''))
|
|
3496
|
+
const splitList = input => String(input ?? '').split(',').map(item => item.trim()).filter(Boolean)
|
|
3497
|
+
const same = (field, left, right) => (isText(field) || isList(field)
|
|
3498
|
+
? listText(left) === listText(right)
|
|
3499
|
+
: Boolean(left) === Boolean(right))
|
|
3500
|
+
const dirty = spec.fields.some(field => !same(field, current[field.key], value[field.key]))
|
|
3501
|
+
const writable = state.writable === true
|
|
3502
|
+
const setField = (key, next) => {
|
|
3503
|
+
setDraft({ ...current, [key]: next })
|
|
3504
|
+
setNotice('')
|
|
3505
|
+
}
|
|
3506
|
+
const save = async () => {
|
|
3507
|
+
if (saving || !dirty) return
|
|
3508
|
+
setSaving(true)
|
|
3509
|
+
setNotice('')
|
|
3510
|
+
try {
|
|
3511
|
+
const ops = spec.fields.map(field => ({
|
|
3512
|
+
op: 'set',
|
|
3513
|
+
path: [field.key],
|
|
3514
|
+
value: isText(field) ? String(current[field.key] ?? '') : isList(field) ? (Array.isArray(current[field.key]) ? current[field.key] : splitList(current[field.key])) : Boolean(current[field.key]),
|
|
3515
|
+
}))
|
|
3516
|
+
const owner = live === undefined ? form : live
|
|
3517
|
+
const accepted = await owner.mutate(ops, state.revision)
|
|
3518
|
+
if (accepted) {
|
|
3519
|
+
setDraft(null)
|
|
3520
|
+
setNotice('Saved.')
|
|
3521
|
+
} else {
|
|
3522
|
+
setNotice('The Host refused the change.')
|
|
3523
|
+
}
|
|
3524
|
+
} catch (error) {
|
|
3525
|
+
setNotice(error instanceof Error ? error.message : String(error))
|
|
3526
|
+
}
|
|
3527
|
+
setSaving(false)
|
|
3528
|
+
}
|
|
3529
|
+
|
|
3530
|
+
return React.createElement('div', { style: { display: 'grid', gap: '18px' } },
|
|
3531
|
+
React.createElement('p', { style: intro }, spec.intro),
|
|
3532
|
+
React.createElement('div', { style: { display: 'grid', gap: '14px' } },
|
|
3533
|
+
spec.fields.map(field => React.createElement('div', {
|
|
3534
|
+
key: field.key,
|
|
3535
|
+
style: { display: 'grid', gap: '3px' },
|
|
3536
|
+
},
|
|
3537
|
+
isText(field) || isList(field)
|
|
3538
|
+
? React.createElement('label', { style: { display: 'grid', gap: '5px' } },
|
|
3539
|
+
React.createElement('span', { style: { fontSize: '13px', fontWeight: 600 } }, field.label),
|
|
3540
|
+
React.createElement('input', {
|
|
3541
|
+
type: 'text',
|
|
3542
|
+
value: listText(current[field.key]),
|
|
3543
|
+
disabled: !writable || saving,
|
|
3544
|
+
onChange: event => { setField(field.key, event.target.value) },
|
|
3545
|
+
placeholder: field.placeholder ?? '',
|
|
3546
|
+
style: {
|
|
3547
|
+
padding: '7px 10px',
|
|
3548
|
+
borderRadius: '8px',
|
|
3549
|
+
border: '1px solid var(--dsw-alias-border, #d4d4d8)',
|
|
3550
|
+
background: 'transparent',
|
|
3551
|
+
color: 'inherit',
|
|
3552
|
+
fontSize: '13px',
|
|
3553
|
+
fontFamily: 'inherit',
|
|
3554
|
+
},
|
|
3555
|
+
}))
|
|
3556
|
+
: React.createElement(Checkbox, {
|
|
3557
|
+
checked: Boolean(current[field.key]),
|
|
3558
|
+
onChange: next => { setField(field.key, next) },
|
|
3559
|
+
label: field.label,
|
|
3560
|
+
disabled: !writable || saving,
|
|
3561
|
+
}),
|
|
3562
|
+
React.createElement('span', { style: { ...hint, marginLeft: isText(field) || isList(field) ? '0' : '26px' } }, field.description)))),
|
|
3563
|
+
React.createElement('div', { style: { display: 'flex', gap: '10px', alignItems: 'center', flexWrap: 'wrap' } },
|
|
3564
|
+
React.createElement(Button, {
|
|
3565
|
+
variant: 'primary',
|
|
3566
|
+
disabled: !writable || saving || !dirty,
|
|
3567
|
+
onClick: save,
|
|
3568
|
+
}, saving ? 'Saving…' : 'Save changes'),
|
|
3569
|
+
dirty
|
|
3570
|
+
? React.createElement(Button, {
|
|
3571
|
+
variant: 'ghost',
|
|
3572
|
+
disabled: saving,
|
|
3573
|
+
onClick: () => { setDraft(null); setNotice('') },
|
|
3574
|
+
}, 'Discard')
|
|
3575
|
+
: null,
|
|
3576
|
+
notice === '' ? null : React.createElement('span', { style: hint }, notice),
|
|
3577
|
+
writable ? null : React.createElement('span', { style: hint }, 'This profile does not accept configuration writes.')))
|
|
3578
|
+
}
|
|
3579
|
+
|
|
3580
|
+
const L5X = {
|
|
3581
|
+
id: 'l5x',
|
|
3582
|
+
summary: 'L5X editing, Studio 5000 SDK access and live EtherNet/IP reads are on by default; turn off what this machine does not use.',
|
|
3583
|
+
intro: 'The read surface is always on. Each switch below adds tool schemas to every request, so turn off what you do not use.',
|
|
3584
|
+
fields: [
|
|
3585
|
+
{
|
|
3586
|
+
key: 'editing',
|
|
3587
|
+
label: 'Editing — nine draft tools',
|
|
3588
|
+
description: 'Stages changes against a project copy; applying writes a new .L5X and leaves the open export untouched.',
|
|
3589
|
+
},
|
|
3590
|
+
{
|
|
3591
|
+
key: 'studio',
|
|
3592
|
+
label: 'Studio 5000 SDK and supervised controller',
|
|
3593
|
+
description: 'Needs Studio 5000 with the Logix Designer SDK service installed; upload, mode change and download are approval-gated.',
|
|
3594
|
+
},
|
|
3595
|
+
{
|
|
3596
|
+
key: 'live',
|
|
3597
|
+
label: 'Live EtherNet/IP',
|
|
3598
|
+
description: 'Controller identity, tag polling, batch reads up to 64 tags, wall clock, LAN discovery and a bounded trend.',
|
|
3599
|
+
},
|
|
3600
|
+
{
|
|
3601
|
+
key: 'allowWrites',
|
|
3602
|
+
label: 'Allow the two live writes',
|
|
3603
|
+
description: 'Tag value and controller clock. Each write still needs human approval for that exact operation, and only applies while live is on.',
|
|
3604
|
+
},
|
|
3605
|
+
],
|
|
3606
|
+
}
|
|
3607
|
+
|
|
3608
|
+
const FTVIEW = {
|
|
3609
|
+
id: 'ftview',
|
|
3610
|
+
summary: 'FactoryTalk View ME edits and the Studio handoff are on by default; turn them off to keep a read-only profile.',
|
|
3611
|
+
intro: 'The read surface and guidance stay on. Edits and the Studio handoff are on by default because the schemas are small.',
|
|
3612
|
+
fields: [
|
|
3613
|
+
{
|
|
3614
|
+
key: 'edit',
|
|
3615
|
+
label: 'FactoryTalk View ME edits',
|
|
3616
|
+
description: 'Display, HMI tag and structural edits against an exported project.',
|
|
3617
|
+
},
|
|
3618
|
+
{
|
|
3619
|
+
key: 'studio',
|
|
3620
|
+
label: 'Studio handoff',
|
|
3621
|
+
description: 'Opens the project in FactoryTalk View Studio ME for the parts the agent should not change itself.',
|
|
3622
|
+
},
|
|
3623
|
+
],
|
|
3624
|
+
}
|
|
3625
|
+
|
|
3626
|
+
const MWI = {
|
|
3627
|
+
id: 'mwi',
|
|
3628
|
+
summary: 'MotionWorks IEC edits are on by default; session, reads and verification are always on.',
|
|
3629
|
+
intro: 'Session, reads and verification stay on. Set the workspace once so the tools find the projects; turn editing off only for a read-only profile.',
|
|
3630
|
+
fields: [
|
|
3631
|
+
{
|
|
3632
|
+
key: 'workspace',
|
|
3633
|
+
type: 'text',
|
|
3634
|
+
label: 'Workspace root',
|
|
3635
|
+
placeholder: 'C:\\Users\\you\\Documents\\Projects',
|
|
3636
|
+
description: 'Absolute folder that contains the MotionWorks projects. Leave empty to use the session directory or the mwi.workspace marker in the profile.',
|
|
3637
|
+
},
|
|
3638
|
+
{
|
|
3639
|
+
key: 'edit',
|
|
3640
|
+
label: 'Editing — seven staged tools',
|
|
3641
|
+
description: 'Code, declarations, structure, blocks and POU package imports/exports. Needs MotionWorks IEC 3 Pro installed.',
|
|
3642
|
+
},
|
|
3643
|
+
],
|
|
3644
|
+
}
|
|
3645
|
+
|
|
3646
|
+
const OPTIX = {
|
|
3647
|
+
id: 'optix',
|
|
3648
|
+
summary: 'FactoryTalk Optix reads and authoring are on by default; turn off what this machine does not use.',
|
|
3649
|
+
intro: 'The Studio bridge runs inside FactoryTalk Optix Studio. Reads work once a project with the bridge is open; turn off the authoring surfaces this machine does not use.',
|
|
3650
|
+
fields: [
|
|
3651
|
+
{
|
|
3652
|
+
key: 'bridgeUrls',
|
|
3653
|
+
type: 'list',
|
|
3654
|
+
label: 'Studio bridge origins',
|
|
3655
|
+
placeholder: 'http://127.0.0.1:8768',
|
|
3656
|
+
description: 'Loopback origins, comma separated. The bridge listens inside Optix Studio; the default is port 8768.',
|
|
3657
|
+
},
|
|
3658
|
+
{
|
|
3659
|
+
key: 'bridgeToken',
|
|
3660
|
+
type: 'text',
|
|
3661
|
+
label: 'Bridge token',
|
|
3662
|
+
placeholder: 'Only if the bridge requires one',
|
|
3663
|
+
description: 'Bearer token sent to the Studio bridge. Leave empty when the bridge has no token.',
|
|
3664
|
+
},
|
|
3665
|
+
{
|
|
3666
|
+
key: 'allowWrites',
|
|
3667
|
+
label: 'Live authoring — optix_edit and optix_action',
|
|
3668
|
+
description: 'Applies typed edits to the live Studio model. Dry-run validation works without it; a successful edit does not save Studio.',
|
|
3669
|
+
},
|
|
3670
|
+
{
|
|
3671
|
+
key: 'allowDestructive',
|
|
3672
|
+
label: 'Allow destructive operations',
|
|
3673
|
+
description: 'Delete, move, reorder, retype, replace and convert. Requires live authoring.',
|
|
3674
|
+
},
|
|
3675
|
+
{
|
|
3676
|
+
key: 'allowInvoke',
|
|
3677
|
+
label: 'Invoke exported methods',
|
|
3678
|
+
description: 'Needs a session-safe bridge build; the packaged templates ship bridge 1.0.7, which cannot invoke.',
|
|
3679
|
+
},
|
|
3680
|
+
{
|
|
3681
|
+
key: 'preview',
|
|
3682
|
+
label: 'Emulator preview and screenshots',
|
|
3683
|
+
description: 'Registers optix_preview, optix_screenshot and (when configured) optix_ocr. Needs the emulator browser open with CDP enabled.',
|
|
3684
|
+
},
|
|
3685
|
+
{
|
|
3686
|
+
key: 'cdpUrl',
|
|
3687
|
+
type: 'text',
|
|
3688
|
+
label: 'Chromium CDP endpoint',
|
|
3689
|
+
placeholder: 'http://127.0.0.1:9223',
|
|
3690
|
+
description: 'Used only when the emulator preview is on.',
|
|
3691
|
+
},
|
|
3692
|
+
{
|
|
3693
|
+
key: 'previewUrl',
|
|
3694
|
+
type: 'text',
|
|
3695
|
+
label: 'Emulator preview URL',
|
|
3696
|
+
placeholder: 'http://127.0.0.1:8081/',
|
|
3697
|
+
description: 'Already-open emulator tab, matched by exact origin, path and query.',
|
|
3698
|
+
},
|
|
3699
|
+
{
|
|
3700
|
+
key: 'allowPreviewInput',
|
|
3701
|
+
label: 'Allow preview pointer and keyboard input',
|
|
3702
|
+
description: 'Input can change runtime values in the emulator. It ships on; turn it off when a test must not move the emulator.',
|
|
3703
|
+
},
|
|
3704
|
+
{
|
|
3705
|
+
key: 'ocrExecutable',
|
|
3706
|
+
type: 'text',
|
|
3707
|
+
label: 'OCR — Tesseract executable',
|
|
3708
|
+
placeholder: 'C:\\Program Files\\Tesseract-OCR\\tesseract.exe',
|
|
3709
|
+
description: 'Full path to tesseract.exe. Leave empty to keep optix_ocr unregistered; preview is still required.',
|
|
3710
|
+
},
|
|
3711
|
+
{
|
|
3712
|
+
key: 'ocrLanguage',
|
|
3713
|
+
type: 'text',
|
|
3714
|
+
label: 'OCR language',
|
|
3715
|
+
placeholder: 'eng',
|
|
3716
|
+
description: 'Tesseract language code, or a + separated list such as eng+deu. The matching .traineddata files must exist.',
|
|
3717
|
+
},
|
|
3718
|
+
{
|
|
3719
|
+
key: 'ocrTessdataDirectory',
|
|
3720
|
+
type: 'text',
|
|
3721
|
+
label: 'OCR tessdata folder',
|
|
3722
|
+
placeholder: 'C:\\Program Files\\Tesseract-OCR\\tessdata',
|
|
3723
|
+
description: 'Folder holding the .traineddata files. Empty uses tessdata beside the executable.',
|
|
3724
|
+
},
|
|
3725
|
+
],
|
|
3726
|
+
}
|
|
3727
|
+
|
|
3728
|
+
/**
|
|
3729
|
+
* Register the four row configuration pages.
|
|
3730
|
+
* @param ctx - the browser plugin context.
|
|
3731
|
+
*/
|
|
3732
|
+
function apply(ctx) {
|
|
3733
|
+
const configForms = () => {
|
|
3734
|
+
try {
|
|
3735
|
+
return ctx.get('configForms')
|
|
3736
|
+
} catch {
|
|
3737
|
+
return undefined
|
|
3738
|
+
}
|
|
3739
|
+
}
|
|
3740
|
+
const register = (rowId, spec) => {
|
|
3741
|
+
ctx.slots.inject('plugins.row.config', () => ctx.slots.register({
|
|
3742
|
+
name: 'plugins.row.config',
|
|
3743
|
+
key: '@aryacode/dsh-engineering#' + rowId,
|
|
3744
|
+
inject: () => ({ spec, configForms }),
|
|
3745
|
+
}, RowConfig))
|
|
3746
|
+
}
|
|
3747
|
+
register('l5x', L5X)
|
|
3748
|
+
register('ftview', FTVIEW)
|
|
3749
|
+
register('mwi', MWI)
|
|
3750
|
+
register('optix', OPTIX)
|
|
3751
|
+
}
|
|
3752
|
+
|
|
3753
|
+
return { inject: ['slots'], apply }
|
|
3754
|
+
|
|
3428
3755
|
})()
|
|
3429
3756
|
|
|
3430
3757
|
if (
|
|
3431
3758
|
typeof ladder.apply !== 'function' ||
|
|
3432
|
-
typeof ftview.apply !== 'function'
|
|
3759
|
+
typeof ftview.apply !== 'function' ||
|
|
3760
|
+
typeof settings.apply !== 'function'
|
|
3433
3761
|
) {
|
|
3434
3762
|
throw new Error("@aryacode/dsh-engineering" + ': a merged client face exports no apply()')
|
|
3435
3763
|
}
|
|
3436
3764
|
|
|
3437
|
-
// The declared services are the union of
|
|
3765
|
+
// The declared services are the union of every face's: one Cordis plugin
|
|
3438
3766
|
// cannot inject less than its parts need. CJS shape (exports.apply /
|
|
3439
3767
|
// exports.inject) is the loader's contract for a registered factory.
|
|
3440
3768
|
return {
|
|
3441
|
-
inject: [...new Set([...ladder.inject, ...ftview.inject])],
|
|
3769
|
+
inject: [...new Set([...ladder.inject, ...ftview.inject, ...settings.inject])],
|
|
3442
3770
|
apply: (ctx) => {
|
|
3443
3771
|
ladder.apply(ctx)
|
|
3444
3772
|
ftview.apply(ctx)
|
|
3773
|
+
settings.apply(ctx)
|
|
3445
3774
|
},
|
|
3446
3775
|
}
|
|
3447
3776
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aryacode/dsh-engineering",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.21",
|
|
4
4
|
"description": "AryaCode engineering bundle: one install surface for the Studio 5000 L5X, FactoryTalk View ME, MotionWorks IEC and FactoryTalk Optix surfaces, one row per product, with the ladder and display previews.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh",
|
|
@@ -55,6 +55,14 @@
|
|
|
55
55
|
]
|
|
56
56
|
}
|
|
57
57
|
},
|
|
58
|
+
"scripts": {
|
|
59
|
+
"test": "node --import tsx --test test/patch.spec.mjs test/docs.spec.mjs test/tool-reference.spec.mjs test/manifests.spec.mjs test/client-face.spec.mjs test/config.spec.mjs",
|
|
60
|
+
"docs:tools": "tsx scripts/gen-tool-reference.ts",
|
|
61
|
+
"docs:check": "tsx scripts/gen-tool-reference.ts --check",
|
|
62
|
+
"build:client": "node scripts/build-client.mjs",
|
|
63
|
+
"assemble": "node scripts/assemble.mjs",
|
|
64
|
+
"prepack": "node scripts/build-client.mjs && node scripts/assemble.mjs"
|
|
65
|
+
},
|
|
58
66
|
"dependencies": {
|
|
59
67
|
"fast-xml-parser": "5.11.1",
|
|
60
68
|
"fast-xml-validator": "1.4.2",
|
|
@@ -79,7 +87,7 @@
|
|
|
79
87
|
"./l5x": "./entries/l5x.js",
|
|
80
88
|
"./ftview": "./entries/ftview.js",
|
|
81
89
|
"./mwi": "./entries/mwi.js",
|
|
82
|
-
"./optix": "./
|
|
90
|
+
"./optix": "./entries/optix.js",
|
|
83
91
|
"./l5x/read": "./vendor/l5x/lib/index.js",
|
|
84
92
|
"./l5x/skill": "./vendor/l5x/lib/skill.js",
|
|
85
93
|
"./l5x/editing": "./vendor/l5x/lib/editing.js",
|
|
@@ -94,12 +102,5 @@
|
|
|
94
102
|
"./mwi/skill": "./vendor/mwi/lib/skill.js",
|
|
95
103
|
"./mwi/verify": "./vendor/mwi/lib/verify.js",
|
|
96
104
|
"./mwi/edit": "./vendor/mwi/lib/edit.js"
|
|
97
|
-
},
|
|
98
|
-
"scripts": {
|
|
99
|
-
"test": "node --import tsx --test test/patch.spec.mjs test/docs.spec.mjs test/tool-reference.spec.mjs test/manifests.spec.mjs test/client-face.spec.mjs",
|
|
100
|
-
"docs:tools": "tsx scripts/gen-tool-reference.ts",
|
|
101
|
-
"docs:check": "tsx scripts/gen-tool-reference.ts --check",
|
|
102
|
-
"build:client": "node scripts/build-client.mjs",
|
|
103
|
-
"assemble": "node scripts/assemble.mjs"
|
|
104
105
|
}
|
|
105
|
-
}
|
|
106
|
+
}
|
package/vendor/ftview/SKILL.md
CHANGED
|
@@ -13,6 +13,23 @@ A staged edit is written to a NEW export folder; the source is never modified. T
|
|
|
13
13
|
a manual import for a human; it does not drive Studio, contact a terminal, or decode MER or MED
|
|
14
14
|
databases.
|
|
15
15
|
|
|
16
|
+
## Backups
|
|
17
|
+
|
|
18
|
+
Every engineering product backs up into the same tree, so a backup means one place whichever surface
|
|
19
|
+
you are in:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
<workspace>/backups/<product>/<subject>/<UTC stamp>/
|
|
23
|
+
backup-manifest.json every copied file: relative path + SHA-256
|
|
24
|
+
<the copy>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
FactoryTalk View is the `ftview` product: the copy is the whole export folder (display XML plus the tag
|
|
28
|
+
CSV), one stamp per backup. `ftview_apply` already writes a new folder, so this is a backup on request
|
|
29
|
+
("back up this export"). Build it as a copy plus `backup-manifest.json` listing every file's relative
|
|
30
|
+
path and SHA-256. `<workspace>/_backups` and `<workspace>/backups/<project>/…` are older layouts: never
|
|
31
|
+
write there, and leave what is there alone.
|
|
32
|
+
|
|
16
33
|
## Start
|
|
17
34
|
|
|
18
35
|
1. Call `ftview_open` with the export folder. Keep the returned `view_id`.
|
package/vendor/l5x/SKILL.md
CHANGED
|
@@ -10,6 +10,23 @@ whenToUse: Use when the user asks about a Studio 5000 L5X export, Logix tags, ro
|
|
|
10
10
|
|
|
11
11
|
This surface reads and drafts. A draft writes only a new L5X file: it never overwrites the source, imports into Studio, connects to a controller, changes mode, or writes runtime data.
|
|
12
12
|
|
|
13
|
+
## Backups
|
|
14
|
+
|
|
15
|
+
Every engineering product backs up into the same tree, so a backup means one place whichever surface
|
|
16
|
+
you are in:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
<workspace>/backups/<product>/<subject>/<UTC stamp>/
|
|
20
|
+
backup-manifest.json every copied file: relative path + SHA-256
|
|
21
|
+
<the copy>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Studio 5000 is the `l5x` product: the copy holds the `.ACD` being worked on, or the `.L5X` export when
|
|
25
|
+
that is the source of truth, one stamp per backup. Drafts and SDK builds already write new files, so
|
|
26
|
+
this is a backup on request ("back up this project"). Build it as a copy plus
|
|
27
|
+
`backup-manifest.json` listing every file's relative path and SHA-256. `<workspace>/_backups` and
|
|
28
|
+
`<workspace>/backups/<project>/…` are older layouts: never write there, and leave what is there alone.
|
|
29
|
+
|
|
13
30
|
## Start
|
|
14
31
|
|
|
15
32
|
1. Call `open_project` with the export path. Keep the returned `project_id`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<configuration><packageSources><clear/><add key="LocalRockwellSdk" value="C:\Users\Public\Documents\Studio 5000\Logix Designer SDK\dotnet"/><add key="nuget.org" value="https://api.nuget.org/v3/index.json"/></packageSources></configuration>
|
|
1
|
+
<configuration><packageSources><clear/><add key="LocalRockwellSdk" value="C:\Users\Public\Documents\Studio 5000\Logix Designer SDK\dotnet"/><add key="nuget.org" value="https://api.nuget.org/v3/index.json"/></packageSources></configuration>
|
package/vendor/mwi/README.md
CHANGED
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
# dsh-engineering-mwi
|
|
2
2
|
|
|
3
|
-
MotionWorks IEC 3 Pro tools, redesigned for the `dsh-engineering` bundle. The product
|
|
4
|
-
**
|
|
5
|
-
|
|
3
|
+
MotionWorks IEC 3 Pro tools, redesigned for the `dsh-engineering` bundle. The product edits the
|
|
4
|
+
**real workspace project**: `mw_project_open` writes one complete hash-verified backup under
|
|
5
|
+
`<workspace>/backups/motionworks/<project>/<stamp>/` first, then drives the running IDE through the
|
|
6
|
+
existing 32-bit COM bridge. A project the IDE already has open is attached (backup recorded) instead of
|
|
7
|
+
reloaded, so unsaved editor changes survive. `mw_project_stage` remains as an optional sandbox.
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
`<workspace>/backups/<product>/<subject>/<stamp>/` is the one tree every engineering product writes
|
|
10
|
+
under, so a backup is one place whichever surface the user is in. MotionWorks is the product whose
|
|
11
|
+
backup is also a contract: the shipped bridge (`Get-DirectIdentity`) and the read-only engine
|
|
12
|
+
(`assert_direct_attached`) refuse a real project unless an identity record names a copy in that tree,
|
|
13
|
+
with a manifest whose SHA-256 matches. Records written before 0.4.21 that point at
|
|
14
|
+
`.motionworks/attached/backups` stay valid.
|
|
10
15
|
|
|
11
|
-
## Rows
|
|
16
|
+
## Rows
|
|
12
17
|
|
|
13
18
|
| Row | Default | Tools | Status |
|
|
14
19
|
|---|---|---|---|
|
|
15
20
|
| `mwi-session` | on | 7 | implemented and live-verified |
|
|
16
21
|
| `mwi-read` | on | 7 | implemented and live-verified |
|
|
17
|
-
| `mwi-verify` | on | 3 |
|
|
18
|
-
| `mwi-edit` |
|
|
22
|
+
| `mwi-verify` | on | 3 | implemented and live-verified |
|
|
23
|
+
| `mwi-edit` | on | 7 | implemented; direct-edit path live-verified |
|
|
19
24
|
| `mwi-skill` | on | the `motionworks-iec` guidance | implemented |
|
|
20
25
|
|
|
21
26
|
Read tools: `mw_project_overview`, `mw_list`, `mw_get`, `mw_search`, `mw_references`, `mw_review`, `mw_help`.
|
|
@@ -23,16 +28,34 @@ Read tools: `mw_project_overview`, `mw_list`, `mw_get`, `mw_search`, `mw_referen
|
|
|
23
28
|
Session tools: `mw_project_find`, `mw_ide_status`, `mw_project_stage`, `mw_project_open`,
|
|
24
29
|
`mw_ide_start`, `mw_worksheet_open`, `mw_project_close`.
|
|
25
30
|
|
|
31
|
+
Edit tools: `mw_edit_code`, `mw_edit_variables`, `mw_edit_structure`, `mw_insert_block`,
|
|
32
|
+
`mw_transfer_pou`, `mw_validate`, `mw_apply`.
|
|
33
|
+
|
|
26
34
|
## Live evidence
|
|
27
35
|
|
|
28
|
-
Verified against MotionWorks IEC 3 Pro 1.19
|
|
29
|
-
|
|
36
|
+
Verified against MotionWorks IEC 3 Pro 1.19 with a copy of a real project in a temporary workspace:
|
|
37
|
+
|
|
38
|
+
1. `open` writes `backups/motionworks/<project>/<stamp>/` with `backup-manifest.json` and
|
|
39
|
+
`.motionworks/attached/records/<id>.json`, verified before the IDE is asked to open anything, and
|
|
40
|
+
reuses that backup on later attaches.
|
|
41
|
+
2. A project already open in the IDE is attached without an `OpenProject` call: `mw_project_open`
|
|
42
|
+
reports `already_open` and the verified backup path.
|
|
43
|
+
3. `start` launches the IDE on the real `.mwt`; `status` reports it open.
|
|
44
|
+
4. `worksheet` opens `Global_Variables` and verifies the active editor and unchanged modified state.
|
|
45
|
+
5. `edit` tools write through the native IDE API; `apply` saves the project in place, and an edit
|
|
46
|
+
refused for a missing backup takes one before retrying.
|
|
47
|
+
6. `close` reports `closed: true`, and the next status reports the IDE not running.
|
|
48
|
+
|
|
49
|
+
The staged flow (`stage` then `open` the copy) still works when a sandbox is wanted.
|
|
50
|
+
|
|
51
|
+
## What the guarded read proves
|
|
52
|
+
|
|
53
|
+
`mw_get` for a POU returns the `text_body_sha256` of the exact body it returns. Passing it to
|
|
54
|
+
`mw_edit_code` is optional: when it is omitted, the tool hashes the current saved body itself, so the
|
|
55
|
+
documented read-then-edit flow works either way.
|
|
30
56
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
3. `status` reported the staged project open, `in_stage: true`.
|
|
34
|
-
4. `worksheet` opened `Global_Variables` and verified the active editor and unchanged modified state.
|
|
35
|
-
5. `close` reported `closed: true`, and the next status reported the IDE not running.
|
|
57
|
+
The identity check confirms the manifest digest and that every recorded member exists. Per-file hashes
|
|
58
|
+
are recorded for a restore and for the copy-time check; they are not recomputed on every guarded call.
|
|
36
59
|
|
|
37
60
|
## Structure
|
|
38
61
|
|
|
@@ -41,8 +64,8 @@ SKILL.md the redesigned guidance
|
|
|
41
64
|
bridge/ the 32-bit PowerShell COM bridge
|
|
42
65
|
code/ the Python engine (wrapper binding, saved-model reads, validation)
|
|
43
66
|
src/core/ params, result, errors, tool, bridge, PowerShell transport, code engine
|
|
44
|
-
src/session/ workspace, stage, runtime
|
|
45
|
-
src/tools/ session
|
|
67
|
+
src/session/ workspace, stage, backup, runtime
|
|
68
|
+
src/tools/ session, read, verify and edit rows
|
|
46
69
|
test/ contract tests and the live fixtures
|
|
47
70
|
```
|
|
48
71
|
|