@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.
Files changed (284) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/LICENSE +21 -0
  3. package/README.md +230 -2
  4. package/cordis.patch.yml +123 -0
  5. package/lib/client.js +3448 -0
  6. package/lib/index.d.ts +2 -0
  7. package/lib/index.js +9 -0
  8. package/locale/en.json +6 -0
  9. package/locale/zh.json +6 -0
  10. package/package.json +94 -3
  11. package/vendor/ftview/README.md +55 -0
  12. package/vendor/ftview/SKILL.md +74 -0
  13. package/vendor/ftview/lib/checks.d.ts +27 -0
  14. package/vendor/ftview/lib/checks.js +39 -0
  15. package/vendor/ftview/lib/core.d.ts +208 -0
  16. package/vendor/ftview/lib/core.js +160 -0
  17. package/vendor/ftview/lib/edit/drafts.d.ts +49 -0
  18. package/vendor/ftview/lib/edit/drafts.js +84 -0
  19. package/vendor/ftview/lib/edit/operations.d.ts +62 -0
  20. package/vendor/ftview/lib/edit/operations.js +126 -0
  21. package/vendor/ftview/lib/edit/prepare.d.ts +38 -0
  22. package/vendor/ftview/lib/edit/prepare.js +133 -0
  23. package/vendor/ftview/lib/edit/tools.d.ts +25 -0
  24. package/vendor/ftview/lib/edit/tools.js +198 -0
  25. package/vendor/ftview/lib/edit.d.ts +30 -0
  26. package/vendor/ftview/lib/edit.js +38 -0
  27. package/vendor/ftview/lib/index.d.ts +31 -0
  28. package/vendor/ftview/lib/index.js +36 -0
  29. package/vendor/ftview/lib/model.d.ts +80 -0
  30. package/vendor/ftview/lib/model.js +267 -0
  31. package/vendor/ftview/lib/session.d.ts +48 -0
  32. package/vendor/ftview/lib/session.js +98 -0
  33. package/vendor/ftview/lib/skill.d.ts +29 -0
  34. package/vendor/ftview/lib/skill.js +43 -0
  35. package/vendor/ftview/lib/studio/discover.d.ts +36 -0
  36. package/vendor/ftview/lib/studio/discover.js +87 -0
  37. package/vendor/ftview/lib/studio/preflight.d.ts +51 -0
  38. package/vendor/ftview/lib/studio/preflight.js +64 -0
  39. package/vendor/ftview/lib/studio/tools.d.ts +15 -0
  40. package/vendor/ftview/lib/studio/tools.js +83 -0
  41. package/vendor/ftview/lib/studio.d.ts +30 -0
  42. package/vendor/ftview/lib/studio.js +37 -0
  43. package/vendor/ftview/lib/tools.d.ts +14 -0
  44. package/vendor/ftview/lib/tools.js +202 -0
  45. package/vendor/l5x/README.md +62 -0
  46. package/vendor/l5x/SKILL.md +81 -0
  47. package/vendor/l5x/lib/approvals.d.ts +50 -0
  48. package/vendor/l5x/lib/approvals.js +93 -0
  49. package/vendor/l5x/lib/client.js +412 -0
  50. package/vendor/l5x/lib/client.js.map +1 -0
  51. package/vendor/l5x/lib/core/errors.d.ts +38 -0
  52. package/vendor/l5x/lib/core/errors.js +48 -0
  53. package/vendor/l5x/lib/core/params.d.ts +49 -0
  54. package/vendor/l5x/lib/core/params.js +39 -0
  55. package/vendor/l5x/lib/core/result.d.ts +46 -0
  56. package/vendor/l5x/lib/core/result.js +21 -0
  57. package/vendor/l5x/lib/core/tool.d.ts +102 -0
  58. package/vendor/l5x/lib/core/tool.js +19 -0
  59. package/vendor/l5x/lib/drafts.d.ts +66 -0
  60. package/vendor/l5x/lib/drafts.js +98 -0
  61. package/vendor/l5x/lib/editing.d.ts +30 -0
  62. package/vendor/l5x/lib/editing.js +42 -0
  63. package/vendor/l5x/lib/engine/acd-edit.d.ts +13 -0
  64. package/vendor/l5x/lib/engine/acd-edit.js +115 -0
  65. package/vendor/l5x/lib/engine/analysis.d.ts +22 -0
  66. package/vendor/l5x/lib/engine/analysis.js +258 -0
  67. package/vendor/l5x/lib/engine/capabilities.d.ts +9 -0
  68. package/vendor/l5x/lib/engine/capabilities.js +40 -0
  69. package/vendor/l5x/lib/engine/change-set.d.ts +122 -0
  70. package/vendor/l5x/lib/engine/change-set.js +446 -0
  71. package/vendor/l5x/lib/engine/configuration.d.ts +21 -0
  72. package/vendor/l5x/lib/engine/configuration.js +42 -0
  73. package/vendor/l5x/lib/engine/details.d.ts +47 -0
  74. package/vendor/l5x/lib/engine/details.js +173 -0
  75. package/vendor/l5x/lib/engine/direct-polling.d.ts +91 -0
  76. package/vendor/l5x/lib/engine/direct-polling.js +193 -0
  77. package/vendor/l5x/lib/engine/download-review.d.ts +15 -0
  78. package/vendor/l5x/lib/engine/download-review.js +63 -0
  79. package/vendor/l5x/lib/engine/logic-syntax.d.ts +60 -0
  80. package/vendor/l5x/lib/engine/logic-syntax.js +237 -0
  81. package/vendor/l5x/lib/engine/observations.d.ts +41 -0
  82. package/vendor/l5x/lib/engine/observations.js +67 -0
  83. package/vendor/l5x/lib/engine/project-analysis.d.ts +131 -0
  84. package/vendor/l5x/lib/engine/project-analysis.js +314 -0
  85. package/vendor/l5x/lib/engine/review-evidence.d.ts +8 -0
  86. package/vendor/l5x/lib/engine/review-evidence.js +49 -0
  87. package/vendor/l5x/lib/engine/review.d.ts +18 -0
  88. package/vendor/l5x/lib/engine/review.js +123 -0
  89. package/vendor/l5x/lib/engine/studio-sdk.d.ts +101 -0
  90. package/vendor/l5x/lib/engine/studio-sdk.js +571 -0
  91. package/vendor/l5x/lib/engine/tag-resolution.d.ts +20 -0
  92. package/vendor/l5x/lib/engine/tag-resolution.js +169 -0
  93. package/vendor/l5x/lib/engine/usage.d.ts +16 -0
  94. package/vendor/l5x/lib/engine/usage.js +92 -0
  95. package/vendor/l5x/lib/engine/xml-regions.d.ts +23 -0
  96. package/vendor/l5x/lib/engine/xml-regions.js +77 -0
  97. package/vendor/l5x/lib/fs.d.ts +17 -0
  98. package/vendor/l5x/lib/fs.js +36 -0
  99. package/vendor/l5x/lib/index.d.ts +36 -0
  100. package/vendor/l5x/lib/index.js +42 -0
  101. package/vendor/l5x/lib/live.d.ts +48 -0
  102. package/vendor/l5x/lib/live.js +48 -0
  103. package/vendor/l5x/lib/model/aois.d.ts +39 -0
  104. package/vendor/l5x/lib/model/aois.js +112 -0
  105. package/vendor/l5x/lib/model/errors.d.ts +15 -0
  106. package/vendor/l5x/lib/model/errors.js +18 -0
  107. package/vendor/l5x/lib/model/index.d.ts +20 -0
  108. package/vendor/l5x/lib/model/index.js +19 -0
  109. package/vendor/l5x/lib/model/module.d.ts +37 -0
  110. package/vendor/l5x/lib/model/module.js +54 -0
  111. package/vendor/l5x/lib/model/modules.d.ts +24 -0
  112. package/vendor/l5x/lib/model/modules.js +55 -0
  113. package/vendor/l5x/lib/model/parse.d.ts +32 -0
  114. package/vendor/l5x/lib/model/parse.js +116 -0
  115. package/vendor/l5x/lib/model/project.d.ts +15 -0
  116. package/vendor/l5x/lib/model/project.js +31 -0
  117. package/vendor/l5x/lib/model/routines.d.ts +71 -0
  118. package/vendor/l5x/lib/model/routines.js +183 -0
  119. package/vendor/l5x/lib/model/tags.d.ts +51 -0
  120. package/vendor/l5x/lib/model/tags.js +119 -0
  121. package/vendor/l5x/lib/model/types.d.ts +304 -0
  122. package/vendor/l5x/lib/model/types.js +12 -0
  123. package/vendor/l5x/lib/model/udts.d.ts +34 -0
  124. package/vendor/l5x/lib/model/udts.js +81 -0
  125. package/vendor/l5x/lib/model/xml.d.ts +139 -0
  126. package/vendor/l5x/lib/model/xml.js +291 -0
  127. package/vendor/l5x/lib/model/xref.d.ts +28 -0
  128. package/vendor/l5x/lib/model/xref.js +154 -0
  129. package/vendor/l5x/lib/session.d.ts +119 -0
  130. package/vendor/l5x/lib/session.js +236 -0
  131. package/vendor/l5x/lib/skill.d.ts +30 -0
  132. package/vendor/l5x/lib/skill.js +44 -0
  133. package/vendor/l5x/lib/studio-state.d.ts +77 -0
  134. package/vendor/l5x/lib/studio-state.js +79 -0
  135. package/vendor/l5x/lib/studio.d.ts +29 -0
  136. package/vendor/l5x/lib/studio.js +40 -0
  137. package/vendor/l5x/lib/tools/checks.d.ts +19 -0
  138. package/vendor/l5x/lib/tools/checks.js +140 -0
  139. package/vendor/l5x/lib/tools/common.d.ts +41 -0
  140. package/vendor/l5x/lib/tools/common.js +84 -0
  141. package/vendor/l5x/lib/tools/controller.d.ts +21 -0
  142. package/vendor/l5x/lib/tools/controller.js +170 -0
  143. package/vendor/l5x/lib/tools/drafts.d.ts +23 -0
  144. package/vendor/l5x/lib/tools/drafts.js +270 -0
  145. package/vendor/l5x/lib/tools/live.d.ts +21 -0
  146. package/vendor/l5x/lib/tools/live.js +175 -0
  147. package/vendor/l5x/lib/tools/read.d.ts +19 -0
  148. package/vendor/l5x/lib/tools/read.js +245 -0
  149. package/vendor/l5x/lib/tools/references.d.ts +20 -0
  150. package/vendor/l5x/lib/tools/references.js +269 -0
  151. package/vendor/l5x/lib/tools/studio.d.ts +21 -0
  152. package/vendor/l5x/lib/tools/studio.js +193 -0
  153. package/vendor/l5x/poll-worker.mjs +77 -0
  154. package/vendor/l5x/studio-bridge/NuGet.Config +1 -0
  155. package/vendor/l5x/studio-bridge/Program.cs +304 -0
  156. package/vendor/l5x/studio-bridge/StudioBridge.csproj +11 -0
  157. package/vendor/mwi/README.md +60 -0
  158. package/vendor/mwi/SKILL.md +87 -0
  159. package/vendor/mwi/bridge/README.md +8 -0
  160. package/vendor/mwi/bridge/mw_bridge.ps1 +2763 -0
  161. package/vendor/mwi/bridge/sdk-interop-importer.cs +30 -0
  162. package/vendor/mwi/bridge/sdk-variable-reader.cs +22 -0
  163. package/vendor/mwi/bridge/start_bridge.cmd +21 -0
  164. package/vendor/mwi/bridge/watch_dialogs.cmd +13 -0
  165. package/vendor/mwi/bridge/watch_dialogs.ps1 +153 -0
  166. package/vendor/mwi/code/engine/motionworks_iec_mcp/__init__.py +14 -0
  167. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/__init__.cpython-312.pyc +0 -0
  168. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/block_interfaces.cpython-312.pyc +0 -0
  169. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/cfb.cpython-312.pyc +0 -0
  170. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/datatypes.cpython-312.pyc +0 -0
  171. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/declarations.cpython-312.pyc +0 -0
  172. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/errors.cpython-312.pyc +0 -0
  173. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/graphical_listing.cpython-312.pyc +0 -0
  174. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/grid.cpython-312.pyc +0 -0
  175. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/knowledge.cpython-312.pyc +0 -0
  176. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/mwt_bind.cpython-312.pyc +0 -0
  177. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/navigation.cpython-312.pyc +0 -0
  178. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/program_checks.cpython-312.pyc +0 -0
  179. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/project.cpython-312.pyc +0 -0
  180. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/staging.cpython-312.pyc +0 -0
  181. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/structure.cpython-312.pyc +0 -0
  182. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/task_bindings.cpython-312.pyc +0 -0
  183. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/tasks.cpython-312.pyc +0 -0
  184. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/tree.cpython-312.pyc +0 -0
  185. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/validation.cpython-312.pyc +0 -0
  186. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/variable_edit.cpython-312.pyc +0 -0
  187. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/variables.cpython-312.pyc +0 -0
  188. package/vendor/mwi/code/engine/motionworks_iec_mcp/__pycache__/workflow.cpython-312.pyc +0 -0
  189. package/vendor/mwi/code/engine/motionworks_iec_mcp/block_interfaces.py +275 -0
  190. package/vendor/mwi/code/engine/motionworks_iec_mcp/build.py +339 -0
  191. package/vendor/mwi/code/engine/motionworks_iec_mcp/capture.py +448 -0
  192. package/vendor/mwi/code/engine/motionworks_iec_mcp/cfb.py +765 -0
  193. package/vendor/mwi/code/engine/motionworks_iec_mcp/com.py +268 -0
  194. package/vendor/mwi/code/engine/motionworks_iec_mcp/datatypes.py +204 -0
  195. package/vendor/mwi/code/engine/motionworks_iec_mcp/declarations.py +399 -0
  196. package/vendor/mwi/code/engine/motionworks_iec_mcp/descriptions.py +30 -0
  197. package/vendor/mwi/code/engine/motionworks_iec_mcp/eip.py +292 -0
  198. package/vendor/mwi/code/engine/motionworks_iec_mcp/errors.py +36 -0
  199. package/vendor/mwi/code/engine/motionworks_iec_mcp/graphical_listing.py +208 -0
  200. package/vendor/mwi/code/engine/motionworks_iec_mcp/grid.py +227 -0
  201. package/vendor/mwi/code/engine/motionworks_iec_mcp/ide.py +317 -0
  202. package/vendor/mwi/code/engine/motionworks_iec_mcp/iec.py +317 -0
  203. package/vendor/mwi/code/engine/motionworks_iec_mcp/installed_help.py +151 -0
  204. package/vendor/mwi/code/engine/motionworks_iec_mcp/knowledge.py +218 -0
  205. package/vendor/mwi/code/engine/motionworks_iec_mcp/libraries.py +250 -0
  206. package/vendor/mwi/code/engine/motionworks_iec_mcp/manuals.py +520 -0
  207. package/vendor/mwi/code/engine/motionworks_iec_mcp/mwt_bind.py +133 -0
  208. package/vendor/mwi/code/engine/motionworks_iec_mcp/navigation.py +44 -0
  209. package/vendor/mwi/code/engine/motionworks_iec_mcp/pou_writer.py +1547 -0
  210. package/vendor/mwi/code/engine/motionworks_iec_mcp/program_checks.py +360 -0
  211. package/vendor/mwi/code/engine/motionworks_iec_mcp/project.py +704 -0
  212. package/vendor/mwi/code/engine/motionworks_iec_mcp/reference_data/catalog.json +672 -0
  213. package/vendor/mwi/code/engine/motionworks_iec_mcp/reference_data/patterns.json +86 -0
  214. package/vendor/mwi/code/engine/motionworks_iec_mcp/restore.py +208 -0
  215. package/vendor/mwi/code/engine/motionworks_iec_mcp/server.py +1913 -0
  216. package/vendor/mwi/code/engine/motionworks_iec_mcp/snapshot.py +138 -0
  217. package/vendor/mwi/code/engine/motionworks_iec_mcp/st_comments.py +25 -0
  218. package/vendor/mwi/code/engine/motionworks_iec_mcp/staging.py +179 -0
  219. package/vendor/mwi/code/engine/motionworks_iec_mcp/stlint.py +676 -0
  220. package/vendor/mwi/code/engine/motionworks_iec_mcp/structure.py +98 -0
  221. package/vendor/mwi/code/engine/motionworks_iec_mcp/task_bindings.py +68 -0
  222. package/vendor/mwi/code/engine/motionworks_iec_mcp/tasks.py +162 -0
  223. package/vendor/mwi/code/engine/motionworks_iec_mcp/transaction.py +157 -0
  224. package/vendor/mwi/code/engine/motionworks_iec_mcp/tree.py +563 -0
  225. package/vendor/mwi/code/engine/motionworks_iec_mcp/tree_writer.py +790 -0
  226. package/vendor/mwi/code/engine/motionworks_iec_mcp/uia.py +465 -0
  227. package/vendor/mwi/code/engine/motionworks_iec_mcp/validation.py +41 -0
  228. package/vendor/mwi/code/engine/motionworks_iec_mcp/variable_edit.py +183 -0
  229. package/vendor/mwi/code/engine/motionworks_iec_mcp/variables.py +472 -0
  230. package/vendor/mwi/code/engine/motionworks_iec_mcp/workflow.py +130 -0
  231. package/vendor/mwi/code/engine/motionworks_iec_mcp/writer.py +666 -0
  232. package/vendor/mwi/code/mw_code.py +1258 -0
  233. package/vendor/mwi/legacy/edit-session.js +50 -0
  234. package/vendor/mwi/legacy/fb-insertion.js +74 -0
  235. package/vendor/mwi/legacy/native-code.js +83 -0
  236. package/vendor/mwi/legacy/native-groups.js +75 -0
  237. package/vendor/mwi/legacy/native-structure.js +143 -0
  238. package/vendor/mwi/legacy/native-variables.js +77 -0
  239. package/vendor/mwi/legacy/pou-conversion.js +47 -0
  240. package/vendor/mwi/legacy/pou-package.js +66 -0
  241. package/vendor/mwi/lib/core/bridge.d.ts +71 -0
  242. package/vendor/mwi/lib/core/bridge.js +53 -0
  243. package/vendor/mwi/lib/core/code-engine.d.ts +47 -0
  244. package/vendor/mwi/lib/core/code-engine.js +109 -0
  245. package/vendor/mwi/lib/core/errors.d.ts +37 -0
  246. package/vendor/mwi/lib/core/errors.js +47 -0
  247. package/vendor/mwi/lib/core/params.d.ts +52 -0
  248. package/vendor/mwi/lib/core/params.js +46 -0
  249. package/vendor/mwi/lib/core/ps-bridge.d.ts +62 -0
  250. package/vendor/mwi/lib/core/ps-bridge.js +127 -0
  251. package/vendor/mwi/lib/core/result.d.ts +45 -0
  252. package/vendor/mwi/lib/core/result.js +20 -0
  253. package/vendor/mwi/lib/core/tool.d.ts +80 -0
  254. package/vendor/mwi/lib/core/tool.js +55 -0
  255. package/vendor/mwi/lib/edit/compare.d.ts +33 -0
  256. package/vendor/mwi/lib/edit/compare.js +70 -0
  257. package/vendor/mwi/lib/edit.d.ts +20 -0
  258. package/vendor/mwi/lib/edit.js +32 -0
  259. package/vendor/mwi/lib/index.d.ts +21 -0
  260. package/vendor/mwi/lib/index.js +33 -0
  261. package/vendor/mwi/lib/read/service.d.ts +117 -0
  262. package/vendor/mwi/lib/read/service.js +229 -0
  263. package/vendor/mwi/lib/read.d.ts +21 -0
  264. package/vendor/mwi/lib/read.js +33 -0
  265. package/vendor/mwi/lib/session/project.d.ts +34 -0
  266. package/vendor/mwi/lib/session/project.js +54 -0
  267. package/vendor/mwi/lib/session/service.d.ts +167 -0
  268. package/vendor/mwi/lib/session/service.js +566 -0
  269. package/vendor/mwi/lib/session/stage.d.ts +84 -0
  270. package/vendor/mwi/lib/session/stage.js +187 -0
  271. package/vendor/mwi/lib/session/workspace.d.ts +52 -0
  272. package/vendor/mwi/lib/session/workspace.js +90 -0
  273. package/vendor/mwi/lib/skill.d.ts +36 -0
  274. package/vendor/mwi/lib/skill.js +56 -0
  275. package/vendor/mwi/lib/tools/edit.d.ts +20 -0
  276. package/vendor/mwi/lib/tools/edit.js +286 -0
  277. package/vendor/mwi/lib/tools/read.d.ts +19 -0
  278. package/vendor/mwi/lib/tools/read.js +161 -0
  279. package/vendor/mwi/lib/tools/session.d.ts +20 -0
  280. package/vendor/mwi/lib/tools/session.js +166 -0
  281. package/vendor/mwi/lib/tools/verify.d.ts +19 -0
  282. package/vendor/mwi/lib/tools/verify.js +85 -0
  283. package/vendor/mwi/lib/verify.d.ts +17 -0
  284. package/vendor/mwi/lib/verify.js +29 -0
@@ -0,0 +1,286 @@
1
+ /**
2
+ * The edit row: replace code, edit declarations, change structure and apply.
3
+ *
4
+ * Editing is off by default. Every tool writes only the staged project, and the
5
+ * proven native helpers verify that unrelated saved and native state did not
6
+ * change.
7
+ *
8
+ * @module dsh-engineering-mwi/tools/edit
9
+ */
10
+ import { boolean, choice, integer, list, object, objectItem, record, string } from "../core/params.js";
11
+ import { success } from "../core/result.js";
12
+ import { MwiError } from "../core/errors.js";
13
+ import { tool } from "../core/tool.js";
14
+ import { workspaceOf } from "../session/workspace.js";
15
+ import { runtimeFor } from "../session/service.js";
16
+ /** What a native edit cannot establish. */
17
+ const EDIT_COVERAGE = {
18
+ complete: false,
19
+ unverified: [
20
+ 'compilation and controller acceptance; the edit verifies saved/native state only',
21
+ 'runtime behavior of the edited code',
22
+ 'graphical bodies; only ST and IL text bodies are editable',
23
+ ],
24
+ };
25
+ /**
26
+ * The edit tools.
27
+ *
28
+ * @param runtimeOf - Workspace runtime factory; defaults to the PowerShell bridge.
29
+ * @returns Tool definitions in registration order.
30
+ */
31
+ export function editTools(runtimeOf = runtimeFor) {
32
+ return [
33
+ tool({
34
+ name: 'mw_edit_code',
35
+ description: 'Replace one ST or IL body in the open staged project through the native ChangeCodeWS path. Supply exact find/replace changes with the body hash, or a complete body with the current body. Verifies saved and native state, then leaves compilation to mw_compile.',
36
+ parameters: object({
37
+ pou: string('Exact POU name.'),
38
+ changes: list('Exact find/replace changes; each must match its expected count.', objectItem('One exact change.', {
39
+ find: string('Exact text to find.'),
40
+ replace: string('Replacement text.'),
41
+ count: integer('Expected non-overlapping occurrences; defaults 1.', { minimum: 1, maximum: 100 }),
42
+ }, ['find', 'replace'])),
43
+ expected_body_sha256: string('Exact 64-character text_body_sha256 from mw_get for kind pou, when using changes.'),
44
+ body: string('Complete replacement body, when not using changes.'),
45
+ expected_body: string('Current body that the complete replacement expects, when using body.'),
46
+ }, ['pou']),
47
+ async run(args, exec) {
48
+ const workspace = workspaceOf(exec.cwd);
49
+ const pou = String(args.pou);
50
+ const changes = Array.isArray(args.changes) ? args.changes : undefined;
51
+ const hasChanges = changes !== undefined && changes.length > 0;
52
+ const hasBody = typeof args.body === 'string';
53
+ if (hasChanges === hasBody) {
54
+ throw new MwiError('INVALID_ARGUMENT', 'Supply either changes with expected_body_sha256, or body with expected_body.', 'Use changes for a small exact patch, or body for a full replacement; do not mix them.');
55
+ }
56
+ if (hasChanges && typeof args.expected_body_sha256 !== 'string') {
57
+ throw new MwiError('INVALID_ARGUMENT', 'Changes need expected_body_sha256.', 'Read the POU with mw_get and pass its text_body_sha256.');
58
+ }
59
+ if (hasBody && typeof args.expected_body !== 'string') {
60
+ throw new MwiError('INVALID_ARGUMENT', 'A complete body needs expected_body.', 'Read the POU with mw_get and pass its current body.');
61
+ }
62
+ const result = await runtimeOf(workspace).editCode({
63
+ pou,
64
+ ...(hasChanges ? { changes, expectedHash: String(args.expected_body_sha256) } : { body: String(args.body), expectedBody: String(args.expected_body) }),
65
+ });
66
+ const verification = result.verification;
67
+ const accepted = verification?.accepted === true;
68
+ return success(accepted ? `Edited ${pou} and verified the saved and native state.` : `Edited ${pou}, but verification reported: ${verification?.errors?.join('; ') ?? 'unknown'}.`, result, accepted
69
+ ? [{ tool: 'mw_compile', why: 'Compile the edited project.' }]
70
+ : [{ tool: 'mw_verify', why: 'Capture a baseline and inspect the mismatch before another edit.' }], EDIT_COVERAGE);
71
+ },
72
+ }),
73
+ tool({
74
+ name: 'mw_edit_variables',
75
+ description: 'Add, edit or delete one declaration in the open staged project through the native IDE API. Edit replaces the complete seven-field declaration and optional boolean flags; delete needs approval and reference review.',
76
+ parameters: object({
77
+ operation: choice('Variable operation.', ['add', 'edit', 'delete']),
78
+ pou: string('POU for a local declaration; omit for resource globals.'),
79
+ name: string('Existing exact name for edit or delete.'),
80
+ declaration: record('Complete replacement declaration.', {
81
+ name: string('Declaration name.'),
82
+ type: string('Data type.'),
83
+ section: string('Declaration section, for example VAR, VAR_GLOBAL or VAR_EXTERNAL.'),
84
+ group: string('Declaration group.'),
85
+ address: string('Direct address, or omit for none.'),
86
+ initial_value: string('Initial value, or omit for none.'),
87
+ description: string('Description, or omit for none.'),
88
+ }, ['name', 'type', 'section']),
89
+ flags: record('Explicit boolean native variable flags; omitted flags stay unchanged.', {
90
+ retain: boolean('Retain flag.'),
91
+ pdd: boolean('Persistent data flag.'),
92
+ opc: boolean('OPC flag.'),
93
+ disabled: boolean('Disabled flag.'),
94
+ not_on_plc: boolean('Not-on-PLC flag.'),
95
+ redundant: boolean('Redundant flag.'),
96
+ }),
97
+ user_approved: boolean('Approval for a deletion.'),
98
+ references_reviewed: boolean('Set after reviewing code and external references.'),
99
+ rename_reviewed: boolean('Set after reviewing references for a rename.'),
100
+ }, ['operation']),
101
+ async run(args, exec) {
102
+ const workspace = workspaceOf(exec.cwd);
103
+ const operation = String(args.operation);
104
+ const raw = args.declaration;
105
+ let declaration;
106
+ if (operation !== 'delete') {
107
+ if (raw === undefined)
108
+ throw new MwiError('INVALID_ARGUMENT', 'An add or edit needs a declaration.', 'Pass name, type and section at minimum; every other field is explicit.');
109
+ const text = (value) => typeof value === 'string' && value !== '' ? value : null;
110
+ declaration = {
111
+ name: String(raw.name),
112
+ type: String(raw.type),
113
+ section: String(raw.section),
114
+ group: text(raw.group),
115
+ address: text(raw.address),
116
+ initial_value: text(raw.initial_value),
117
+ description: text(raw.description),
118
+ };
119
+ }
120
+ const result = await runtimeOf(workspace).editVariable({
121
+ operation,
122
+ ...(typeof args.pou === 'string' ? { pou: args.pou } : {}),
123
+ ...(typeof args.name === 'string' ? { name: args.name } : {}),
124
+ ...(declaration === undefined ? {} : { declaration }),
125
+ ...(args.flags === undefined ? {} : { flags: args.flags }),
126
+ ...(args.user_approved === true ? { user_approved: true } : {}),
127
+ ...(args.references_reviewed === true ? { references_reviewed: true } : {}),
128
+ ...(args.rename_reviewed === true ? { rename_reviewed: true } : {}),
129
+ });
130
+ const verification = result.verification;
131
+ const accepted = verification?.accepted === true;
132
+ return success(accepted ? `${operation} verified against the saved declarations.` : `${operation} did not verify: ${verification?.errors?.join('; ') ?? 'unknown'}.`, result, accepted ? [{ tool: 'mw_compile', why: 'Compile after the intended changes are complete.' }] : [{ tool: 'mw_verify', why: 'Inspect the mismatch before another edit.' }], EDIT_COVERAGE);
133
+ },
134
+ }),
135
+ tool({
136
+ name: 'mw_edit_structure',
137
+ description: 'Create, copy, rename, delete, convert or assign one POU, or create, edit, delete, assign or unassign one task, through the native IDE API. Deletion and unassignment need approval; rename needs reference review.',
138
+ parameters: object({
139
+ scope: choice('Structure kind.', ['pou', 'task']),
140
+ operation: choice('Operation.', ['create', 'copy', 'rename', 'delete', 'edit', 'assign', 'unassign']),
141
+ name: string('Existing name for edit/delete/assign, or the new name for create.'),
142
+ new_name: string('New name for copy or rename.'),
143
+ language: choice('POU language for creation.', ['ST', 'IL', 'FBD', 'LD']),
144
+ pou_type: choice('POU type for creation.', ['PROGRAM', 'FUNCTION_BLOCK', 'FUNCTION']),
145
+ return_type: string('Function return type.'),
146
+ kind: choice('Task kind for creation.', ['CYCLIC', 'DEFAULT', 'SYSTEM']),
147
+ pou: string('Program to assign to a task.'),
148
+ instance: string('Instance name for assign or unassign.'),
149
+ settings: record('Task settings to change; each value is a string.', {
150
+ TYPE: string('Task type.'),
151
+ INTERVAL: string('Cyclic interval, for example T#8ms.'),
152
+ PRIORITY: string('Task priority.'),
153
+ WATCHDOG: string('Watchdog value.'),
154
+ WATCHDOG_ENABLED: string('YES or NO.'),
155
+ }),
156
+ user_approved: boolean('Approval for deletion or unassignment.'),
157
+ references_reviewed: boolean('Set after reviewing references for rename or delete.'),
158
+ }, ['scope', 'operation', 'name']),
159
+ async run(args, exec) {
160
+ const workspace = workspaceOf(exec.cwd);
161
+ const result = await runtimeOf(workspace).editStructure({
162
+ scope: args.scope,
163
+ operation: args.operation,
164
+ name: args.name,
165
+ ...(typeof args.new_name === 'string' ? { new_name: args.new_name } : {}),
166
+ ...(typeof args.language === 'string' ? { language: args.language } : {}),
167
+ ...(typeof args.pou_type === 'string' ? { pou_type: args.pou_type } : {}),
168
+ ...(typeof args.return_type === 'string' ? { return_type: args.return_type } : {}),
169
+ ...(typeof args.kind === 'string' ? { kind: args.kind } : {}),
170
+ ...(typeof args.pou === 'string' ? { pou: args.pou } : {}),
171
+ ...(typeof args.instance === 'string' ? { instance: args.instance } : {}),
172
+ ...(args.settings === undefined ? {} : { settings_changes: args.settings }),
173
+ ...(args.user_approved === true ? { user_approved: true } : {}),
174
+ ...(args.references_reviewed === true ? { references_reviewed: true } : {}),
175
+ });
176
+ const verification = result.verification;
177
+ const accepted = verification?.accepted === true;
178
+ return success(accepted ? `${String(args.operation)} verified against the saved and native structure.` : `${String(args.operation)} did not verify: ${verification?.errors?.join('; ') ?? 'unknown'}.`, result, accepted ? [{ tool: 'mw_compile', why: 'Compile after the intended changes are complete.' }] : [{ tool: 'mw_verify', why: 'Inspect the mismatch before another edit.' }], EDIT_COVERAGE);
179
+ },
180
+ }),
181
+ tool({
182
+ name: 'mw_insert_block',
183
+ description: 'Insert one FB instance declaration and its ST call into a POU through the native APIs. Bindings are pin/value pairs; outputs and in-outs need existing direct variables. Requires the exact current body hash.',
184
+ parameters: object({
185
+ pou: string('Target ST POU.'),
186
+ block: string('Function-block name to instantiate.'),
187
+ instance: string('New instance name.'),
188
+ bindings: list('Pin bindings; every in-out pin must be present.', objectItem('One pin binding.', {
189
+ pin: string('Pin name.'),
190
+ value: string('Exact expression or existing direct variable.'),
191
+ }, ['pin', 'value'])),
192
+ expected_body_sha256: string('Exact 64-character hash of the current POU body, or use expected_body.'),
193
+ expected_body: string('Current POU body, or use expected_body_sha256.'),
194
+ library: string('Library that resolves a duplicate block name.'),
195
+ group: string('Declaration group for the instance; defaults to Default.'),
196
+ before: string('Unique exact text to insert before; mutually exclusive with offset.'),
197
+ offset: integer('Zero-based character offset at a line boundary; defaults to append.', { minimum: 0 }),
198
+ }, ['pou', 'block', 'instance', 'bindings']),
199
+ async run(args, exec) {
200
+ const workspace = workspaceOf(exec.cwd);
201
+ if ((typeof args.expected_body_sha256 === 'string') === (typeof args.expected_body === 'string')) {
202
+ throw new MwiError('INVALID_ARGUMENT', 'Supply exactly one of expected_body_sha256 or expected_body.', 'Read the POU with mw_get and pass its body or its hash.');
203
+ }
204
+ const bindings = {};
205
+ for (const entry of args.bindings) {
206
+ if (bindings[entry.pin] !== undefined)
207
+ throw new MwiError('INVALID_ARGUMENT', `Pin ${entry.pin} is bound twice.`, 'Bind each pin once.');
208
+ bindings[entry.pin] = entry.value;
209
+ }
210
+ const result = await runtimeOf(workspace).insertBlock({
211
+ pou: args.pou,
212
+ block: args.block,
213
+ instance: args.instance,
214
+ bindings,
215
+ ...(typeof args.expected_body_sha256 === 'string' ? { expected_body_sha256: args.expected_body_sha256 } : { expected_body: args.expected_body }),
216
+ ...(typeof args.library === 'string' ? { library: args.library } : {}),
217
+ ...(typeof args.group === 'string' ? { group: args.group } : {}),
218
+ ...(typeof args.before === 'string' ? { before: args.before } : {}),
219
+ ...(typeof args.offset === 'number' ? { offset: args.offset } : {}),
220
+ });
221
+ const verification = result.verification;
222
+ const accepted = verification?.accepted === true;
223
+ return success(accepted ? `Inserted ${String(args.instance)} and its call into ${String(args.pou)}.` : `Insertion did not verify: ${verification?.errors?.join('; ') ?? 'unknown'}.`, result, accepted ? [{ tool: 'mw_compile', why: 'Compile the inserted call.' }] : [{ tool: 'mw_verify', why: 'Inspect the partial phase evidence before another attempt.' }], EDIT_COVERAGE);
224
+ },
225
+ }),
226
+ tool({
227
+ name: 'mw_transfer_pou',
228
+ description: 'Export one writable POU to a private workspace package, or import that untouched package into this staged project. Import needs the export token and a dependency review; a token is consumed by one attempt.',
229
+ parameters: object({
230
+ operation: choice('Package operation.', ['export', 'import']),
231
+ pou: string('Exact POU to export.'),
232
+ package_token: string('Token returned by the export.'),
233
+ dependencies_reviewed: boolean('Set after reviewing the package externals before import.'),
234
+ }, ['operation']),
235
+ async run(args, exec) {
236
+ const workspace = workspaceOf(exec.cwd);
237
+ const operation = String(args.operation);
238
+ if (operation === 'export' && typeof args.pou !== 'string') {
239
+ throw new MwiError('INVALID_ARGUMENT', 'Export needs the exact POU name.', 'Pass pou; import takes no POU name.');
240
+ }
241
+ if (operation === 'import' && typeof args.package_token !== 'string') {
242
+ throw new MwiError('INVALID_ARGUMENT', 'Import needs package_token.', 'Export first, then import with its token.');
243
+ }
244
+ const result = await runtimeOf(workspace).transferPou({
245
+ operation,
246
+ ...(typeof args.pou === 'string' ? { pou: args.pou } : {}),
247
+ ...(typeof args.package_token === 'string' ? { package_token: args.package_token } : {}),
248
+ ...(args.dependencies_reviewed === true ? { dependencies_reviewed: true } : {}),
249
+ });
250
+ const accepted = result.accepted === true;
251
+ return success(accepted
252
+ ? operation === 'export' ? `Exported ${String(args.pou)}.` : 'Imported the POU package.'
253
+ : `Package ${operation} did not verify: ${result.errors?.join('; ') ?? 'unknown'}.`, result, accepted ? [{ tool: 'mw_compile', why: 'Compile after the intended changes are complete.' }] : [{ tool: 'mw_verify', why: 'Inspect the retained package evidence.' }], EDIT_COVERAGE);
254
+ },
255
+ }),
256
+ tool({
257
+ name: 'mw_validate',
258
+ description: 'Validate the open staged project before applying: workflow blockers, native validation and an optional program review for one POU or proposed body. Read the findings before saving or compiling.',
259
+ parameters: object({
260
+ pou: string('POU to review.'),
261
+ body: string('Proposed replacement body to review without writing it.'),
262
+ }),
263
+ async run(args, exec) {
264
+ const workspace = workspaceOf(exec.cwd);
265
+ const result = await runtimeOf(workspace).validate({
266
+ ...(typeof args.pou === 'string' ? { pou: args.pou } : {}),
267
+ ...(typeof args.body === 'string' ? { body: args.body } : {}),
268
+ });
269
+ const ready = result.ready === true;
270
+ return success(ready ? 'Validation found no blocker.' : `Validation found ${String(result.blockers?.length ?? 0)} blocker(s) and ${String(result.validation_errors?.length ?? 0)} validation error(s).`, result, ready
271
+ ? [{ tool: 'mw_apply', why: 'Save the validated staged project.' }]
272
+ : [{ tool: 'mw_review', why: 'Inspect the components named by the findings.' }], EDIT_COVERAGE);
273
+ },
274
+ }),
275
+ tool({
276
+ name: 'mw_apply',
277
+ description: 'Save the open staged project through the IDE. This writes only the staged copy; promoting source back to the workspace remains a separate, explicit step.',
278
+ parameters: object({}),
279
+ async run(_args, exec) {
280
+ const workspace = workspaceOf(exec.cwd);
281
+ const result = await runtimeOf(workspace).apply();
282
+ return success('Saved the staged project through the IDE.', result, [{ tool: 'mw_compile', why: 'Compile the saved project.' }], EDIT_COVERAGE);
283
+ },
284
+ }),
285
+ ];
286
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The read row: the saved project model, code, help and review evidence.
3
+ *
4
+ * Reads describe the saved project. Anything that needs the loaded IDE instance
5
+ * belongs to the session or verify rows and says so in its own coverage.
6
+ *
7
+ * @module dsh-engineering-mwi/tools/read
8
+ */
9
+ import { type ToolDefinition } from '../core/tool.ts';
10
+ import { type ReadService } from '../read/service.ts';
11
+ /** How the tools reach the read service; injectable for tests. */
12
+ export type ReadFactory = (workspace: string) => ReadService;
13
+ /**
14
+ * The read tools.
15
+ *
16
+ * @param readsOf - Read service factory; defaults to the cached workspace runtime.
17
+ * @returns Tool definitions in registration order.
18
+ */
19
+ export declare function readTools(readsOf?: ReadFactory): readonly ToolDefinition[];
@@ -0,0 +1,161 @@
1
+ /**
2
+ * The read row: the saved project model, code, help and review evidence.
3
+ *
4
+ * Reads describe the saved project. Anything that needs the loaded IDE instance
5
+ * belongs to the session or verify rows and says so in its own coverage.
6
+ *
7
+ * @module dsh-engineering-mwi/tools/read
8
+ */
9
+ import { choice, integer, object, string } from "../core/params.js";
10
+ import { success } from "../core/result.js";
11
+ import { tool } from "../core/tool.js";
12
+ import { defaultProject, resolveProject } from "../session/project.js";
13
+ import { workspaceOf } from "../session/workspace.js";
14
+ import { runtimeFor } from "../session/service.js";
15
+ import { GET_KINDS, LIST_KINDS } from "../read/service.js";
16
+ /** Limits shared by every saved-project read. */
17
+ const READ_COVERAGE = {
18
+ complete: false,
19
+ unverified: [
20
+ 'the loaded IDE instance; these reads use the saved project files',
21
+ 'graphical LD/FBD bodies, which are listed but not read as text',
22
+ 'runtime behavior and controller state',
23
+ ],
24
+ };
25
+ /**
26
+ * The read tools.
27
+ *
28
+ * @param readsOf - Read service factory; defaults to the cached workspace runtime.
29
+ * @returns Tool definitions in registration order.
30
+ */
31
+ export function readTools(readsOf = workspace => runtimeFor(workspace).reads) {
32
+ const projectOf = (args, workspace) => typeof args.project === 'string' ? resolveProject(workspace, args.project) : defaultProject(workspace);
33
+ return [
34
+ tool({
35
+ name: 'mw_project_overview',
36
+ description: 'Summarize one project from its saved files: languages, POU, variable, type and task counts, readiness and validation findings. Use it before listing components.',
37
+ parameters: object({
38
+ project: string('Project directory or .mwt inside the workspace. Omit to use the single staged project.'),
39
+ }),
40
+ async run(args, exec) {
41
+ const workspace = workspaceOf(exec.cwd);
42
+ const project = projectOf(args, workspace);
43
+ const reads = readsOf(workspace);
44
+ const workflow = await reads.workflow(project);
45
+ const counts = {};
46
+ for (const kind of ['pou', 'global', 'type', 'task']) {
47
+ counts[kind] = (await reads.list(project, kind, { limit: 1 })).total;
48
+ }
49
+ return success(`${project.name}: ${counts.pou} POU(s), ${counts.global} global declaration(s), ${counts.type} type(s), ${counts.task} task row(s).`, { project: project.directory, staged: project.staged, counts, workflow }, [{ tool: 'mw_list', why: 'List the components you need.' }], READ_COVERAGE);
50
+ },
51
+ }),
52
+ tool({
53
+ name: 'mw_list',
54
+ description: 'List POUs, variables, globals, types, tasks or library blocks from the saved project, with a filter and paging.',
55
+ parameters: object({
56
+ kind: choice('What to list.', LIST_KINDS),
57
+ project: string('Project directory or .mwt inside the workspace. Omit to use the single staged project.'),
58
+ pou: string('POU whose declarations to list; required for kind variable.'),
59
+ filter: string('Case-insensitive substring over the returned fields.'),
60
+ offset: integer('Rows to skip. Defaults to 0.', { minimum: 0 }),
61
+ limit: integer('Most rows. Defaults to 50, maximum 200.', { minimum: 1, maximum: 200 }),
62
+ }, ['kind']),
63
+ async run(args, exec) {
64
+ const workspace = workspaceOf(exec.cwd);
65
+ const project = projectOf(args, workspace);
66
+ const kind = String(args.kind);
67
+ const listed = await readsOf(workspace).list(project, kind, {
68
+ filter: typeof args.filter === 'string' ? args.filter : undefined,
69
+ offset: typeof args.offset === 'number' ? args.offset : 0,
70
+ limit: typeof args.limit === 'number' ? args.limit : 50,
71
+ pou: typeof args.pou === 'string' ? args.pou : undefined,
72
+ });
73
+ return success(`${listed.total} ${kind}(s) in ${project.name}; showing ${listed.rows.length}.`, { project: project.directory, kind, total: listed.total, rows: listed.rows }, [{ tool: 'mw_get', why: 'Read one row in full.' }], READ_COVERAGE);
74
+ },
75
+ }),
76
+ tool({
77
+ name: 'mw_get',
78
+ description: 'Read one POU with its declarations, one type, one task row, one block interface or the EtherNet/IP assembly map.',
79
+ parameters: object({
80
+ kind: choice('What to read.', GET_KINDS),
81
+ name: string('Exact component name; omit only for kind eip.'),
82
+ project: string('Project directory or .mwt inside the workspace. Omit to use the single staged project.'),
83
+ library: string('Library name for a block interface.'),
84
+ }, ['kind']),
85
+ async run(args, exec) {
86
+ const workspace = workspaceOf(exec.cwd);
87
+ const project = projectOf(args, workspace);
88
+ const kind = String(args.kind);
89
+ const name = typeof args.name === 'string' ? args.name : '';
90
+ const document = await readsOf(workspace).get(project, kind, name, typeof args.library === 'string' ? args.library : undefined);
91
+ return success(kind === 'eip' ? `Read the EtherNet/IP assembly map of ${project.name}.` : `Read ${kind} ${name} from ${project.name}.`, { project: project.directory, kind, document }, [{ tool: 'mw_list', why: 'Continue with the components around this one.' }], READ_COVERAGE);
92
+ },
93
+ }),
94
+ tool({
95
+ name: 'mw_search',
96
+ description: 'Find literal text across the saved POU bodies, case-insensitively, with the POU and line of each match.',
97
+ parameters: object({
98
+ query: string('Literal text to find.'),
99
+ project: string('Project directory or .mwt inside the workspace. Omit to use the single staged project.'),
100
+ limit: integer('Most matches. Defaults to 50, maximum 200.', { minimum: 1, maximum: 200 }),
101
+ }, ['query']),
102
+ async run(args, exec) {
103
+ const workspace = workspaceOf(exec.cwd);
104
+ const project = projectOf(args, workspace);
105
+ const result = await readsOf(workspace).search(project, String(args.query), typeof args.limit === 'number' ? args.limit : 50);
106
+ return success(`${result.matches.length} match(es) across ${result.scanned} text POU(s).`, { project: project.directory, ...result }, [{ tool: 'mw_get', why: 'Read the POU that contains the match.', args: { kind: 'pou', name: result.matches[0]?.pou } }], READ_COVERAGE);
107
+ },
108
+ }),
109
+ tool({
110
+ name: 'mw_references',
111
+ description: 'Find where one symbol appears across the saved POU bodies, with the POU and line. Static evidence only.',
112
+ parameters: object({
113
+ symbol: string('Declared or written symbol name.'),
114
+ project: string('Project directory or .mwt inside the workspace. Omit to use the single staged project.'),
115
+ limit: integer('Most matches. Defaults to 50, maximum 200.', { minimum: 1, maximum: 200 }),
116
+ }, ['symbol']),
117
+ async run(args, exec) {
118
+ const workspace = workspaceOf(exec.cwd);
119
+ const project = projectOf(args, workspace);
120
+ const result = await readsOf(workspace).references(project, String(args.symbol), typeof args.limit === 'number' ? args.limit : 50);
121
+ return success(`${result.matches.length} reference(s) across ${result.scanned} text POU(s).`, { project: project.directory, symbol: args.symbol, ...result }, [{ tool: 'mw_get', why: 'Read the enclosing POU.', args: { kind: 'pou', name: result.matches[0]?.pou } }], READ_COVERAGE);
122
+ },
123
+ }),
124
+ tool({
125
+ name: 'mw_review',
126
+ description: 'Run the static review: workflow readiness, native validation, unsupported constructs, and optionally a program review for one POU or proposed body.',
127
+ parameters: object({
128
+ project: string('Project directory or .mwt inside the workspace. Omit to use the single staged project.'),
129
+ pou: string('POU to review.'),
130
+ body: string('Proposed replacement body to review without writing it.'),
131
+ }),
132
+ async run(args, exec) {
133
+ const workspace = workspaceOf(exec.cwd);
134
+ const project = projectOf(args, workspace);
135
+ const review = await readsOf(workspace).review(project, {
136
+ ...(typeof args.pou === 'string' ? { pou: args.pou } : {}),
137
+ ...(typeof args.body === 'string' ? { body: args.body } : {}),
138
+ });
139
+ const workflow = review.workflow;
140
+ return success(`Reviewed ${project.name}${typeof args.pou === 'string' ? ` (${args.pou})` : ''}; ${workflow?.blockers?.length ?? 0} blocker(s).`, { project: project.directory, ...review }, [{ tool: 'mw_list', why: 'Inspect the components named by a finding.' }], { complete: false, unverified: ['review is static; it does not prove runtime behavior', 'vendor XSD or compiler equivalence'] });
141
+ },
142
+ }),
143
+ tool({
144
+ name: 'mw_help',
145
+ description: 'Search installed MotionWorks help, the installed manuals, reviewed Yaskawa references or the versioned ST patterns.',
146
+ parameters: object({
147
+ source: choice('Where to search.', ['help', 'manual', 'reference', 'pattern']),
148
+ query: string('Search term or pattern name; omit to list what is available.'),
149
+ limit: integer('Most rows. Defaults to 10, maximum 50.', { minimum: 1, maximum: 50 }),
150
+ project: string('Project directory or .mwt inside the workspace. Omit to use the single staged project.'),
151
+ }, ['source']),
152
+ async run(args, exec) {
153
+ const workspace = workspaceOf(exec.cwd);
154
+ const project = projectOf(args, workspace);
155
+ const source = String(args.source);
156
+ const document = await readsOf(workspace).help(project, source, typeof args.query === 'string' ? args.query : undefined, typeof args.limit === 'number' ? args.limit : 10);
157
+ return success(`Searched ${source} for ${typeof args.query === 'string' ? args.query : 'available topics'}.`, { project: project.directory, source, document }, [], READ_COVERAGE);
158
+ },
159
+ }),
160
+ ];
161
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * The session row: find, stage, open and close the project; report IDE state.
3
+ *
4
+ * An IDE that is not running is a state, not a failure: the tools report it and
5
+ * point at the start tool. Every mutation that touches the IDE names the consent
6
+ * it needs in its parameters.
7
+ *
8
+ * @module dsh-engineering-mwi/tools/session
9
+ */
10
+ import { type ToolDefinition } from '../core/tool.ts';
11
+ import { type SessionRuntime } from '../session/service.ts';
12
+ /** How the tools reach a workspace runtime; injectable for tests. */
13
+ export type RuntimeFactory = (workspace: string) => SessionRuntime;
14
+ /**
15
+ * The session tools.
16
+ *
17
+ * @param runtimeOf - Workspace runtime factory; defaults to the PowerShell bridge.
18
+ * @returns Tool definitions in registration order.
19
+ */
20
+ export declare function sessionTools(runtimeOf?: RuntimeFactory): readonly ToolDefinition[];