0
0
Fork 0
Commit graph

3 commits

Author SHA1 Message Date
Karstein Phobic Nyvold Kvistad
d414c779a5 fix(add_library): refuse to save unresolvable placeholders
Prior behaviour: lm.add_library(LIBRARY_NAME) was called with a string,
which always hits the placeholder overload of ScriptLibManObject.add_library
(see helpme-codesys.com "ScriptLibManObject" / local SP22 stub
ScriptLib/Stubs/scriptengine/ScriptLibManObject.pyi). If the named
placeholder is not registered in the IDE, the resulting reference fails
to resolve at load time and the next project open throws

  Library Manager: Error: Could not open library 'X'.
  (Reason: The placeholder library 'X' could not be resolved.)

after which script_engine.projects.primary returns None and the project
is effectively bricked until the binary is reverted. add_library reported
SUCCESS in this scenario.

Fix:
  1. Pre-resolve LIBRARY_NAME via the IDE-level
     library_manager.find_library(name) global. If found, pass the
     resulting ManagedLib to lm.add_library(...) -- the V3.5.5.0 ManagedLib
     overload which produces a managed reference instead of a placeholder.
  2. After the add, walk lm.references to locate the new entry and verify
     it resolved (managed -> always; placeholder -> non-empty
     effective_resolution per ScriptPlaceholderReference in the stub).
  3. If the reference did not resolve, call lm.remove_library(name) to back
     out the bad reference and refuse to save the project, returning an
     actionable error instead.

Also tightened the libman lookup to use the documented
has_library_manager / get_library_manager() container API
(ScriptLibManObjectContainer in the stub) instead of name-searching for
"Library Manager" as a tree node, matching what list_project_libraries.py
already does. The legacy name-search fallback is preserved for older SPs.

Regression test added in tests/integration/e2e.test.ts asserting the
rendered script template carries the resolution gate, the managed-overload
preference, the back-out call, and that primary_project.save() in the
add_library body lives downstream of the _is_resolved gate.

Followup: lm.remove_library(name) is documented for SP22 and is the
clean back-out path. On SPs that lack remove_library (none observed in
the 3.5.21+ docs but possible on truly old branches) the script reports
the constraint and exits non-zero rather than silently saving a bad
reference.
2026-04-26 19:44:00 +02:00
Karstein Phobic Nyvold Kvistad
35abc8cb52 fix(set_pou_code): omitted declaration/impl no longer wipes the POU
Bug: calling set_pou_code with implementationCode only (declarationCode
omitted) would wipe the POU's PROGRAM/VAR...END_VAR block in the binary.
After such a call mirror_export classified the POU as 'UNKNOWN' (no
PROGRAM/FUNCTION_BLOCK keyword in the empty declaration), and the var
block disappeared from the .st mirror file.

Root cause: the TS wrapper substituted '' (empty string) into the Python
template when declarationCode was undefined, giving DECLARATION_CONTENT
= "". The Python script then took the truthy-ish branch (empty string
is not None) and called decl_obj.replace('') -- wiping textual_decl.

Fix: pass explicit SET_DECLARATION / SET_IMPLEMENTATION boolean flags
from the TS wrapper, gate the replace() calls on those flags. Empty
string remains a valid intentional value (caller wants to wipe).

- Reproduced on MCPTest2: PLC_PRG declaration block was wiped between
  v1.3.0.0 and v1.3.1.0 by exactly this code path.
- Regression test added in tests/integration/e2e.test.ts covering the
  omitted-declarationCode path.
- Existing set_pou_code test extended to assert SET_DECLARATION /
  SET_IMPLEMENTATION are emitted in the rendered script.
2026-04-26 18:41:48 +02:00
Luke
e374519fe1 Initial release: MCP server for CODESYS with persistent UI instance
v0.3.0 returning-watcher architecture — background thread polls for commands
and marshals execution onto the CODESYS UI thread, keeping the IDE fully
responsive between operations. File-based IPC with atomic writes, async mutex
command serialization, headless fallback, and 35 passing tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 18:59:16 +10:00