@aryacode/dsh-engineering 0.0.0-stage → 0.4.0
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 +128 -0
- package/LICENSE +21 -0
- package/README.md +230 -2
- package/cordis.patch.yml +123 -0
- package/lib/client.js +3448 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +9 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +94 -3
- package/vendor/ftview/README.md +55 -0
- package/vendor/ftview/SKILL.md +74 -0
- package/vendor/ftview/lib/checks.d.ts +27 -0
- package/vendor/ftview/lib/checks.js +39 -0
- package/vendor/ftview/lib/core.d.ts +208 -0
- package/vendor/ftview/lib/core.js +160 -0
- package/vendor/ftview/lib/edit/drafts.d.ts +49 -0
- package/vendor/ftview/lib/edit/drafts.js +84 -0
- package/vendor/ftview/lib/edit/operations.d.ts +62 -0
- package/vendor/ftview/lib/edit/operations.js +126 -0
- package/vendor/ftview/lib/edit/prepare.d.ts +38 -0
- package/vendor/ftview/lib/edit/prepare.js +133 -0
- package/vendor/ftview/lib/edit/tools.d.ts +25 -0
- package/vendor/ftview/lib/edit/tools.js +198 -0
- package/vendor/ftview/lib/edit.d.ts +30 -0
- package/vendor/ftview/lib/edit.js +38 -0
- package/vendor/ftview/lib/index.d.ts +31 -0
- package/vendor/ftview/lib/index.js +36 -0
- package/vendor/ftview/lib/model.d.ts +80 -0
- package/vendor/ftview/lib/model.js +267 -0
- package/vendor/ftview/lib/session.d.ts +48 -0
- package/vendor/ftview/lib/session.js +98 -0
- package/vendor/ftview/lib/skill.d.ts +29 -0
- package/vendor/ftview/lib/skill.js +43 -0
- package/vendor/ftview/lib/studio/discover.d.ts +36 -0
- package/vendor/ftview/lib/studio/discover.js +87 -0
- package/vendor/ftview/lib/studio/preflight.d.ts +51 -0
- package/vendor/ftview/lib/studio/preflight.js +64 -0
- package/vendor/ftview/lib/studio/tools.d.ts +15 -0
- package/vendor/ftview/lib/studio/tools.js +83 -0
- package/vendor/ftview/lib/studio.d.ts +30 -0
- package/vendor/ftview/lib/studio.js +37 -0
- package/vendor/ftview/lib/tools.d.ts +14 -0
- package/vendor/ftview/lib/tools.js +202 -0
- package/vendor/l5x/README.md +62 -0
- package/vendor/l5x/SKILL.md +81 -0
- package/vendor/l5x/lib/approvals.d.ts +50 -0
- package/vendor/l5x/lib/approvals.js +93 -0
- package/vendor/l5x/lib/client.js +412 -0
- package/vendor/l5x/lib/client.js.map +1 -0
- package/vendor/l5x/lib/core/errors.d.ts +38 -0
- package/vendor/l5x/lib/core/errors.js +48 -0
- package/vendor/l5x/lib/core/params.d.ts +49 -0
- package/vendor/l5x/lib/core/params.js +39 -0
- package/vendor/l5x/lib/core/result.d.ts +46 -0
- package/vendor/l5x/lib/core/result.js +21 -0
- package/vendor/l5x/lib/core/tool.d.ts +102 -0
- package/vendor/l5x/lib/core/tool.js +19 -0
- package/vendor/l5x/lib/drafts.d.ts +66 -0
- package/vendor/l5x/lib/drafts.js +98 -0
- package/vendor/l5x/lib/editing.d.ts +30 -0
- package/vendor/l5x/lib/editing.js +42 -0
- package/vendor/l5x/lib/engine/acd-edit.d.ts +13 -0
- package/vendor/l5x/lib/engine/acd-edit.js +115 -0
- package/vendor/l5x/lib/engine/analysis.d.ts +22 -0
- package/vendor/l5x/lib/engine/analysis.js +258 -0
- package/vendor/l5x/lib/engine/capabilities.d.ts +9 -0
- package/vendor/l5x/lib/engine/capabilities.js +40 -0
- package/vendor/l5x/lib/engine/change-set.d.ts +122 -0
- package/vendor/l5x/lib/engine/change-set.js +446 -0
- package/vendor/l5x/lib/engine/configuration.d.ts +21 -0
- package/vendor/l5x/lib/engine/configuration.js +42 -0
- package/vendor/l5x/lib/engine/details.d.ts +47 -0
- package/vendor/l5x/lib/engine/details.js +173 -0
- package/vendor/l5x/lib/engine/direct-polling.d.ts +91 -0
- package/vendor/l5x/lib/engine/direct-polling.js +193 -0
- package/vendor/l5x/lib/engine/download-review.d.ts +15 -0
- package/vendor/l5x/lib/engine/download-review.js +63 -0
- package/vendor/l5x/lib/engine/logic-syntax.d.ts +60 -0
- package/vendor/l5x/lib/engine/logic-syntax.js +237 -0
- package/vendor/l5x/lib/engine/observations.d.ts +41 -0
- package/vendor/l5x/lib/engine/observations.js +67 -0
- package/vendor/l5x/lib/engine/project-analysis.d.ts +131 -0
- package/vendor/l5x/lib/engine/project-analysis.js +314 -0
- package/vendor/l5x/lib/engine/review-evidence.d.ts +8 -0
- package/vendor/l5x/lib/engine/review-evidence.js +49 -0
- package/vendor/l5x/lib/engine/review.d.ts +18 -0
- package/vendor/l5x/lib/engine/review.js +123 -0
- package/vendor/l5x/lib/engine/studio-sdk.d.ts +101 -0
- package/vendor/l5x/lib/engine/studio-sdk.js +571 -0
- package/vendor/l5x/lib/engine/tag-resolution.d.ts +20 -0
- package/vendor/l5x/lib/engine/tag-resolution.js +169 -0
- package/vendor/l5x/lib/engine/usage.d.ts +16 -0
- package/vendor/l5x/lib/engine/usage.js +92 -0
- package/vendor/l5x/lib/engine/xml-regions.d.ts +23 -0
- package/vendor/l5x/lib/engine/xml-regions.js +77 -0
- package/vendor/l5x/lib/fs.d.ts +17 -0
- package/vendor/l5x/lib/fs.js +36 -0
- package/vendor/l5x/lib/index.d.ts +36 -0
- package/vendor/l5x/lib/index.js +42 -0
- package/vendor/l5x/lib/live.d.ts +48 -0
- package/vendor/l5x/lib/live.js +48 -0
- package/vendor/l5x/lib/model/aois.d.ts +39 -0
- package/vendor/l5x/lib/model/aois.js +112 -0
- package/vendor/l5x/lib/model/errors.d.ts +15 -0
- package/vendor/l5x/lib/model/errors.js +18 -0
- package/vendor/l5x/lib/model/index.d.ts +20 -0
- package/vendor/l5x/lib/model/index.js +19 -0
- package/vendor/l5x/lib/model/module.d.ts +37 -0
- package/vendor/l5x/lib/model/module.js +54 -0
- package/vendor/l5x/lib/model/modules.d.ts +24 -0
- package/vendor/l5x/lib/model/modules.js +55 -0
- package/vendor/l5x/lib/model/parse.d.ts +32 -0
- package/vendor/l5x/lib/model/parse.js +116 -0
- package/vendor/l5x/lib/model/project.d.ts +15 -0
- package/vendor/l5x/lib/model/project.js +31 -0
- package/vendor/l5x/lib/model/routines.d.ts +71 -0
- package/vendor/l5x/lib/model/routines.js +183 -0
- package/vendor/l5x/lib/model/tags.d.ts +51 -0
- package/vendor/l5x/lib/model/tags.js +119 -0
- package/vendor/l5x/lib/model/types.d.ts +304 -0
- package/vendor/l5x/lib/model/types.js +12 -0
- package/vendor/l5x/lib/model/udts.d.ts +34 -0
- package/vendor/l5x/lib/model/udts.js +81 -0
- package/vendor/l5x/lib/model/xml.d.ts +139 -0
- package/vendor/l5x/lib/model/xml.js +291 -0
- package/vendor/l5x/lib/model/xref.d.ts +28 -0
- package/vendor/l5x/lib/model/xref.js +154 -0
- package/vendor/l5x/lib/session.d.ts +119 -0
- package/vendor/l5x/lib/session.js +236 -0
- package/vendor/l5x/lib/skill.d.ts +30 -0
- package/vendor/l5x/lib/skill.js +44 -0
- package/vendor/l5x/lib/studio-state.d.ts +77 -0
- package/vendor/l5x/lib/studio-state.js +79 -0
- package/vendor/l5x/lib/studio.d.ts +29 -0
- package/vendor/l5x/lib/studio.js +40 -0
- package/vendor/l5x/lib/tools/checks.d.ts +19 -0
- package/vendor/l5x/lib/tools/checks.js +140 -0
- package/vendor/l5x/lib/tools/common.d.ts +41 -0
- package/vendor/l5x/lib/tools/common.js +84 -0
- package/vendor/l5x/lib/tools/controller.d.ts +21 -0
- package/vendor/l5x/lib/tools/controller.js +170 -0
- package/vendor/l5x/lib/tools/drafts.d.ts +23 -0
- package/vendor/l5x/lib/tools/drafts.js +270 -0
- package/vendor/l5x/lib/tools/live.d.ts +21 -0
- package/vendor/l5x/lib/tools/live.js +175 -0
- package/vendor/l5x/lib/tools/read.d.ts +19 -0
- package/vendor/l5x/lib/tools/read.js +245 -0
- package/vendor/l5x/lib/tools/references.d.ts +20 -0
- package/vendor/l5x/lib/tools/references.js +269 -0
- package/vendor/l5x/lib/tools/studio.d.ts +21 -0
- package/vendor/l5x/lib/tools/studio.js +193 -0
- package/vendor/l5x/poll-worker.mjs +77 -0
- package/vendor/l5x/studio-bridge/NuGet.Config +1 -0
- package/vendor/l5x/studio-bridge/Program.cs +304 -0
- package/vendor/l5x/studio-bridge/StudioBridge.csproj +11 -0
- package/vendor/mwi/README.md +60 -0
- package/vendor/mwi/SKILL.md +87 -0
- package/vendor/mwi/bridge/README.md +8 -0
- package/vendor/mwi/bridge/mw_bridge.ps1 +2763 -0
- package/vendor/mwi/bridge/sdk-interop-importer.cs +30 -0
- package/vendor/mwi/bridge/sdk-variable-reader.cs +22 -0
- package/vendor/mwi/bridge/start_bridge.cmd +21 -0
- package/vendor/mwi/bridge/watch_dialogs.cmd +13 -0
- package/vendor/mwi/bridge/watch_dialogs.ps1 +153 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/__init__.py +14 -0
- 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/vendor/mwi/code/engine/motionworks_iec_mcp/block_interfaces.py +275 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/build.py +339 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/capture.py +448 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/cfb.py +765 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/com.py +268 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/datatypes.py +204 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/declarations.py +399 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/descriptions.py +30 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/eip.py +292 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/errors.py +36 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/graphical_listing.py +208 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/grid.py +227 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/ide.py +317 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/iec.py +317 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/installed_help.py +151 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/knowledge.py +218 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/libraries.py +250 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/manuals.py +520 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/mwt_bind.py +133 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/navigation.py +44 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/pou_writer.py +1547 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/program_checks.py +360 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/project.py +704 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/reference_data/catalog.json +672 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/reference_data/patterns.json +86 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/restore.py +208 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/server.py +1913 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/snapshot.py +138 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/st_comments.py +25 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/staging.py +179 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/stlint.py +676 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/structure.py +98 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/task_bindings.py +68 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/tasks.py +162 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/transaction.py +157 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/tree.py +563 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/tree_writer.py +790 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/uia.py +465 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/validation.py +41 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/variable_edit.py +183 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/variables.py +472 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/workflow.py +130 -0
- package/vendor/mwi/code/engine/motionworks_iec_mcp/writer.py +666 -0
- package/vendor/mwi/code/mw_code.py +1258 -0
- package/vendor/mwi/legacy/edit-session.js +50 -0
- package/vendor/mwi/legacy/fb-insertion.js +74 -0
- package/vendor/mwi/legacy/native-code.js +83 -0
- package/vendor/mwi/legacy/native-groups.js +75 -0
- package/vendor/mwi/legacy/native-structure.js +143 -0
- package/vendor/mwi/legacy/native-variables.js +77 -0
- package/vendor/mwi/legacy/pou-conversion.js +47 -0
- package/vendor/mwi/legacy/pou-package.js +66 -0
- package/vendor/mwi/lib/core/bridge.d.ts +71 -0
- package/vendor/mwi/lib/core/bridge.js +53 -0
- package/vendor/mwi/lib/core/code-engine.d.ts +47 -0
- package/vendor/mwi/lib/core/code-engine.js +109 -0
- package/vendor/mwi/lib/core/errors.d.ts +37 -0
- package/vendor/mwi/lib/core/errors.js +47 -0
- package/vendor/mwi/lib/core/params.d.ts +52 -0
- package/vendor/mwi/lib/core/params.js +46 -0
- package/vendor/mwi/lib/core/ps-bridge.d.ts +62 -0
- package/vendor/mwi/lib/core/ps-bridge.js +127 -0
- package/vendor/mwi/lib/core/result.d.ts +45 -0
- package/vendor/mwi/lib/core/result.js +20 -0
- package/vendor/mwi/lib/core/tool.d.ts +80 -0
- package/vendor/mwi/lib/core/tool.js +55 -0
- package/vendor/mwi/lib/edit/compare.d.ts +33 -0
- package/vendor/mwi/lib/edit/compare.js +70 -0
- package/vendor/mwi/lib/edit.d.ts +20 -0
- package/vendor/mwi/lib/edit.js +32 -0
- package/vendor/mwi/lib/index.d.ts +21 -0
- package/vendor/mwi/lib/index.js +33 -0
- package/vendor/mwi/lib/read/service.d.ts +117 -0
- package/vendor/mwi/lib/read/service.js +229 -0
- package/vendor/mwi/lib/read.d.ts +21 -0
- package/vendor/mwi/lib/read.js +33 -0
- package/vendor/mwi/lib/session/project.d.ts +34 -0
- package/vendor/mwi/lib/session/project.js +54 -0
- package/vendor/mwi/lib/session/service.d.ts +167 -0
- package/vendor/mwi/lib/session/service.js +566 -0
- package/vendor/mwi/lib/session/stage.d.ts +84 -0
- package/vendor/mwi/lib/session/stage.js +187 -0
- package/vendor/mwi/lib/session/workspace.d.ts +52 -0
- package/vendor/mwi/lib/session/workspace.js +90 -0
- package/vendor/mwi/lib/skill.d.ts +36 -0
- package/vendor/mwi/lib/skill.js +56 -0
- package/vendor/mwi/lib/tools/edit.d.ts +20 -0
- package/vendor/mwi/lib/tools/edit.js +286 -0
- package/vendor/mwi/lib/tools/read.d.ts +19 -0
- package/vendor/mwi/lib/tools/read.js +161 -0
- package/vendor/mwi/lib/tools/session.d.ts +20 -0
- package/vendor/mwi/lib/tools/session.js +166 -0
- package/vendor/mwi/lib/tools/verify.d.ts +19 -0
- package/vendor/mwi/lib/tools/verify.js +85 -0
- package/vendor/mwi/lib/verify.d.ts +17 -0
- package/vendor/mwi/lib/verify.js +29 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The PowerShell transport for the MotionWorks COM bridge.
|
|
3
|
+
*
|
|
4
|
+
* The bridge is a 32-bit PowerShell process that polls a request file and writes
|
|
5
|
+
* one response file. Files, not stdio: a confined harness cannot open named
|
|
6
|
+
* pipes, and `Mwt.exe` is a 32-bit LocalServer32 that a 64-bit client cannot
|
|
7
|
+
* instantiate at all.
|
|
8
|
+
*
|
|
9
|
+
* This client owns the mailbox, serializes requests, starts the bridge once and
|
|
10
|
+
* maps the bridge's answer onto the typed bridge contract.
|
|
11
|
+
*
|
|
12
|
+
* @module dsh-engineering-mwi/core/ps-bridge
|
|
13
|
+
*/
|
|
14
|
+
import { spawn } from 'node:child_process';
|
|
15
|
+
import { randomUUID } from 'node:crypto';
|
|
16
|
+
import { mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
17
|
+
import { tmpdir } from 'node:os';
|
|
18
|
+
import { join } from 'node:path';
|
|
19
|
+
import { MwiError } from "./errors.js";
|
|
20
|
+
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
21
|
+
/**
|
|
22
|
+
* A serialized client over the file mailbox, matching the legacy bridge protocol.
|
|
23
|
+
*/
|
|
24
|
+
export class PowerShellBridgeTransport {
|
|
25
|
+
options;
|
|
26
|
+
ipcDir;
|
|
27
|
+
requestPath;
|
|
28
|
+
responsePath;
|
|
29
|
+
startupMs;
|
|
30
|
+
spawned = false;
|
|
31
|
+
queue = Promise.resolve();
|
|
32
|
+
/**
|
|
33
|
+
* @param options - Bridge location and workspace authorization.
|
|
34
|
+
*/
|
|
35
|
+
constructor(options) {
|
|
36
|
+
this.options = options;
|
|
37
|
+
this.ipcDir = options.ipcDir ?? join(tmpdir(), '@aryacode/dsh-engineering-mwi', `${process.pid}-${randomUUID()}`);
|
|
38
|
+
this.requestPath = join(this.ipcDir, 'req.json');
|
|
39
|
+
this.responsePath = join(this.ipcDir, 'res.json');
|
|
40
|
+
this.startupMs = options.startupMs ?? 12_000;
|
|
41
|
+
}
|
|
42
|
+
/** The mailbox this client owns; exposed for diagnostics. */
|
|
43
|
+
get mailbox() {
|
|
44
|
+
return this.ipcDir;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Send one request and wait for its response.
|
|
48
|
+
*
|
|
49
|
+
* @param request - Operation and arguments.
|
|
50
|
+
* @param timeoutMs - Hard operation budget.
|
|
51
|
+
* @param signal - Cancellation owned by the caller.
|
|
52
|
+
* @returns The bridge's answer.
|
|
53
|
+
*/
|
|
54
|
+
async send(request, timeoutMs, signal) {
|
|
55
|
+
const pending = this.queue.then(async () => await this.exchange(request, timeoutMs, signal));
|
|
56
|
+
this.queue = pending.catch(() => undefined);
|
|
57
|
+
return await pending;
|
|
58
|
+
}
|
|
59
|
+
/** Run one request after the previous one settled. */
|
|
60
|
+
async exchange(request, timeoutMs, signal) {
|
|
61
|
+
mkdirSync(this.ipcDir, { recursive: true });
|
|
62
|
+
this.spawnBridge();
|
|
63
|
+
const id = randomUUID();
|
|
64
|
+
const payload = {
|
|
65
|
+
id,
|
|
66
|
+
verb: request.operation,
|
|
67
|
+
...request.arguments,
|
|
68
|
+
workspace: this.options.workspace,
|
|
69
|
+
stage_root: this.options.stageRoot,
|
|
70
|
+
};
|
|
71
|
+
const staged = `${this.requestPath}.tmp`;
|
|
72
|
+
rmSync(this.responsePath, { force: true });
|
|
73
|
+
writeFileSync(staged, JSON.stringify(payload), 'utf8');
|
|
74
|
+
renameSync(staged, this.requestPath);
|
|
75
|
+
const deadline = Date.now() + Math.max(timeoutMs, this.startupMs);
|
|
76
|
+
while (Date.now() < deadline) {
|
|
77
|
+
if (signal?.aborted === true)
|
|
78
|
+
throw new MwiError('ABORTED', 'The MotionWorks call was cancelled.', 'Retry when the IDE is idle.');
|
|
79
|
+
const response = this.readResponse();
|
|
80
|
+
if (response !== undefined && response.id === id) {
|
|
81
|
+
return response.ok
|
|
82
|
+
? { ok: true, result: response.data }
|
|
83
|
+
: { ok: false, error: { code: this.codeOf(response), message: response.error ?? 'The MotionWorks bridge refused the request.' } };
|
|
84
|
+
}
|
|
85
|
+
await sleep(120);
|
|
86
|
+
}
|
|
87
|
+
throw new MwiError('BRIDGE_TIMEOUT', `The MotionWorks bridge did not answer ${request.operation} within ${Math.round(timeoutMs / 1000)} s.`, 'Inspect the IDE: a modal dialog or a busy project blocks the bridge. Resolve it, then retry.');
|
|
88
|
+
}
|
|
89
|
+
/** Read the current response file, ignoring partial or malformed writes. */
|
|
90
|
+
readResponse() {
|
|
91
|
+
try {
|
|
92
|
+
const parsed = JSON.parse(readFileSync(this.responsePath, 'utf8'));
|
|
93
|
+
return typeof parsed?.id === 'string' ? parsed : undefined;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/** Map a bridge refusal to a stable code the model can act on. */
|
|
100
|
+
codeOf(response) {
|
|
101
|
+
const text = response.error ?? '';
|
|
102
|
+
if (/no running MotionWorks IDE/i.test(text))
|
|
103
|
+
return 'IDE_NOT_RUNNING';
|
|
104
|
+
if (/REFUSED/i.test(text))
|
|
105
|
+
return 'REFUSED';
|
|
106
|
+
if (/unknown verb/i.test(text))
|
|
107
|
+
return 'BRIDGE_UNKNOWN_OPERATION';
|
|
108
|
+
return 'BRIDGE_FAILED';
|
|
109
|
+
}
|
|
110
|
+
/** Start the 32-bit bridge once per client. */
|
|
111
|
+
spawnBridge() {
|
|
112
|
+
if (this.spawned)
|
|
113
|
+
return;
|
|
114
|
+
const launcher = join(this.options.bridgeDir, 'start_bridge.cmd');
|
|
115
|
+
const child = spawn('cmd.exe', ['/c', launcher], {
|
|
116
|
+
env: { ...process.env, MW_BRIDGE_DIR: this.ipcDir },
|
|
117
|
+
windowsHide: true,
|
|
118
|
+
detached: true,
|
|
119
|
+
stdio: 'ignore',
|
|
120
|
+
});
|
|
121
|
+
child.on('error', () => {
|
|
122
|
+
this.spawned = false;
|
|
123
|
+
});
|
|
124
|
+
child.unref();
|
|
125
|
+
this.spawned = true;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The model-facing success document.
|
|
3
|
+
*
|
|
4
|
+
* Every tool answers with a summary first and concrete next calls last, as in
|
|
5
|
+
* the other engineering products.
|
|
6
|
+
*
|
|
7
|
+
* @module dsh-engineering-mwi/core/result
|
|
8
|
+
*/
|
|
9
|
+
/** One call the reader can make next, with the reason it is useful. */
|
|
10
|
+
export interface NextStep {
|
|
11
|
+
/** Tool name registered by this plugin. */
|
|
12
|
+
readonly tool: string;
|
|
13
|
+
/** Why this call answers the current question. */
|
|
14
|
+
readonly why: string;
|
|
15
|
+
/** Arguments worth passing; omitted when the tool needs none. */
|
|
16
|
+
readonly args?: Readonly<Record<string, unknown>>;
|
|
17
|
+
}
|
|
18
|
+
/** How much of the requested question the answer actually covers. */
|
|
19
|
+
export interface Coverage {
|
|
20
|
+
/** Whether the requested scope was answered in full. */
|
|
21
|
+
readonly complete: boolean;
|
|
22
|
+
/** What this answer cannot establish, named rather than implied. */
|
|
23
|
+
readonly unverified: readonly string[];
|
|
24
|
+
}
|
|
25
|
+
/** A successful tool answer. */
|
|
26
|
+
export interface Success<T> {
|
|
27
|
+
/** One sentence the reader can act on. */
|
|
28
|
+
readonly summary: string;
|
|
29
|
+
/** Tool-specific payload. */
|
|
30
|
+
readonly data: T;
|
|
31
|
+
/** Present when the answer has limits worth stating. */
|
|
32
|
+
readonly coverage?: Coverage;
|
|
33
|
+
/** Concrete next calls, most useful first. */
|
|
34
|
+
readonly next: readonly NextStep[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Build a success document.
|
|
38
|
+
*
|
|
39
|
+
* @param summary - One sentence naming what was read.
|
|
40
|
+
* @param data - Tool-specific payload.
|
|
41
|
+
* @param next - Concrete next calls; may be empty when the answer is terminal.
|
|
42
|
+
* @param coverage - Limits of the answer, when it has any.
|
|
43
|
+
* @returns The document the tool returns.
|
|
44
|
+
*/
|
|
45
|
+
export declare function success<T>(summary: string, data: T, next?: readonly NextStep[], coverage?: Coverage): Success<T>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The model-facing success document.
|
|
3
|
+
*
|
|
4
|
+
* Every tool answers with a summary first and concrete next calls last, as in
|
|
5
|
+
* the other engineering products.
|
|
6
|
+
*
|
|
7
|
+
* @module dsh-engineering-mwi/core/result
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Build a success document.
|
|
11
|
+
*
|
|
12
|
+
* @param summary - One sentence naming what was read.
|
|
13
|
+
* @param data - Tool-specific payload.
|
|
14
|
+
* @param next - Concrete next calls; may be empty when the answer is terminal.
|
|
15
|
+
* @param coverage - Limits of the answer, when it has any.
|
|
16
|
+
* @returns The document the tool returns.
|
|
17
|
+
*/
|
|
18
|
+
export function success(summary, data, next = [], coverage) {
|
|
19
|
+
return coverage === undefined ? { summary, data, next } : { summary, data, coverage, next };
|
|
20
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tool contract shared by every MWI row.
|
|
3
|
+
*
|
|
4
|
+
* The legacy surface declared 63 tools in one file. The redesign keeps one
|
|
5
|
+
* builder here so every tool carries a description, described parameters, the
|
|
6
|
+
* canonical output declaration and the shared failure document.
|
|
7
|
+
*
|
|
8
|
+
* @module dsh-engineering-mwi/core/tool
|
|
9
|
+
*/
|
|
10
|
+
import type { Parameters } from './params.ts';
|
|
11
|
+
/** One content block the registry renders for the model. */
|
|
12
|
+
export interface TextBlock {
|
|
13
|
+
readonly type: 'text';
|
|
14
|
+
readonly text: string;
|
|
15
|
+
}
|
|
16
|
+
/** The canonical output declaration every tool must carry. */
|
|
17
|
+
export interface ToolOutput {
|
|
18
|
+
readonly schema: {
|
|
19
|
+
readonly type: 'object';
|
|
20
|
+
readonly additionalProperties: boolean;
|
|
21
|
+
};
|
|
22
|
+
render(args: unknown, value: unknown): readonly TextBlock[];
|
|
23
|
+
}
|
|
24
|
+
/** The execution context a tool receives from the registry. */
|
|
25
|
+
export interface ToolExec {
|
|
26
|
+
readonly signal?: AbortSignal;
|
|
27
|
+
readonly cwd?: string;
|
|
28
|
+
/** The calling chat; staged project handles are scoped to it. */
|
|
29
|
+
readonly chat?: object;
|
|
30
|
+
readonly sessionId?: string;
|
|
31
|
+
readonly agent?: unknown;
|
|
32
|
+
}
|
|
33
|
+
/** A registered tool. */
|
|
34
|
+
export interface ToolDefinition {
|
|
35
|
+
readonly name: string;
|
|
36
|
+
readonly description: string;
|
|
37
|
+
readonly parameters: Parameters;
|
|
38
|
+
readonly output: ToolOutput;
|
|
39
|
+
execute(args: Readonly<Record<string, unknown>>, exec?: ToolExec): Promise<unknown>;
|
|
40
|
+
}
|
|
41
|
+
/** The registry service. */
|
|
42
|
+
export interface ToolRegistry {
|
|
43
|
+
register(definition: ToolDefinition): unknown;
|
|
44
|
+
}
|
|
45
|
+
/** One tool body, before the shared output and failure document are attached. */
|
|
46
|
+
export interface ToolSpec {
|
|
47
|
+
readonly name: string;
|
|
48
|
+
readonly description: string;
|
|
49
|
+
readonly parameters: Parameters;
|
|
50
|
+
run(args: Readonly<Record<string, unknown>>, exec: ToolExec): Promise<unknown>;
|
|
51
|
+
}
|
|
52
|
+
/** The services a composition must provide before an MWI row loads. */
|
|
53
|
+
export interface PluginContext {
|
|
54
|
+
readonly tools: ToolRegistry;
|
|
55
|
+
readonly logger?: {
|
|
56
|
+
info?(message: string): void;
|
|
57
|
+
warn?(message: string): void;
|
|
58
|
+
};
|
|
59
|
+
/** Register a service other entries in the same composition can consume. */
|
|
60
|
+
provide?(name: string, value: unknown): void;
|
|
61
|
+
/** Read a service another entry in the same composition provided. */
|
|
62
|
+
get?(name: string): unknown;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Render one tool answer as pretty JSON.
|
|
66
|
+
*
|
|
67
|
+
* @param _args - Accepted arguments; unused by this renderer.
|
|
68
|
+
* @param value - The validated canonical value.
|
|
69
|
+
* @returns One text block.
|
|
70
|
+
*/
|
|
71
|
+
export declare function jsonText(_args: unknown, value: unknown): readonly TextBlock[];
|
|
72
|
+
/**
|
|
73
|
+
* Attach the canonical output declaration and the shared failure handling.
|
|
74
|
+
*
|
|
75
|
+
* @param spec - The tool body and its metadata.
|
|
76
|
+
* @returns The definition the registry receives.
|
|
77
|
+
*/
|
|
78
|
+
export declare function tool(spec: ToolSpec): ToolDefinition;
|
|
79
|
+
/** Read one required string argument, or refuse with a fix. */
|
|
80
|
+
export declare function requiredString(args: Readonly<Record<string, unknown>>, name: string): string;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tool contract shared by every MWI row.
|
|
3
|
+
*
|
|
4
|
+
* The legacy surface declared 63 tools in one file. The redesign keeps one
|
|
5
|
+
* builder here so every tool carries a description, described parameters, the
|
|
6
|
+
* canonical output declaration and the shared failure document.
|
|
7
|
+
*
|
|
8
|
+
* @module dsh-engineering-mwi/core/tool
|
|
9
|
+
*/
|
|
10
|
+
import { errorEnvelope, MwiError } from "./errors.js";
|
|
11
|
+
/**
|
|
12
|
+
* Render one tool answer as pretty JSON.
|
|
13
|
+
*
|
|
14
|
+
* @param _args - Accepted arguments; unused by this renderer.
|
|
15
|
+
* @param value - The validated canonical value.
|
|
16
|
+
* @returns One text block.
|
|
17
|
+
*/
|
|
18
|
+
export function jsonText(_args, value) {
|
|
19
|
+
return [{ type: 'text', text: JSON.stringify(value, undefined, 2) }];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Attach the canonical output declaration and the shared failure handling.
|
|
23
|
+
*
|
|
24
|
+
* @param spec - The tool body and its metadata.
|
|
25
|
+
* @returns The definition the registry receives.
|
|
26
|
+
*/
|
|
27
|
+
export function tool(spec) {
|
|
28
|
+
if (!spec.name.startsWith('mw_')) {
|
|
29
|
+
throw new Error(`MWI tool ${spec.name} must use the mw_ prefix so the motionworks-iec switch governs it`);
|
|
30
|
+
}
|
|
31
|
+
if (spec.description.trim() === '')
|
|
32
|
+
throw new Error(`MWI tool ${spec.name} has no description`);
|
|
33
|
+
return {
|
|
34
|
+
name: spec.name,
|
|
35
|
+
description: spec.description,
|
|
36
|
+
parameters: spec.parameters,
|
|
37
|
+
output: { schema: { type: 'object', additionalProperties: true }, render: jsonText },
|
|
38
|
+
async execute(args, exec) {
|
|
39
|
+
try {
|
|
40
|
+
return await spec.run(args, exec ?? {});
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
return errorEnvelope(error);
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** Read one required string argument, or refuse with a fix. */
|
|
49
|
+
export function requiredString(args, name) {
|
|
50
|
+
const value = args[name];
|
|
51
|
+
if (typeof value !== 'string' || value.trim() === '') {
|
|
52
|
+
throw new MwiError('INVALID_ARGUMENT', `Argument ${name} must be a non-empty string.`, `Pass ${name} as a non-empty string; see the tool description for its expected value.`);
|
|
53
|
+
}
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compare saved declarations with the native rows an edit expects.
|
|
3
|
+
*
|
|
4
|
+
* The evidence names the exact fields that differ; it never repairs a mismatch.
|
|
5
|
+
*
|
|
6
|
+
* @module dsh-engineering-mwi/edit/compare
|
|
7
|
+
*/
|
|
8
|
+
/** The declaration fields a saved/native comparison covers. */
|
|
9
|
+
export declare const VARIABLE_FIELDS: readonly ["name", "type", "section", "group", "address", "initial_value", "description"];
|
|
10
|
+
/** A comparison outcome the edit helpers accept. */
|
|
11
|
+
export interface VariableComparison {
|
|
12
|
+
readonly accepted: boolean;
|
|
13
|
+
readonly evidence_kind: 'saved-declarations-only';
|
|
14
|
+
readonly expected_count: number;
|
|
15
|
+
readonly saved_count: number;
|
|
16
|
+
readonly missing: string[];
|
|
17
|
+
readonly unexpected: string[];
|
|
18
|
+
readonly changed: {
|
|
19
|
+
name: string;
|
|
20
|
+
fields: string[];
|
|
21
|
+
expected: Record<string, null | string>;
|
|
22
|
+
saved: Record<string, null | string>;
|
|
23
|
+
}[];
|
|
24
|
+
readonly errors: string[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Compare expected and actual declaration rows by upper-cased name.
|
|
28
|
+
*
|
|
29
|
+
* @param expected - Declarations the edit expects after the mutation.
|
|
30
|
+
* @param actual - Declarations read back from the saved project.
|
|
31
|
+
* @returns The comparison with every difference named.
|
|
32
|
+
*/
|
|
33
|
+
export declare function compareVariables(expected: readonly Record<string, unknown>[], actual: readonly Record<string, unknown>[]): VariableComparison;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compare saved declarations with the native rows an edit expects.
|
|
3
|
+
*
|
|
4
|
+
* The evidence names the exact fields that differ; it never repairs a mismatch.
|
|
5
|
+
*
|
|
6
|
+
* @module dsh-engineering-mwi/edit/compare
|
|
7
|
+
*/
|
|
8
|
+
/** The declaration fields a saved/native comparison covers. */
|
|
9
|
+
export const VARIABLE_FIELDS = ['name', 'type', 'section', 'group', 'address', 'initial_value', 'description'];
|
|
10
|
+
/**
|
|
11
|
+
* Compare expected and actual declaration rows by upper-cased name.
|
|
12
|
+
*
|
|
13
|
+
* @param expected - Declarations the edit expects after the mutation.
|
|
14
|
+
* @param actual - Declarations read back from the saved project.
|
|
15
|
+
* @returns The comparison with every difference named.
|
|
16
|
+
*/
|
|
17
|
+
export function compareVariables(expected, actual) {
|
|
18
|
+
const errors = [];
|
|
19
|
+
const index = (rows, label, strict) => {
|
|
20
|
+
if (!Array.isArray(rows))
|
|
21
|
+
throw new Error(`${label} declarations must be an array`);
|
|
22
|
+
const result = new Map();
|
|
23
|
+
for (const row of rows) {
|
|
24
|
+
if (typeof row?.name !== 'string' || row.name.trim() === '')
|
|
25
|
+
throw new Error(`${label}: missing variable name`);
|
|
26
|
+
if (strict && VARIABLE_FIELDS.some(field => !Object.hasOwn(row, field) || (row[field] !== null && typeof row[field] !== 'string'))) {
|
|
27
|
+
throw new Error(`${label}: supply every declaration field for ${String(row.name)}, including explicit nulls`);
|
|
28
|
+
}
|
|
29
|
+
const key = row.name.toUpperCase();
|
|
30
|
+
if (result.has(key))
|
|
31
|
+
errors.push(`${label}: duplicate variable ${String(row.name)}`);
|
|
32
|
+
result.set(key, row);
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
35
|
+
};
|
|
36
|
+
const wanted = index(expected, 'expected', true);
|
|
37
|
+
const found = index(actual, 'saved', false);
|
|
38
|
+
const missing = [];
|
|
39
|
+
const unexpected = [];
|
|
40
|
+
const changed = [];
|
|
41
|
+
for (const [key, row] of wanted) {
|
|
42
|
+
const saved = found.get(key);
|
|
43
|
+
if (saved === undefined) {
|
|
44
|
+
missing.push(String(row.name));
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const fields = VARIABLE_FIELDS.filter(field => (row[field] ?? null) !== (saved[field] ?? null));
|
|
48
|
+
if (fields.length > 0) {
|
|
49
|
+
changed.push({
|
|
50
|
+
name: String(row.name),
|
|
51
|
+
fields: [...fields],
|
|
52
|
+
expected: Object.fromEntries(fields.map(field => [field, (row[field] ?? null)])),
|
|
53
|
+
saved: Object.fromEntries(fields.map(field => [field, (saved[field] ?? null)])),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
for (const [key, row] of found)
|
|
58
|
+
if (!wanted.has(key))
|
|
59
|
+
unexpected.push(String(row.name));
|
|
60
|
+
return {
|
|
61
|
+
accepted: errors.length === 0 && missing.length === 0 && unexpected.length === 0 && changed.length === 0,
|
|
62
|
+
evidence_kind: 'saved-declarations-only',
|
|
63
|
+
expected_count: expected.length,
|
|
64
|
+
saved_count: actual.length,
|
|
65
|
+
missing,
|
|
66
|
+
unexpected,
|
|
67
|
+
changed,
|
|
68
|
+
errors,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `mwi-edit` entry: staged edits, validation and apply.
|
|
3
|
+
*
|
|
4
|
+
* Off by default. The row writes only the staged project and verifies that
|
|
5
|
+
* unrelated saved and native state did not change.
|
|
6
|
+
*
|
|
7
|
+
* @module dsh-engineering-mwi/edit
|
|
8
|
+
*/
|
|
9
|
+
import type { PluginContext } from './core/tool.ts';
|
|
10
|
+
/** Plugin name in a composition. */
|
|
11
|
+
export declare const name = "mwi-edit";
|
|
12
|
+
/** Services this plugin cannot register without. */
|
|
13
|
+
export declare const inject: readonly ["tools"];
|
|
14
|
+
/**
|
|
15
|
+
* Register the edit tools.
|
|
16
|
+
*
|
|
17
|
+
* @param ctx - Plugin context with the tool registry.
|
|
18
|
+
*/
|
|
19
|
+
export declare function apply(ctx: PluginContext): void;
|
|
20
|
+
export { editTools } from './tools/edit.ts';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `mwi-edit` entry: staged edits, validation and apply.
|
|
3
|
+
*
|
|
4
|
+
* Off by default. The row writes only the staged project and verifies that
|
|
5
|
+
* unrelated saved and native state did not change.
|
|
6
|
+
*
|
|
7
|
+
* @module dsh-engineering-mwi/edit
|
|
8
|
+
*/
|
|
9
|
+
import { editTools } from "./tools/edit.js";
|
|
10
|
+
/** Plugin name in a composition. */
|
|
11
|
+
export const name = 'mwi-edit';
|
|
12
|
+
/** Services this plugin cannot register without. */
|
|
13
|
+
export const inject = ['tools'];
|
|
14
|
+
/**
|
|
15
|
+
* Register the edit tools.
|
|
16
|
+
*
|
|
17
|
+
* @param ctx - Plugin context with the tool registry.
|
|
18
|
+
*/
|
|
19
|
+
export function apply(ctx) {
|
|
20
|
+
if (process.platform !== 'win32') {
|
|
21
|
+
try {
|
|
22
|
+
ctx.logger?.info?.(`mwi-edit: skipped because this host is ${process.platform}; MotionWorks IEC requires Windows.`);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
// A logger that refuses must not turn an unsupported host into a crash.
|
|
26
|
+
}
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
for (const definition of editTools())
|
|
30
|
+
ctx.tools.register(definition);
|
|
31
|
+
}
|
|
32
|
+
export { editTools } from "./tools/edit.js";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `mwi-session` entry: project discovery and IDE lifecycle.
|
|
3
|
+
*
|
|
4
|
+
* The row registers on Windows only; the IDE is a Windows application and the
|
|
5
|
+
* bridge cannot exist elsewhere.
|
|
6
|
+
*
|
|
7
|
+
* @module dsh-engineering-mwi
|
|
8
|
+
*/
|
|
9
|
+
import type { PluginContext } from './core/tool.ts';
|
|
10
|
+
/** Plugin name in a composition. */
|
|
11
|
+
export declare const name = "mwi-session";
|
|
12
|
+
/** Services this plugin cannot register without. */
|
|
13
|
+
export declare const inject: readonly ["tools"];
|
|
14
|
+
/**
|
|
15
|
+
* Register the session tools.
|
|
16
|
+
*
|
|
17
|
+
* @param ctx - Plugin context with the tool registry.
|
|
18
|
+
*/
|
|
19
|
+
export declare function apply(ctx: PluginContext): void;
|
|
20
|
+
export { sessionTools } from './tools/session.ts';
|
|
21
|
+
export { PowerShellSessionRuntime, runtimeFor } from './session/service.ts';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `mwi-session` entry: project discovery and IDE lifecycle.
|
|
3
|
+
*
|
|
4
|
+
* The row registers on Windows only; the IDE is a Windows application and the
|
|
5
|
+
* bridge cannot exist elsewhere.
|
|
6
|
+
*
|
|
7
|
+
* @module dsh-engineering-mwi
|
|
8
|
+
*/
|
|
9
|
+
import { sessionTools } from "./tools/session.js";
|
|
10
|
+
/** Plugin name in a composition. */
|
|
11
|
+
export const name = 'mwi-session';
|
|
12
|
+
/** Services this plugin cannot register without. */
|
|
13
|
+
export const inject = ['tools'];
|
|
14
|
+
/**
|
|
15
|
+
* Register the session tools.
|
|
16
|
+
*
|
|
17
|
+
* @param ctx - Plugin context with the tool registry.
|
|
18
|
+
*/
|
|
19
|
+
export function apply(ctx) {
|
|
20
|
+
if (process.platform !== 'win32') {
|
|
21
|
+
try {
|
|
22
|
+
ctx.logger?.info?.(`mwi-session: skipped because this host is ${process.platform}; MotionWorks IEC requires Windows.`);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
// A logger that refuses must not turn an unsupported host into a crash.
|
|
26
|
+
}
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
for (const definition of sessionTools())
|
|
30
|
+
ctx.tools.register(definition);
|
|
31
|
+
}
|
|
32
|
+
export { sessionTools } from "./tools/session.js";
|
|
33
|
+
export { PowerShellSessionRuntime, runtimeFor } from "./session/service.js";
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read the saved project through the code engine.
|
|
3
|
+
*
|
|
4
|
+
* These reads describe the saved project, not the loaded IDE instance. Anything
|
|
5
|
+
* that needs the live object model says so in its coverage.
|
|
6
|
+
*
|
|
7
|
+
* @module dsh-engineering-mwi/read/service
|
|
8
|
+
*/
|
|
9
|
+
import type { EngineResult } from '../core/code-engine.ts';
|
|
10
|
+
import type { ProjectRef } from '../session/project.ts';
|
|
11
|
+
/** The engine surface the reads use; injectable for tests. */
|
|
12
|
+
export interface ReadEngine {
|
|
13
|
+
run(verb: string, request: Readonly<Record<string, unknown>>, timeoutMs?: number, signal?: AbortSignal): Promise<EngineResult>;
|
|
14
|
+
}
|
|
15
|
+
/** One row in a listing. */
|
|
16
|
+
export interface ListRow {
|
|
17
|
+
readonly name: string;
|
|
18
|
+
readonly [field: string]: unknown;
|
|
19
|
+
}
|
|
20
|
+
/** One literal match in a POU body. */
|
|
21
|
+
export interface CodeMatch {
|
|
22
|
+
readonly pou: string;
|
|
23
|
+
readonly line: number;
|
|
24
|
+
readonly text: string;
|
|
25
|
+
}
|
|
26
|
+
/** Kinds `mw_list` can enumerate. */
|
|
27
|
+
export declare const LIST_KINDS: readonly ["pou", "variable", "global", "type", "task", "library"];
|
|
28
|
+
/** Kinds `mw_get` can read. */
|
|
29
|
+
export declare const GET_KINDS: readonly ["pou", "type", "task", "block", "eip"];
|
|
30
|
+
/** The saved-project read service. */
|
|
31
|
+
export declare class ReadService {
|
|
32
|
+
private readonly engine;
|
|
33
|
+
/**
|
|
34
|
+
* @param engine - Code engine over the project files.
|
|
35
|
+
*/
|
|
36
|
+
constructor(engine: ReadEngine);
|
|
37
|
+
/** Confirm the engine can read one project. */
|
|
38
|
+
workflow(project: ProjectRef): Promise<EngineResult>;
|
|
39
|
+
/**
|
|
40
|
+
* List one kind.
|
|
41
|
+
*
|
|
42
|
+
* @param project - Project to read.
|
|
43
|
+
* @param kind - Listing kind.
|
|
44
|
+
* @param options - Filter, paging and the POU for variable reads.
|
|
45
|
+
* @returns Rows and the total before paging.
|
|
46
|
+
*/
|
|
47
|
+
list(project: ProjectRef, kind: string, options?: {
|
|
48
|
+
filter?: string;
|
|
49
|
+
offset?: number;
|
|
50
|
+
limit?: number;
|
|
51
|
+
pou?: string;
|
|
52
|
+
}): Promise<{
|
|
53
|
+
rows: ListRow[];
|
|
54
|
+
total: number;
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Read one component by name.
|
|
58
|
+
*
|
|
59
|
+
* @param project - Project to read.
|
|
60
|
+
* @param kind - Component kind.
|
|
61
|
+
* @param name - Exact name.
|
|
62
|
+
* @param library - Library name for a block interface.
|
|
63
|
+
* @returns The component document.
|
|
64
|
+
*/
|
|
65
|
+
get(project: ProjectRef, kind: string, name: string, library?: string): Promise<EngineResult>;
|
|
66
|
+
/**
|
|
67
|
+
* Search POU bodies for literal text.
|
|
68
|
+
*
|
|
69
|
+
* @param project - Project to read.
|
|
70
|
+
* @param query - Case-insensitive literal text.
|
|
71
|
+
* @param limit - Most matches.
|
|
72
|
+
* @returns Matches in project order.
|
|
73
|
+
*/
|
|
74
|
+
search(project: ProjectRef, query: string, limit?: number): Promise<{
|
|
75
|
+
matches: CodeMatch[];
|
|
76
|
+
truncated: boolean;
|
|
77
|
+
scanned: number;
|
|
78
|
+
}>;
|
|
79
|
+
/**
|
|
80
|
+
* Find a symbol in POU bodies.
|
|
81
|
+
*
|
|
82
|
+
* @param project - Project to read.
|
|
83
|
+
* @param symbol - Declared or written symbol name.
|
|
84
|
+
* @param limit - Most matches.
|
|
85
|
+
* @returns Matches with the line that contains them.
|
|
86
|
+
*/
|
|
87
|
+
references(project: ProjectRef, symbol: string, limit?: number): Promise<{
|
|
88
|
+
matches: CodeMatch[];
|
|
89
|
+
truncated: boolean;
|
|
90
|
+
scanned: number;
|
|
91
|
+
}>;
|
|
92
|
+
/**
|
|
93
|
+
* Run the static review surface.
|
|
94
|
+
*
|
|
95
|
+
* @param project - Project to read.
|
|
96
|
+
* @param options - Optional POU and proposed body.
|
|
97
|
+
* @returns Workflow, validation, unsupported-construct and program-review results.
|
|
98
|
+
*/
|
|
99
|
+
review(project: ProjectRef, options?: {
|
|
100
|
+
pou?: string;
|
|
101
|
+
body?: string;
|
|
102
|
+
}): Promise<Record<string, unknown>>;
|
|
103
|
+
/**
|
|
104
|
+
* Search help and reviewed references.
|
|
105
|
+
*
|
|
106
|
+
* @param project - Project used for the workspace cache.
|
|
107
|
+
* @param source - Help source: help, manual, reference or pattern.
|
|
108
|
+
* @param query - Search term; omitted lists what is available.
|
|
109
|
+
* @param limit - Most rows.
|
|
110
|
+
* @returns The engine document with its source named.
|
|
111
|
+
*/
|
|
112
|
+
help(project: ProjectRef, source: string, query: string | undefined, limit?: number): Promise<EngineResult>;
|
|
113
|
+
/** Read every POU body, capped. */
|
|
114
|
+
private bodies;
|
|
115
|
+
/** Map one kind to rows. */
|
|
116
|
+
private rows;
|
|
117
|
+
}
|