0
0
Fork 0
Commit graph

4 commits

Author SHA1 Message Date
Karstein Phobic Nyvold Kvistad
f1ea6e446f fix(watcher): use ASCII-only comments/log strings (IronPython 2.7 syntax error)
0.4.1 used em-dashes (--) in three log strings and one docstring line.
IronPython 2.7 (CODESYS scripting host) rejects non-ASCII bytes in a
source file unless an explicit encoding declaration (PEP 263) is present:

  Microsoft.Scripting.SyntaxErrorException: Non-ASCII character '\xe2' in
  file ...\watcher.py on line 225, but no encoding declared

Replaced em-dashes with ASCII '--' and bumped WATCHER_VERSION to 0.4.2.
File is now ASCII-clean throughout.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 15:10:21 +02:00
Karstein Phobic Nyvold Kvistad
93a105a644 fix(watcher): swallow KeyboardInterrupt so CODESYS Cancel link doesn't crash the watcher
When the user clicks "Click here to CANCEL this operation" in CODESYS,
IronPython injects KeyboardInterrupt into the running script. The watcher's
try/except blocks only caught Exception, which doesn't include
KeyboardInterrupt — so the interrupt propagated to the host and CODESYS
popped the modal "Running script ... caused exception ... KeyboardInterrupt:
Script aborted by user." dialog. The watcher process then died, taking the
MCP IPC channel with it.

Three layers of handling:

  1. execute_script(): catch KeyboardInterrupt and convert it into a normal
     command failure ("Aborted by user (Cancel pressed in CODESYS)") so the
     in-flight command fails gracefully and the loop continues.

  2. Main poll loop: catch KeyboardInterrupt around the iteration body, log
     it, and continue. New _safe_delay() helper wraps system.delay() with
     its own KeyboardInterrupt swallow because the cancel link almost always
     hits during the delay (line 231 in 0.4.0).

  3. Outer try: explicit KeyboardInterrupt arm so a cancel that fires before
     the loop (during scriptengine import or directory setup) still exits
     quietly without the modal traceback dialog.

Bumps WATCHER_VERSION to 0.4.1. Verification pending — needs user to
click the Cancel link in CODESYS after a fresh launch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 15:05:35 +02:00
Karstein Phobic Nyvold Kvistad
f525da973a fix: drop bg-thread + execute_on_primary_thread for SP21+/SP22
Replace the .NET background-thread + system.execute_on_primary_thread
marshalling design with a single-threaded primary-thread polling loop
that yields to the IDE via system.delay(). The deprecated
execute_on_primary_thread API was removed in CODESYS V3.5 SP21+ — see
docs/MIGRATION-SP21-PLUS.md for full evidence and rationale.

- watcher.py: drop clr / System.Threading imports, drop ManualResetEvent
  + done_event + shared_result cross-thread machinery, keep file-based
  IPC and OutputCapture untouched.
- Loop checks for terminate.signal at the top of each iteration, then
  serves the message loop via system.delay(POLL_INTERVAL).
- Bumped WATCHER_VERSION to 0.4.0.

Verified against:
- CODESYS 3.5.22.10 (SP22 Patch 1) — open_project + get_application_state
  both succeed where they previously failed with the marshal error.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 14:27:54 +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