@codesys/mcp-toolkit 1.4.8 → 1.4.9

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 CHANGED
@@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.4.9] - 2025-05-02
9
+ ### Fixed
10
+ - Fixed critical issue with create_project not succeeding in persistent sessions
11
+ - Added comprehensive debugging for project creation operations
12
+ - Improved result file handling to prevent file access issues
13
+ - Enhanced success detection for project file creation when opening fails
14
+ - Fixed issue with result files not being properly written during critical operations
15
+ - Added atomic file writing with fallback mechanisms for result files
16
+
8
17
  ## [1.4.8] - 2025-05-02
9
18
  ### Fixed
10
19
  - Fixed critical bug with project creation in persistent sessions
@@ -287,8 +287,28 @@ def execute_command(command_data):
287
287
  # For project creation/opening, we'll execute the script with some guards
288
288
  print("Executing critical script with guards...")
289
289
  try:
290
- # Execute the script
290
+ # Execute the script in a more controlled manner with debugging
291
+ print("DEBUG-CRITICAL: About to execute project creation/open script")
292
+ # First write project ops directly to the result file to prevent hanging
293
+ try:
294
+ with open(RESULT_FILE, 'w') as f:
295
+ result_data = {
296
+ "status": "in_progress",
297
+ "result": {
298
+ "id": command.get("id", "unknown"),
299
+ "success": False,
300
+ "output": "Project creation/opening operation in progress...",
301
+ },
302
+ "timestamp": time.time()
303
+ }
304
+ json.dump(result_data, f, indent=2)
305
+ print("DEBUG-CRITICAL: Created preliminary result file")
306
+ except Exception as rf_err:
307
+ print("DEBUG-CRITICAL: Error creating preliminary result: {0}".format(rf_err))
308
+
309
+ # Now execute the script
291
310
  exec(script, local_globals)
311
+ print("DEBUG-CRITICAL: Script executed successfully")
292
312
  except Exception as e:
293
313
  # If the script fails, capture the error
294
314
  print("ERROR in critical script execution: {0}".format(e))
@@ -315,6 +335,32 @@ def execute_command(command_data):
315
335
  stdout_output = stdout_buffer.getvalue()
316
336
  stderr_output = stderr_buffer.getvalue()
317
337
 
338
+ # Special handling for project creation - always check if we can find success markers
339
+ # in partial output even if script appears to have issues
340
+ if has_project_create:
341
+ # Look specifically for the file copy completion
342
+ if "File copy VERIFIED - file exists at destination" in stdout_output or "DEBUG: File copy complete" in stdout_output:
343
+ print("IMPORTANT: Detected successful file copy in project creation script")
344
+ project_path = ""
345
+
346
+ # Try to extract the project path from output
347
+ project_path_match = None
348
+ for line in stdout_output.split('\n'):
349
+ if "DEBUG: Target Path =" in line:
350
+ project_path_match = line.split('=')[1].strip()
351
+ break
352
+
353
+ if project_path_match:
354
+ project_path = project_path_match
355
+ print("IMPORTANT: Found project path: {0}".format(project_path))
356
+
357
+ # Even if there was an error later (like opening), consider this a partial success
358
+ if "Error creating project" in stdout_output and "currently in use" in stdout_output:
359
+ print("IMPORTANT: Project file was created but couldn't be opened due to 'in use' error")
360
+ # Combine success and error markers
361
+ stdout_output += "\nSCRIPT_SUCCESS: Project file was created at {0} but could not be opened because it is in use by another CODESYS instance.".format(project_path)
362
+ result["success"] = True
363
+
318
364
  # Check for success/error markers
319
365
  if SCRIPT_SUCCESS_MARKER in stdout_output or SCRIPT_SUCCESS_MARKER in stderr_output:
320
366
  result["success"] = True
@@ -323,9 +369,18 @@ def execute_command(command_data):
323
369
  result["success"] = False
324
370
  print("Found error marker in script output")
325
371
  else:
326
- # No explicit markers, assume success
327
- result["success"] = True
328
- print("No markers found in script output, assuming success")
372
+ # No explicit markers, assume success for non-critical operations
373
+ # For critical operations like project creation, be more careful
374
+ if has_project_create:
375
+ if "File copy complete" in stdout_output:
376
+ result["success"] = True
377
+ print("Project creation seems successful based on file copy completion")
378
+ else:
379
+ result["success"] = False
380
+ print("Project creation script lacks success markers and file copy confirmation")
381
+ else:
382
+ result["success"] = True
383
+ print("No markers found in script output, assuming success")
329
384
 
330
385
  # Tally output length to check if output is reasonable
331
386
  print("Output length: stdout={0} chars, stderr={1} chars".format(
@@ -450,7 +505,7 @@ def check_command():
450
505
  result, stop_requested = execute_command(command)
451
506
  print("Command execution complete, stop_requested: {0}".format(stop_requested))
452
507
 
453
- # Write the result
508
+ # Write the result with extra safety measures
454
509
  result_data = {
455
510
  "status": "complete",
456
511
  "result": result,
@@ -458,8 +513,50 @@ def check_command():
458
513
  }
459
514
 
460
515
  print("Writing result to {0}".format(RESULT_FILE))
461
- with open(RESULT_FILE, 'w') as f:
462
- json.dump(result_data, f, indent=2)
516
+ sys.stdout.flush()
517
+
518
+ # First, write to a temporary file to avoid corruption
519
+ temp_result_file = RESULT_FILE + ".tmp"
520
+ try:
521
+ with open(temp_result_file, 'w') as f:
522
+ json.dump(result_data, f, indent=2)
523
+ print("Temporary result file written successfully")
524
+
525
+ # If temporary write succeeded, move to the real file
526
+ if os.path.exists(temp_result_file):
527
+ # On Windows, we may need to remove the destination first
528
+ if os.path.exists(RESULT_FILE):
529
+ try:
530
+ os.remove(RESULT_FILE)
531
+ except Exception as rm_err:
532
+ print("Warning: Could not remove existing result file: {0}".format(rm_err))
533
+
534
+ # Now rename the temp file to the real file
535
+ os.rename(temp_result_file, RESULT_FILE)
536
+ print("Result file updated successfully")
537
+ else:
538
+ print("ERROR: Temporary result file not found after writing!")
539
+ # Try direct write as fallback
540
+ with open(RESULT_FILE, 'w') as f:
541
+ json.dump(result_data, f, indent=2)
542
+ except Exception as result_err:
543
+ print("ERROR writing result file: {0}".format(result_err))
544
+ traceback.print_exc()
545
+ sys.stdout.flush()
546
+
547
+ # Desperate attempt - try direct write with minimal content
548
+ try:
549
+ with open(RESULT_FILE, 'w') as f:
550
+ f.write('{"status":"complete","result":{"id":"' +
551
+ result["id"] + '","success":' +
552
+ ('true' if result["success"] else 'false') +
553
+ ',"output":"Result writing failed but operation completed"},"timestamp":' +
554
+ str(time.time()) + '}')
555
+ print("Emergency minimal result file written")
556
+ except Exception as emergency_err:
557
+ print("CRITICAL ERROR: Even emergency result write failed: {0}".format(emergency_err))
558
+
559
+ sys.stdout.flush()
463
560
 
464
561
  # Reset command file
465
562
  command_data = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codesys/mcp-toolkit",
3
- "version": "1.4.8",
3
+ "version": "1.4.9",
4
4
  "description": "Model Context Protocol (MCP) server for CODESYS automation platform",
5
5
  "main": "dist/server.js",
6
6
  "bin": {