@aryacode/dsh-engineering 0.4.6 → 0.4.20
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 +199 -0
- package/README.md +37 -26
- package/cordis.patch.yml +7 -6
- package/entries/config.js +62 -0
- package/entries/ftview.js +5 -4
- package/entries/l5x.js +61 -13
- 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/l5x/README.md +27 -5
- package/vendor/l5x/studio-bridge/NuGet.Config +1 -1
- package/vendor/mwi/README.md +39 -18
- package/vendor/mwi/SKILL.md +26 -20
- package/vendor/mwi/bridge/mw_bridge.ps1 +2763 -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/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 +128 -128
- 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 +55 -0
- package/vendor/mwi/lib/session/backup.js +232 -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__/__init__.cpython-312.pyc +0 -0
- 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__/errors.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__/staging.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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,204 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.20] - 2026-10-27
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **The bundle no longer ships Python bytecode.** `__pycache__` and `*.pyc` from the MotionWorks
|
|
8
|
+
engine are ignored and excluded, so the tarball contains only the sources the plugin runs.
|
|
9
|
+
|
|
10
|
+
## [0.4.19] - 2026-10-27
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **Reads without a project name find the attached project.** `mw_get`, `mw_help` and `mw_search`
|
|
15
|
+
resolve the single project with a verified pre-edit backup when no `project` is passed, so the
|
|
16
|
+
direct workflow no longer fails with `NO_PROJECT`. A leftover `.motionworks/stage` copy no longer
|
|
17
|
+
shadows that project, and two attached projects are reported as `AMBIGUOUS_PROJECT` with both names.
|
|
18
|
+
|
|
19
|
+
## [0.4.18] - 2026-10-27
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- **MotionWorks edits no longer demand a body hash the caller had to guess.** `mw_edit_code` with
|
|
24
|
+
`changes` hashes the body it is about to patch when `expected_body_sha256` is omitted; the backup
|
|
25
|
+
and exact find/replace still guard the write, and a supplied hash is still honored.
|
|
26
|
+
- **A stale stage no longer makes the direct workflow ambiguous.** When a project has a verified
|
|
27
|
+
pre-edit backup, `singleStage()` now prefers that project over old `.motionworks/stage` copies.
|
|
28
|
+
|
|
29
|
+
## [0.4.17] - 2026-10-27
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
|
|
33
|
+
- **A direct MotionWorks open was refused as "outside the staging root".** 0.4.13 promised a
|
|
34
|
+
backup-first direct open, but the copy was written to `<workspace>/backups/<project>/<timestamp>`
|
|
35
|
+
while the shipped bridge (`Get-DirectIdentity`) and the read-only engine (`assert_direct_attached`)
|
|
36
|
+
only accept an identity record at `<workspace>/.motionworks/attached/records/<id>.json` naming a
|
|
37
|
+
backup under `.motionworks/attached/backups`. The two never met: `mw_project_open` refused every
|
|
38
|
+
project the retired solo plugin had not already attached, which is why MotionWorks work still looked
|
|
39
|
+
like it required staging. The backup module now writes exactly that layout, verifies the copy before
|
|
40
|
+
writing the identity, and refuses to replace an identity that no longer verifies.
|
|
41
|
+
- **A project already open in the IDE could not be edited.** Edits, compile and verify required a
|
|
42
|
+
proven backup and failed with `NOT_ATTACHED` for a workspace project the IDE already had open.
|
|
43
|
+
`mw_project_open` now attaches that project — writes the verified backup and reports
|
|
44
|
+
`already_open` — instead of calling `OpenProject`, because a reload over unsaved editor changes is
|
|
45
|
+
data loss the backup cannot undo. An edit, compile or verify that finds an unattached workspace
|
|
46
|
+
project takes the backup before it refuses.
|
|
47
|
+
- **`mw_edit_code` could not be given the hash it demands.** Its precondition is the SHA-256 of the
|
|
48
|
+
saved body, and the tool tells the caller to read `text_body_sha256` from `mw_get`; `mw_get`
|
|
49
|
+
returned the body but no hash, so the hash had to be found elsewhere or guessed and the edit failed
|
|
50
|
+
with "Saved code differs from expected_body/hash". `mw_get` now returns the `text_body_sha256` of
|
|
51
|
+
exactly the body it returns.
|
|
52
|
+
- **A read before the open still pointed at staging.** The engine guard's refusal text belongs to the
|
|
53
|
+
retired staging flow and told the caller to stage a copy, which is what sent an agent back into
|
|
54
|
+
staging after it had been removed from the workflow. The engine boundary now translates that
|
|
55
|
+
refusal into `NOT_ATTACHED` with the fix "call `mw_project_open` first"; every other refusal keeps
|
|
56
|
+
its own text.
|
|
57
|
+
|
|
58
|
+
### Documentation
|
|
59
|
+
|
|
60
|
+
- `packages/mwi/SKILL.md`: the backup lives under `<workspace>/.motionworks/attached/`, an
|
|
61
|
+
already-open project is attached and not reloaded, and the edit section names the hash `mw_get`
|
|
62
|
+
returns.
|
|
63
|
+
- `packages/mwi/README.md`: rows, backup layout, the attach-without-reload path and the guarded read,
|
|
64
|
+
including what the identity check does and does not recompute.
|
|
65
|
+
- README: the MotionWorks row, the composition diagram, the tool groups and the safety section
|
|
66
|
+
describe a direct edit. The row-default table and diagram now match the shipped defaults (every
|
|
67
|
+
surface on), which the 0.4.15 release changed but the diagram still showed as off.
|
|
68
|
+
|
|
69
|
+
## [0.4.16] - 2026-10-27
|
|
70
|
+
|
|
71
|
+
### Added
|
|
72
|
+
|
|
73
|
+
- **FactoryTalk Optix OCR is configurable from Plugins.** The `optix` row now
|
|
74
|
+
carries `ocrExecutable`, `ocrLanguage` and `ocrTessdataDirectory`. A configured
|
|
75
|
+
executable registers `optix_ocr`; an empty path keeps OCR off. An empty tessdata
|
|
76
|
+
folder derives `tessdata` beside the executable. OCR still requires the preview
|
|
77
|
+
browser and one matching tab, because it reads the rendered canvas.
|
|
78
|
+
|
|
79
|
+
### Fixed
|
|
80
|
+
|
|
81
|
+
- **An empty preview URL no longer breaks `optix_preview` and `optix_screenshot`.**
|
|
82
|
+
A saved blank `previewUrl` or `cdpUrl` now falls back to the loopback defaults
|
|
83
|
+
instead of failing with `Invalid URL`.
|
|
84
|
+
|
|
85
|
+
## [0.4.15] - 2026-10-27
|
|
86
|
+
|
|
87
|
+
### Changed
|
|
88
|
+
|
|
89
|
+
- **Every tool surface ships on.** A fresh install no longer hides the expensive
|
|
90
|
+
halves: L5X gets `editing`, `studio`, `live` and `allowWrites`; MotionWorks IEC
|
|
91
|
+
gets `edit`; FactoryTalk Optix gets live authoring, destructive operations,
|
|
92
|
+
exported-method invocation, the emulator preview and preview input. The defaults
|
|
93
|
+
live in each row's `Config` schema, so the Configure page shows them on and a
|
|
94
|
+
read-only profile can still switch them off.
|
|
95
|
+
- Docs, row descriptions and the generated tool reference now describe the
|
|
96
|
+
on-by-default behaviour. `docs/architecture.md`, `README.md`, `cordis.patch.yml`
|
|
97
|
+
and the settings page copy were updated with the schemas.
|
|
98
|
+
|
|
99
|
+
## [0.4.14] - 2026-10-27
|
|
100
|
+
|
|
101
|
+
### Added
|
|
102
|
+
|
|
103
|
+
- **FactoryTalk Optix has a Configure page.** The `optix` row now mounts through
|
|
104
|
+
`entries/optix.js`, which owns a volatile config schema and hands the prebuilt
|
|
105
|
+
`@aryacode/dsh-tool-ft-optix` plugin plain options. Configure can set the Studio
|
|
106
|
+
bridge origins and token, live authoring, destructive operations, exported-method
|
|
107
|
+
invocation, the emulator preview and preview input. Live authoring is on by default from 0.4.15; the Configure page can
|
|
108
|
+
switch it off. Reads work as soon as a project with the Studio bridge is open.
|
|
109
|
+
## [0.4.13] - 2026-10-27
|
|
110
|
+
|
|
111
|
+
### Changed
|
|
112
|
+
|
|
113
|
+
- **MotionWorks edits the real project again.** `mw_project_open` and `mw_ide_start` now take a
|
|
114
|
+
workspace `.mwt` and work on its files directly. Before the first write they copy the wrapper and
|
|
115
|
+
the expanded project into `<workspace>/backups/<project>/<timestamp>/`, hash every copied file in
|
|
116
|
+
`backup-manifest.json`, verify the copy, and reuse that backup on later attaches. `mw_apply` saves
|
|
117
|
+
in place; there is no sync-back step.
|
|
118
|
+
- **Staging is optional.** `mw_project_stage` remains for a sandbox copy, but the skill and tool
|
|
119
|
+
descriptions lead with the direct path.
|
|
120
|
+
|
|
121
|
+
## [0.4.12] - 2026-10-27
|
|
122
|
+
|
|
123
|
+
### Fixed
|
|
124
|
+
|
|
125
|
+
- **The MotionWorks workspace setting was ignored.** `workspace` is volatile, so it arrives as a
|
|
126
|
+
live reference; passing the reference to `configureWorkspace` did nothing. The row now unwraps it
|
|
127
|
+
with `text()`, so the value saved in Configure is the folder the tools search.
|
|
128
|
+
|
|
129
|
+
## [0.4.11] - 2026-10-27
|
|
130
|
+
|
|
131
|
+
### Fixed
|
|
132
|
+
|
|
133
|
+
- **MotionWorks editing tools never mounted even when the switch was on.** A `.volatile()` config
|
|
134
|
+
field reaches `apply()` as a live accessor, so `config.edit === true` was always false and the
|
|
135
|
+
seven edit tools were never registered. Every row now resolves switches through
|
|
136
|
+
`entries/config.js` (`flag`/`list`).
|
|
137
|
+
- **Flipping a switch did not take effect until the row was disabled and re-enabled.** The loader
|
|
138
|
+
commits volatile-only changes without re-running `apply()`, then emits `loader/volatile-update`.
|
|
139
|
+
The L5X and MotionWorks rows now mount and unmount their optional surfaces from that event.
|
|
140
|
+
- **MotionWorks looked for projects in the profile directory.** The host does not always pass the
|
|
141
|
+
session cwd, so `workspaceOf()` fell back to `process.cwd()`. The row now carries a `workspace`
|
|
142
|
+
setting (shown in Configure) and falls back to the `mwi.workspace` marker in the profile, then the
|
|
143
|
+
process directory. Project discovery follows directory junctions without looping.
|
|
144
|
+
|
|
145
|
+
## [0.4.10] - 2026-10-26
|
|
146
|
+
|
|
147
|
+
### Fixed
|
|
148
|
+
|
|
149
|
+
- **The row settings page sat on "Loading configuration…".** The Plugins page snapshots a row's
|
|
150
|
+
configuration form once when it opens and does not subscribe to it, so a form that was still
|
|
151
|
+
loading at that moment never produced the switches. The page now reads the live form from the
|
|
152
|
+
client `configForms` service, whose `get` starts the one describe fetch, and subscribes to it;
|
|
153
|
+
the switches appear when the settings settle, and a row with no configuration says so instead of
|
|
154
|
+
loading forever.
|
|
155
|
+
- **The row switches were not served to Settings at all.** The config fields were plain
|
|
156
|
+
`z.boolean()` values, and the settings domain only publishes fields marked `.volatile()`; the
|
|
157
|
+
rows therefore had no settings namespace for the page to bind to. `editing`, `studio`, `live`,
|
|
158
|
+
`allowWrites`, `allowedAddresses`, `ftview.edit`/`studio` and `mwi.edit` are now volatile, so the
|
|
159
|
+
Configure page edits the running row instead of remounting it.
|
|
160
|
+
|
|
161
|
+
## [0.4.9] - 2026-10-26
|
|
162
|
+
|
|
163
|
+
### Fixed
|
|
164
|
+
|
|
165
|
+
- Republished the row settings pages with the client half's declared service list taken from every
|
|
166
|
+
bundled face rather than the two viewer faces. Same pages and same defaults as 0.4.8; this build is
|
|
167
|
+
the installable one.
|
|
168
|
+
|
|
169
|
+
## [0.4.8] - 2026-10-26
|
|
170
|
+
|
|
171
|
+
### Fixed
|
|
172
|
+
|
|
173
|
+
- **The product rows had no settings page.** The bundle's client half never registered a
|
|
174
|
+
`plugins.row.config` entry, so the Plugins page showed no Configure control for `l5x`, `ftview` or
|
|
175
|
+
`mwi`, and the switches the README documents were unreachable without editing the profile patch by
|
|
176
|
+
hand. `scripts/faces/settings.js` now registers one page per row: L5X editing, the Studio 5000 SDK,
|
|
177
|
+
live EtherNet/IP and the two live writes; FactoryTalk View ME edits and the Studio handoff;
|
|
178
|
+
MotionWorks IEC edits. Values are staged and saved through the row's own configuration form, and the
|
|
179
|
+
defaults are unchanged.
|
|
180
|
+
|
|
181
|
+
## [0.4.7] - 2026-10-25
|
|
182
|
+
|
|
183
|
+
### Fixed
|
|
184
|
+
|
|
185
|
+
- **`allowWrites` could not be reached from the L5X row.** The composite entry mounted the live entry
|
|
186
|
+
with no config, so the write switch had no path from the Plugins page. `entries/l5x.js` now declares
|
|
187
|
+
`allowWrites` and `allowedAddresses` and forwards both into the live entry; the write tools still
|
|
188
|
+
refuse without per-call approval.
|
|
189
|
+
|
|
190
|
+
### Documentation
|
|
191
|
+
|
|
192
|
+
- README: the safety section states the two keys a live write takes, the tool groups list all seven
|
|
193
|
+
EtherNet/IP tools, and the L5X count is 40 (84 with Optix).
|
|
194
|
+
- `docs/examples.md`: a live section covering batch reads, discovery, the controller clock, the trend,
|
|
195
|
+
and a supervised write with the exact fields the reader must see and the refusals they may hit.
|
|
196
|
+
- `docs/architecture.md`: a new EtherNet/IP section — the two workers, the transaction engine's deadline
|
|
197
|
+
and decoding, and the four gates that stand between a write request and a controller.
|
|
198
|
+
- `docs/port/l5x.md`: the live surface is recorded as seven tools with the driver call each one uses, and
|
|
199
|
+
the unused capability (CIP subscriptions, UDT `Structure` reads) is named.
|
|
200
|
+
- `packages/l5x/README.md`: read and write tool tables, and the full live configuration row.
|
|
201
|
+
|
|
3
202
|
## [0.4.6] - 2026-10-25
|
|
4
203
|
|
|
5
204
|
### Added
|
package/README.md
CHANGED
|
@@ -14,17 +14,19 @@ A general assistant pays for every tool schema on every request. An automation e
|
|
|
14
14
|
surfaces — reading a 3 MB L5X, comparing two projects, staging ladder edits, talking to a controller —
|
|
15
15
|
but only one or two of them at a time.
|
|
16
16
|
|
|
17
|
-
This bundle splits those surfaces into one row per product. The expensive surfaces are
|
|
18
|
-
the row
|
|
17
|
+
This bundle splits those surfaces into one row per product. The expensive surfaces are switches inside
|
|
18
|
+
the row. They ship on by default so a fresh install can use every tool; switch off what a
|
|
19
|
+
read-only or low-context profile does not need:
|
|
19
20
|
|
|
20
21
|
| Product row | Config option | Default | What turning it on adds |
|
|
21
22
|
|---|---|---|---|
|
|
22
|
-
| `l5x` | `editing` |
|
|
23
|
-
| `l5x` | `studio` |
|
|
24
|
-
| `l5x` | `live` |
|
|
25
|
-
| `l5x` | `allowWrites` |
|
|
23
|
+
| `l5x` | `editing` | on | the nine `draft_*` schemas |
|
|
24
|
+
| `l5x` | `studio` | on | the Logix Designer SDK and supervised controller schemas |
|
|
25
|
+
| `l5x` | `live` | on | the EtherNet/IP read, batch, discovery, clock and trend schemas |
|
|
26
|
+
| `l5x` | `allowWrites` | on | the two approval-gated writes (tag, wall clock) |
|
|
26
27
|
| `ftview` | `edit`, `studio` | on | staged ME edits and the Studio handoff |
|
|
27
|
-
| `mwi` | `edit` |
|
|
28
|
+
| `mwi` | `edit` | on | the seven MotionWorks edit schemas |
|
|
29
|
+
| `optix` | `allowWrites`, `allowDestructive`, `allowInvoke`, `preview`, `ocrExecutable` | on | Studio authoring, destructive ops, method invocation, emulator preview and OCR when Tesseract is set |
|
|
28
30
|
|
|
29
31
|
The previews are independent of the tools — switching a product off does not remove the ladder viewer.
|
|
30
32
|
Both previews mount from **one** row (`viewers`), because a package registers exactly one browser
|
|
@@ -34,17 +36,17 @@ bundle.
|
|
|
34
36
|
|
|
35
37
|
| Product | Tools | Default | Needs |
|
|
36
38
|
|---|---|---|---|
|
|
37
|
-
| **Studio 5000 L5X** | 40 |
|
|
39
|
+
| **Studio 5000 L5X** | 40 | all on | Node for offline reads; Studio 5000 + Logix Designer SDK for SDK work; a controller for live |
|
|
38
40
|
| **FactoryTalk View ME** | 14 | all on | Node for an export folder; FactoryTalk View Studio ME for discovery and the handoff |
|
|
39
|
-
| **MotionWorks IEC** | 24 |
|
|
40
|
-
| **FactoryTalk Optix** |
|
|
41
|
+
| **MotionWorks IEC** | 24 | all on | MotionWorks IEC 3 Pro installed; verified against 1.19 |
|
|
42
|
+
| **FactoryTalk Optix** | 9 (3 need preview) | all on | Optix Studio installed; Tesseract for OCR |
|
|
41
43
|
|
|
42
44
|
Tool groups, by product:
|
|
43
45
|
|
|
44
46
|
- **L5X** — 11 read (`open_project` … `compare_projects`), 9 staged drafts (`draft_*`), 6 Logix
|
|
45
47
|
Designer SDK, 7 supervised controller, 7 live EtherNet/IP (2 reads, 2 identity/discovery, 1 batch read, 2 approval-gated writes)
|
|
46
48
|
- **FactoryTalk View** — 6 read, 5 staged edits, 3 Studio handoff
|
|
47
|
-
- **MotionWorks IEC** — 7 session, 7 saved-project reads, 3 verify, 7
|
|
49
|
+
- **MotionWorks IEC** — 7 session, 7 saved-project reads, 3 verify, 7 direct edits
|
|
48
50
|
- **Optix** — 6 tools, unlinked to a skill until one exists
|
|
49
51
|
|
|
50
52
|
## Switches
|
|
@@ -56,11 +58,11 @@ down:
|
|
|
56
58
|
|
|
57
59
|
| Row | Mounts | Config options (default) |
|
|
58
60
|
|---|---|---|
|
|
59
|
-
| `l5x` | offline reads, checks, comparison and the `rockwell-l5x` guidance; optionally drafts, SDK, live (reads, batch, discovery, clock) and supervised writes | `editing` (
|
|
61
|
+
| `l5x` | offline reads, checks, comparison and the `rockwell-l5x` guidance; optionally drafts, SDK, live (reads, batch, discovery, clock) and supervised writes | `editing` (on), `studio` (on), `live` (on), `allowWrites` (on) |
|
|
60
62
|
| `ftview` | FactoryTalk View ME read, guidance and edits; optionally the Studio handoff | `edit` (on), `studio` (on) |
|
|
61
|
-
| `mwi` | MotionWorks IEC session, reads, verify
|
|
63
|
+
| `mwi` | MotionWorks IEC session, reads, verify, guidance and the edits | `workspace` (empty), `edit` (on) |
|
|
62
64
|
| `viewers` | ladder + ME display previews | — |
|
|
63
|
-
| `optix` | FactoryTalk Optix Studio authoring |
|
|
65
|
+
| `optix` | FactoryTalk Optix Studio authoring | `bridgeUrls` (8768), `bridgeToken` (empty), `allowWrites` (on), `allowDestructive` (on), `allowInvoke` (on), `preview` (on), `allowPreviewInput` (on), `cdpUrl`, `previewUrl`, `ocrExecutable` (empty), `ocrLanguage` (`eng`), `ocrTessdataDirectory` (empty) |
|
|
64
66
|
|
|
65
67
|
**Why the row list collapsed.** The Plugins page lists a bundle's rows flat and skips `cordis:group`
|
|
66
68
|
containers (`plugin-manager/src/index.ts`: *"Group rows are containers … their children carry the
|
|
@@ -90,13 +92,16 @@ Where each surface actually stands, based on what has been exercised.
|
|
|
90
92
|
- Live EtherNet/IP: polling, one-request batch reads of up to 64 tags, controller identity and clock, LAN discovery, and a bounded trend
|
|
91
93
|
- Supervised live writes: `write_live_tag` and `write_controller_clock` need the row's `allowWrites` switch **and** per-call human approval, and report the value the controller reads back
|
|
92
94
|
- FactoryTalk View ME: export reads, structural checks, comparison, staged display and HMI tag edits
|
|
93
|
-
- MotionWorks IEC: verified live against 3 Pro 1.19 —
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
- MotionWorks IEC: verified live against 3 Pro 1.19 — direct open with a verified pre-edit backup
|
|
96
|
+
under `.motionworks/attached`, attach-without-reload to a project the IDE already has open, start,
|
|
97
|
+
worksheet, close, saved-project reads, compile diagnostics, code replacement, declaration add, POU
|
|
98
|
+
create/delete, block insertion and a POU package export/delete/import round trip
|
|
96
99
|
- Ladder viewer and FactoryTalk View display preview
|
|
97
100
|
|
|
98
|
-
**
|
|
99
|
-
|
|
101
|
+
**On by default** — every tool surface mounts on a fresh install. Switch one off from the row's
|
|
102
|
+
Configure page in Plugins (`l5x` editing/Studio/live/allowWrites, `mwi` edit, `optix` authoring/preview)
|
|
103
|
+
when the profile is read-only or the request budget is tight. Tool schemas are sent on every request, so
|
|
104
|
+
the lean profile is the one that turns them off.
|
|
100
105
|
|
|
101
106
|
**Known limits** — stated in the bundle, not hidden:
|
|
102
107
|
|
|
@@ -105,7 +110,7 @@ Where each surface actually stands, based on what has been exercised.
|
|
|
105
110
|
- FBD/SFC semantics are not exercised
|
|
106
111
|
- FactoryTalk View Studio work is a **manual handoff**: the bundle plans the import and preflights
|
|
107
112
|
changed files, it does not import
|
|
108
|
-
- Optix has no skill
|
|
113
|
+
- Optix has no skill yet; its tools follow the `optix` row config and the Studio bridge
|
|
109
114
|
|
|
110
115
|
**Not in this repository** — CAD mounts as an independent plugin.
|
|
111
116
|
|
|
@@ -113,6 +118,8 @@ Where each surface actually stands, based on what has been exercised.
|
|
|
113
118
|
|
|
114
119
|
| Version | What landed |
|
|
115
120
|
|---|---|
|
|
121
|
+
| **0.4.17** | MotionWorks edits the real project again: the pre-edit backup is written where the bridge and engine verify it, an already-open project is attached instead of reloaded, and `mw_get` returns the body hash the edit takes |
|
|
122
|
+
| **0.4.15** | Every tool surface ships on by default; the row Configure pages switch them off |
|
|
116
123
|
| **0.4.4** | One row per product: five rows, optional surfaces moved into each row's config |
|
|
117
124
|
| **0.4.0** | Both previews fold into the bundle's own client face — one package, one browser bundle, 16 rows |
|
|
118
125
|
| **0.4.6** | Full EtherNet/IP surface: batch reads, discovery, controller clock, and approval-gated tag and clock writes; 84 tools |
|
|
@@ -149,9 +156,9 @@ another bundle owns.
|
|
|
149
156
|
```mermaid
|
|
150
157
|
flowchart TB
|
|
151
158
|
Profile["Profile bundle list"] --> Bundle["@aryacode/dsh-engineering"]
|
|
152
|
-
Bundle -->|insert| L5X["l5x (on) — read + guidance
|
|
159
|
+
Bundle -->|insert| L5X["l5x (on) — read + guidance + drafts / SDK / live"]
|
|
153
160
|
Bundle -->|insert| FTV["ftview (on) — read, edits, Studio handoff"]
|
|
154
|
-
Bundle -->|insert| MWI["mwi (on) — session, read, verify
|
|
161
|
+
Bundle -->|insert| MWI["mwi (on) — session, read, verify, edit"]
|
|
155
162
|
Bundle -->|insert| Viewers["viewers (on) — ladder + ME display previews"]
|
|
156
163
|
Bundle -->|insert| Optix["optix (on)"]
|
|
157
164
|
```
|
|
@@ -161,21 +168,25 @@ even when the implementation behind a row is replaced.
|
|
|
161
168
|
|
|
162
169
|
| Row id | Package entry | Config options |
|
|
163
170
|
|---|---|---|
|
|
164
|
-
| `l5x` | `dsh-engineering-l5x` | `editing`
|
|
171
|
+
| `l5x` | `dsh-engineering-l5x` | `editing` on · `studio` on · `live` on · `allowWrites` on |
|
|
165
172
|
| `ftview` | `dsh-engineering-ftview` | `edit` on · `studio` on |
|
|
166
|
-
| `mwi` | `dsh-engineering-mwi` | `edit`
|
|
173
|
+
| `mwi` | `dsh-engineering-mwi` | `edit` on |
|
|
167
174
|
| `viewers` | `@aryacode/dsh-engineering` (its own client face: ladder + ME display previews) | — |
|
|
168
|
-
| `optix` | `@aryacode/dsh-tool-ft-optix` |
|
|
175
|
+
| `optix` | `@aryacode/dsh-engineering/optix` (wraps the prebuilt `@aryacode/dsh-tool-ft-optix`) | `allowWrites` on · `allowDestructive` on · `allowInvoke` on · `preview` on |
|
|
169
176
|
|
|
170
177
|
## Safety
|
|
171
178
|
|
|
172
179
|
- **Read-only by default.** Reading, checks, comparison and the viewers never change a controller.
|
|
173
180
|
- **Edits write new files.** `draft_apply` writes one new L5X beside the source and refuses to
|
|
174
181
|
overwrite; `ftview_apply` writes a new export folder and leaves the source untouched. MotionWorks
|
|
175
|
-
edits write
|
|
182
|
+
edits write the real workspace project, after one complete backup under
|
|
183
|
+
`<workspace>/.motionworks/attached/`, and verify unrelated saved and native state.
|
|
176
184
|
- **Controller changes need a human.** Upload, mode change and download require per-call approval and
|
|
177
185
|
a session policy that permits asking. The tools refuse before contacting a controller when approval
|
|
178
186
|
is unavailable, and a download accepts only a verification id produced by a passed build.
|
|
187
|
+
- **Live writes take two keys.** `write_live_tag` and `write_controller_clock` need the row's
|
|
188
|
+
`allowWrites` switch *and* approval for that exact write; the tag is validated against the export
|
|
189
|
+
first and the result is the value the controller reads back (`WRITE_NOT_VERIFIED` if it differs).
|
|
179
190
|
- **No hidden vendor execution.** The FactoryTalk View Studio handoff returns a manual import plan; it
|
|
180
191
|
does not run a vendor utility.
|
|
181
192
|
- **Coverage is stated.** Every result names what it cannot establish, including whether online logic
|
package/cordis.patch.yml
CHANGED
|
@@ -6,13 +6,14 @@
|
|
|
6
6
|
#
|
|
7
7
|
# The optional parts are the row's config, not separate rows:
|
|
8
8
|
#
|
|
9
|
-
# l5x → editing, studio, live (all
|
|
10
|
-
# ftview → edit, studio
|
|
11
|
-
# mwi → edit
|
|
9
|
+
# l5x → editing, studio, live, allowWrites (all on by default)
|
|
10
|
+
# ftview → edit, studio (both on by default)
|
|
11
|
+
# mwi → edit (on by default)
|
|
12
|
+
# optix → authoring, destructive, invoke, preview (all on by default)
|
|
12
13
|
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
14
|
+
# Every surface ships on so a fresh install can use the full plugin. Turn one
|
|
15
|
+
# off from the row's Configure page when the profile is read-only or the request
|
|
16
|
+
# budget is tight; the schemas are sent on every request.
|
|
16
17
|
#
|
|
17
18
|
# The patch only ever inserts. It must never target a row another bundle owns:
|
|
18
19
|
# a profile without that row makes composition fail ("patch: entry ... not
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve one value from a plugin row's config.
|
|
3
|
+
*
|
|
4
|
+
* A field marked `.volatile()` in the `Config` schema arrives as a live
|
|
5
|
+
* reference ({ get() }) rather than as the value itself: schemastery wraps it
|
|
6
|
+
* with `createVolatile`, so `config.edit` is the reference, not `true`. Reading
|
|
7
|
+
* the value directly made every volatile switch look off to `apply()` — the row
|
|
8
|
+
* mounted its read surface and never its edit surface, no matter what the
|
|
9
|
+
* profile patch or the settings page said.
|
|
10
|
+
*
|
|
11
|
+
* Keep this tolerance in one place so every product row resolves its switches
|
|
12
|
+
* the same way, and so a plain value (tests, older hosts) still works.
|
|
13
|
+
*
|
|
14
|
+
* @module dsh-engineering-config
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Read a config field that may be a volatile reference.
|
|
19
|
+
*
|
|
20
|
+
* @param input - the raw field, a reference, or undefined.
|
|
21
|
+
* @param fallback - value to use when the field is absent.
|
|
22
|
+
* @returns the current value, or the fallback.
|
|
23
|
+
*/
|
|
24
|
+
export function resolve(input, fallback) {
|
|
25
|
+
const current = input && typeof input.get === 'function' ? input.get() : input
|
|
26
|
+
return current === undefined ? fallback : current
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Read a boolean switch.
|
|
31
|
+
*
|
|
32
|
+
* @param input - the raw field, a reference, or undefined.
|
|
33
|
+
* @param fallback - value to use when the field is absent or not a boolean.
|
|
34
|
+
* @returns the boolean value.
|
|
35
|
+
*/
|
|
36
|
+
export function flag(input, fallback = false) {
|
|
37
|
+
const current = resolve(input, fallback)
|
|
38
|
+
return typeof current === 'boolean' ? current : fallback
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Read a string-list field.
|
|
43
|
+
*
|
|
44
|
+
* @param input - the raw field, a reference, or undefined.
|
|
45
|
+
* @returns the list, or an empty list.
|
|
46
|
+
*/
|
|
47
|
+
export function list(input) {
|
|
48
|
+
const current = resolve(input, [])
|
|
49
|
+
return Array.isArray(current) ? current : []
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Read a string field.
|
|
54
|
+
*
|
|
55
|
+
* @param input - the raw field, a reference, or undefined.
|
|
56
|
+
* @param fallback - value to use when the field is absent or not a string.
|
|
57
|
+
* @returns the string value.
|
|
58
|
+
*/
|
|
59
|
+
export function text(input, fallback = '') {
|
|
60
|
+
const current = resolve(input, fallback)
|
|
61
|
+
return typeof current === 'string' ? current : fallback
|
|
62
|
+
}
|
package/entries/ftview.js
CHANGED
|
@@ -10,16 +10,17 @@ import * as read from '../vendor/ftview/lib/index.js'
|
|
|
10
10
|
import * as skill from '../vendor/ftview/lib/skill.js'
|
|
11
11
|
import * as edit from '../vendor/ftview/lib/edit.js'
|
|
12
12
|
import * as studio from '../vendor/ftview/lib/studio.js'
|
|
13
|
+
import { flag } from './config.js'
|
|
13
14
|
|
|
14
15
|
export const name = 'engineering-ftview'
|
|
15
16
|
/** Union of the parts' requirements: the read entry owns the view service. */
|
|
16
17
|
export const inject = ['tools', 'fs']
|
|
17
18
|
|
|
18
19
|
export const Config = z.object({
|
|
19
|
-
edit: z.boolean().default(true).description(
|
|
20
|
+
edit: z.boolean().default(true).volatile().description(
|
|
20
21
|
'Staged display and HMI-tag edits, validated then written to a new export folder.',
|
|
21
22
|
),
|
|
22
|
-
studio: z.boolean().default(true).description(
|
|
23
|
+
studio: z.boolean().default(true).volatile().description(
|
|
23
24
|
'FactoryTalk View Studio discovery and the manual import plan. Runs no vendor utility.',
|
|
24
25
|
),
|
|
25
26
|
})
|
|
@@ -32,6 +33,6 @@ export const Config = z.object({
|
|
|
32
33
|
export function apply(ctx, config = {}) {
|
|
33
34
|
ctx.plugin(read)
|
|
34
35
|
ctx.plugin(skill)
|
|
35
|
-
if (config.edit
|
|
36
|
-
if (config.studio
|
|
36
|
+
if (flag(config.edit, true)) ctx.plugin(edit)
|
|
37
|
+
if (flag(config.studio, true)) ctx.plugin(studio)
|
|
37
38
|
}
|
package/entries/l5x.js
CHANGED
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
* The Studio 5000 L5X product row: one switch for the whole L5X surface.
|
|
3
3
|
*
|
|
4
4
|
* The parts are the vendored entries; this module mounts them, so the Plugins
|
|
5
|
-
* page shows one row per product instead of one per surface. The
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* page shows one row per product instead of one per surface. The expensive
|
|
6
|
+
* surfaces are on by default and can be switched off from this row's config form,
|
|
7
|
+
* which is the same decision the old separate rows encoded — just reachable
|
|
8
|
+
* from the product row instead of from the list.
|
|
9
|
+
*
|
|
10
|
+
* `allowWrites` is forwarded into the live entry, not consumed here: the write
|
|
11
|
+
* tools refuse from inside that entry, so the switch and the per-call approval
|
|
12
|
+
* both live where the controller traffic happens.
|
|
9
13
|
*/
|
|
10
14
|
import z from '@deepseek-ai/schemastery'
|
|
11
15
|
import * as read from '../vendor/l5x/lib/index.js'
|
|
@@ -13,32 +17,76 @@ import * as skill from '../vendor/l5x/lib/skill.js'
|
|
|
13
17
|
import * as editing from '../vendor/l5x/lib/editing.js'
|
|
14
18
|
import * as studio from '../vendor/l5x/lib/studio.js'
|
|
15
19
|
import * as live from '../vendor/l5x/lib/live.js'
|
|
20
|
+
import { flag, list } from './config.js'
|
|
16
21
|
|
|
17
22
|
export const name = 'engineering-l5x'
|
|
18
23
|
/** Union of the parts' requirements: the read entry owns the project service. */
|
|
19
24
|
export const inject = ['tools', 'fs']
|
|
20
25
|
|
|
21
26
|
export const Config = z.object({
|
|
22
|
-
editing: z.boolean().default(
|
|
23
|
-
'Nine staged draft tools (draft_rung, draft_apply, ...).
|
|
27
|
+
editing: z.boolean().default(true).volatile().description(
|
|
28
|
+
'Nine staged draft tools (draft_rung, draft_apply, ...). On by default; a read-only profile can switch it off to drop these schemas.',
|
|
24
29
|
),
|
|
25
|
-
studio: z.boolean().default(
|
|
30
|
+
studio: z.boolean().default(true).volatile().description(
|
|
26
31
|
'Logix Designer SDK and supervised controller tools. Needs Studio 5000 with the SDK service installed.',
|
|
27
32
|
),
|
|
28
|
-
live: z.boolean().default(
|
|
29
|
-
'EtherNet/IP polling and
|
|
33
|
+
live: z.boolean().default(true).volatile().description(
|
|
34
|
+
'EtherNet/IP surface: polling, batch reads, discovery, controller clock and trends. Needs a reachable controller address.',
|
|
35
|
+
),
|
|
36
|
+
allowWrites: z.boolean().default(true).volatile().description(
|
|
37
|
+
'Permit the two live write tools (tag, wall clock). Each write still needs human approval for that exact operation, and only applies while live is on.',
|
|
38
|
+
),
|
|
39
|
+
allowedAddresses: z.array(z.string()).default([]).volatile().description(
|
|
40
|
+
'Optional IPv4 allowlist for live reads, writes and discovery. Empty permits any explicit address.',
|
|
30
41
|
),
|
|
31
42
|
})
|
|
32
43
|
|
|
33
44
|
/**
|
|
34
45
|
* Mount the L5X surface.
|
|
35
46
|
* @param ctx - plugin context.
|
|
36
|
-
* @param config - the
|
|
47
|
+
* @param config - the optional surfaces, all off unless enabled.
|
|
37
48
|
*/
|
|
38
49
|
export function apply(ctx, config = {}) {
|
|
39
50
|
ctx.plugin(read)
|
|
40
51
|
ctx.plugin(skill)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
52
|
+
// Volatile-only config changes never re-run apply(): the loader commits the
|
|
53
|
+
// new values and emits loader/volatile-update. Remount the optional surfaces
|
|
54
|
+
// from that event so a switch flipped in the row page takes effect at once.
|
|
55
|
+
let editingFiber
|
|
56
|
+
let studioFiber
|
|
57
|
+
let liveFiber
|
|
58
|
+
let liveSignature = ''
|
|
59
|
+
const sync = () => {
|
|
60
|
+
const wantEditing = flag(config.editing)
|
|
61
|
+
if (wantEditing && editingFiber === undefined) editingFiber = ctx.plugin(editing)
|
|
62
|
+
else if (!wantEditing && editingFiber !== undefined) {
|
|
63
|
+
void editingFiber.dispose()
|
|
64
|
+
editingFiber = undefined
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const wantStudio = flag(config.studio)
|
|
68
|
+
if (wantStudio && studioFiber === undefined) studioFiber = ctx.plugin(studio)
|
|
69
|
+
else if (!wantStudio && studioFiber !== undefined) {
|
|
70
|
+
void studioFiber.dispose()
|
|
71
|
+
studioFiber = undefined
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const wantLive = flag(config.live)
|
|
75
|
+
const addresses = list(config.allowedAddresses)
|
|
76
|
+
const signature = wantLive ? JSON.stringify([flag(config.allowWrites), addresses]) : ''
|
|
77
|
+
if (wantLive && (liveFiber === undefined || signature !== liveSignature)) {
|
|
78
|
+
if (liveFiber !== undefined) void liveFiber.dispose()
|
|
79
|
+
liveFiber = ctx.plugin(live, {
|
|
80
|
+
allowWrites: flag(config.allowWrites),
|
|
81
|
+
...(addresses.length === 0 ? {} : { allowedAddresses: addresses }),
|
|
82
|
+
})
|
|
83
|
+
liveSignature = signature
|
|
84
|
+
} else if (!wantLive && liveFiber !== undefined) {
|
|
85
|
+
void liveFiber.dispose()
|
|
86
|
+
liveFiber = undefined
|
|
87
|
+
liveSignature = ''
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
sync()
|
|
91
|
+
ctx.on('loader/volatile-update', sync)
|
|
44
92
|
}
|
package/entries/mwi.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* The MotionWorks IEC product row: one switch for the session, read, verify and
|
|
3
3
|
* edit surfaces plus the skill.
|
|
4
4
|
*
|
|
5
|
-
* Editing is the largest schema set in the bundle
|
|
6
|
-
* row's config form
|
|
5
|
+
* Editing is the largest schema set in the bundle; it ships on by default and
|
|
6
|
+
* the row's config form can switch it off for a read-only profile.
|
|
7
7
|
*/
|
|
8
8
|
import z from '@deepseek-ai/schemastery'
|
|
9
9
|
import * as session from '../vendor/mwi/lib/index.js'
|
|
@@ -11,26 +11,46 @@ import * as read from '../vendor/mwi/lib/read.js'
|
|
|
11
11
|
import * as skill from '../vendor/mwi/lib/skill.js'
|
|
12
12
|
import * as verify from '../vendor/mwi/lib/verify.js'
|
|
13
13
|
import * as edit from '../vendor/mwi/lib/edit.js'
|
|
14
|
+
import { configureWorkspace } from '../vendor/mwi/lib/session/workspace.js'
|
|
15
|
+
import { flag, text } from './config.js'
|
|
14
16
|
|
|
15
17
|
export const name = 'engineering-mwi'
|
|
16
18
|
/** The whole product needs the tool registry. */
|
|
17
19
|
export const inject = ['tools']
|
|
18
20
|
|
|
19
21
|
export const Config = z.object({
|
|
20
|
-
|
|
21
|
-
'
|
|
22
|
+
workspace: z.string().default('').volatile().description(
|
|
23
|
+
'Absolute workspace root for MotionWorks projects. Empty uses the session directory when the host passes one, then the mwi.workspace marker in the profile.',
|
|
24
|
+
),
|
|
25
|
+
edit: z.boolean().default(true).volatile().description(
|
|
26
|
+
'Seven staged edit tools (code, declarations, structure, blocks, POU packages). On by default; switch it off to drop the largest schemas in the bundle.',
|
|
22
27
|
),
|
|
23
28
|
})
|
|
24
29
|
|
|
25
30
|
/**
|
|
26
31
|
* Mount the MotionWorks IEC surface.
|
|
27
32
|
* @param ctx - plugin context.
|
|
28
|
-
* @param config - the optional edit surface
|
|
33
|
+
* @param config - the workspace root and the optional edit surface.
|
|
29
34
|
*/
|
|
30
35
|
export function apply(ctx, config = {}) {
|
|
31
36
|
ctx.plugin(session)
|
|
32
37
|
ctx.plugin(read)
|
|
33
38
|
ctx.plugin(skill)
|
|
34
39
|
ctx.plugin(verify)
|
|
35
|
-
|
|
40
|
+
// The loader commits volatile-only config changes into the live references
|
|
41
|
+
// and emits `loader/volatile-update` instead of re-running apply(). The edit
|
|
42
|
+
// switch must mount and unmount the edit tools in place, or the page would
|
|
43
|
+
// claim the tools are on while the request still lacks them.
|
|
44
|
+
let mounted
|
|
45
|
+
const sync = () => {
|
|
46
|
+
configureWorkspace(text(config.workspace))
|
|
47
|
+
const wanted = flag(config.edit)
|
|
48
|
+
if (wanted && mounted === undefined) mounted = ctx.plugin(edit)
|
|
49
|
+
else if (!wanted && mounted !== undefined) {
|
|
50
|
+
void mounted.dispose()
|
|
51
|
+
mounted = undefined
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
sync()
|
|
55
|
+
ctx.on('loader/volatile-update', sync)
|
|
36
56
|
}
|