@codesys/mcp-toolkit 1.1.5 → 1.1.7

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 (34) hide show
  1. package/CHANGELOG.md +10 -5
  2. package/dist/bin.js +2 -41
  3. package/dist/scriptLoader.js +18 -1
  4. package/dist/scripts/check_status.py +21 -0
  5. package/dist/scripts/compile_project.py +65 -0
  6. package/dist/scripts/create_method.py +80 -0
  7. package/dist/scripts/create_pou.py +96 -0
  8. package/dist/scripts/create_project.py +54 -0
  9. package/dist/scripts/create_property.py +78 -0
  10. package/dist/scripts/ensure_project_open.py +154 -0
  11. package/dist/scripts/find_object_by_path.py +111 -0
  12. package/dist/scripts/get_pou_code.py +91 -0
  13. package/dist/scripts/get_project_structure.py +72 -0
  14. package/dist/scripts/open_project.py +25 -0
  15. package/dist/scripts/save_project.py +29 -0
  16. package/dist/scripts/set_pou_code.py +104 -0
  17. package/dist/server.js +319 -503
  18. package/package.json +16 -4
  19. package/src/scripts/check_status.py +21 -0
  20. package/src/scripts/compile_project.py +65 -0
  21. package/src/scripts/create_method.py +80 -0
  22. package/src/scripts/create_pou.py +96 -0
  23. package/src/scripts/create_project.py +54 -0
  24. package/src/scripts/create_property.py +78 -0
  25. package/src/scripts/ensure_project_open.py +154 -0
  26. package/src/scripts/find_object_by_path.py +111 -0
  27. package/src/scripts/get_pou_code.py +91 -0
  28. package/src/scripts/get_project_structure.py +72 -0
  29. package/src/scripts/open_project.py +25 -0
  30. package/src/scripts/save_project.py +29 -0
  31. package/src/scripts/set_pou_code.py +104 -0
  32. package/.claude/settings.local.json +0 -13
  33. package/CONTRIBUTING.md +0 -72
  34. package/codesys_scripts/listener_script.py +0 -1539
@@ -0,0 +1,111 @@
1
+ import traceback
2
+ # --- Find object by path function ---
3
+ def find_object_by_path_robust(start_node, full_path, target_type_name="object"):
4
+ print("DEBUG: Finding %s by path: '%s'" % (target_type_name, full_path))
5
+ normalized_path = full_path.replace('\\\\', '/').strip('/')
6
+ path_parts = normalized_path.split('/')
7
+ if not path_parts:
8
+ print("ERROR: Path is empty.")
9
+ return None
10
+
11
+ # Determine the actual starting node (project or application)
12
+ project = start_node # Assume start_node is project initially
13
+ if not hasattr(start_node, 'active_application') and hasattr(start_node, 'project'):
14
+ # If start_node is not project but has project ref (e.g., an application), get the project
15
+ try: project = start_node.project
16
+ except Exception as proj_ref_err:
17
+ print("WARN: Could not get project reference from start_node: %s" % proj_ref_err)
18
+ # Proceed assuming start_node might be the project anyway or search fails
19
+
20
+ # Try to get the application object robustly if we think we have the project
21
+ app = None
22
+ if hasattr(project, 'active_application'):
23
+ try: app = project.active_application
24
+ except Exception: pass # Ignore errors getting active app
25
+ if not app:
26
+ try:
27
+ apps = project.find("Application", True) # Search recursively
28
+ if apps: app = apps[0]
29
+ except Exception: pass
30
+
31
+ # Check if the first path part matches the application name
32
+ app_name_lower = ""
33
+ if app:
34
+ try: app_name_lower = (app.get_name() or "application").lower()
35
+ except Exception: app_name_lower = "application" # Fallback
36
+
37
+ # Decide where to start the traversal
38
+ current_obj = start_node # Default to the node passed in
39
+ if hasattr(project, 'active_application'): # Only adjust if start_node was likely the project
40
+ if app and path_parts[0].lower() == app_name_lower:
41
+ print("DEBUG: Path starts with Application name '%s'. Beginning search there." % path_parts[0])
42
+ current_obj = app
43
+ path_parts = path_parts[1:] # Consume the app name part
44
+ # If path was *only* the application name
45
+ if not path_parts:
46
+ print("DEBUG: Target path is the Application object itself.")
47
+ return current_obj
48
+ else:
49
+ print("DEBUG: Path does not start with Application name. Starting search from project root.")
50
+ current_obj = project # Start search from the project root
51
+ else:
52
+ print("DEBUG: Starting search from originally provided node.")
53
+
54
+
55
+ # Traverse the remaining path parts
56
+ parent_path_str = getattr(current_obj, 'get_name', lambda: str(current_obj))() # Safer name getting
57
+
58
+ for i, part_name in enumerate(path_parts):
59
+ is_last_part = (i == len(path_parts) - 1)
60
+ print("DEBUG: Searching for part [%d/%d]: '%s' under '%s'" % (i+1, len(path_parts), part_name, parent_path_str))
61
+ found_in_parent = None
62
+ try:
63
+ # Prioritize non-recursive find for direct children
64
+ children_of_current = current_obj.get_children(False)
65
+ print("DEBUG: Found %d direct children under '%s'." % (len(children_of_current), parent_path_str))
66
+ for child in children_of_current:
67
+ child_name = getattr(child, 'get_name', lambda: None)() # Safer name getting
68
+ # print("DEBUG: Checking child: '%s'" % child_name) # Verbose
69
+ if child_name == part_name:
70
+ found_in_parent = child
71
+ print("DEBUG: Found direct child matching '%s'." % part_name)
72
+ break # Found direct child, stop searching children
73
+
74
+ # If not found directly, AND it's the last part, try recursive find from current parent
75
+ if not found_in_parent and is_last_part:
76
+ print("DEBUG: Direct find failed for last part '%s'. Trying recursive find under '%s'." % (part_name, parent_path_str))
77
+ found_recursive_list = current_obj.find(part_name, True) # Recursive find
78
+ if found_recursive_list:
79
+ # Maybe add a check here if multiple are found?
80
+ found_in_parent = found_recursive_list[0] # Take the first match
81
+ print("DEBUG: Found last part '%s' recursively." % part_name)
82
+ else:
83
+ print("DEBUG: Recursive find also failed for last part '%s'." % part_name)
84
+
85
+ # Update current object if found
86
+ if found_in_parent:
87
+ current_obj = found_in_parent
88
+ parent_path_str = getattr(current_obj, 'get_name', lambda: part_name)() # Safer name getting
89
+ print("DEBUG: Stepped into '%s'." % parent_path_str)
90
+ else:
91
+ # If not found at any point, the path is invalid from this parent
92
+ print("ERROR: Path part '%s' not found under '%s'." % (part_name, parent_path_str))
93
+ return None # Path broken
94
+
95
+ except Exception as find_err:
96
+ print("ERROR: Exception while searching for '%s' under '%s': %s" % (part_name, parent_path_str, find_err))
97
+ traceback.print_exc()
98
+ return None # Error during search
99
+
100
+ # Final verification (optional but recommended): Check if the found object's name matches the last part
101
+ final_expected_name = full_path.split('/')[-1]
102
+ found_final_name = getattr(current_obj, 'get_name', lambda: None)() # Safer name getting
103
+
104
+ if found_final_name == final_expected_name:
105
+ print("DEBUG: Final %s found and name verified for path '%s': %s" % (target_type_name, full_path, found_final_name))
106
+ return current_obj
107
+ else:
108
+ print("ERROR: Traversal ended on object '%s' but expected final name was '%s'." % (found_final_name, final_expected_name))
109
+ return None # Name mismatch implies target not found as expected
110
+
111
+ # --- End of find object function ---
@@ -0,0 +1,91 @@
1
+ import sys, scriptengine as script_engine, os, traceback
2
+
3
+ # Import ensure_project_open function from the template
4
+ # This will be prepended by the script loader
5
+ def ensure_project_open(target_project_path):
6
+ # Function implementation will be included from ensure_project_open.py
7
+ pass
8
+
9
+ # Import find_object_by_path function from the template
10
+ # This will be prepended by the script loader
11
+ def find_object_by_path_robust(start_node, full_path, target_type_name="object"):
12
+ # Function implementation will be included from find_object_by_path.py
13
+ pass
14
+
15
+ POU_FULL_PATH = "{POU_FULL_PATH}"
16
+ CODE_START_MARKER = "### POU CODE START ###"
17
+ CODE_END_MARKER = "### POU CODE END ###"
18
+ DECL_START_MARKER = "### POU DECLARATION START ###"
19
+ DECL_END_MARKER = "### POU DECLARATION END ###"
20
+ IMPL_START_MARKER = "### POU IMPLEMENTATION START ###"
21
+ IMPL_END_MARKER = "### POU IMPLEMENTATION END ###"
22
+
23
+ try:
24
+ print("DEBUG: Getting code: POU_FULL_PATH='%s', Project='%s'" % (POU_FULL_PATH, PROJECT_FILE_PATH))
25
+ primary_project = ensure_project_open(PROJECT_FILE_PATH)
26
+ if not POU_FULL_PATH: raise ValueError("POU full path empty.")
27
+
28
+ # Find the target POU/Method/Property object
29
+ target_object = find_object_by_path_robust(primary_project, POU_FULL_PATH, "target object")
30
+ if not target_object: raise ValueError("Target object not found using path: %s" % POU_FULL_PATH)
31
+
32
+ target_name = getattr(target_object, 'get_name', lambda: POU_FULL_PATH)()
33
+ print("DEBUG: Found target object: %s" % target_name)
34
+
35
+ declaration_code = ""; implementation_code = ""
36
+
37
+ # --- Get Declaration Part ---
38
+ if hasattr(target_object, 'textual_declaration'):
39
+ decl_obj = target_object.textual_declaration
40
+ if decl_obj and hasattr(decl_obj, 'text'):
41
+ try:
42
+ declaration_code = decl_obj.text
43
+ print("DEBUG: Got declaration text.")
44
+ except Exception as decl_read_err:
45
+ print("ERROR: Failed to read declaration text: %s" % decl_read_err)
46
+ declaration_code = "/* ERROR reading declaration: %s */" % decl_read_err
47
+ else:
48
+ print("WARN: textual_declaration exists but is None or has no 'text' attribute.")
49
+ else:
50
+ print("WARN: No textual_declaration attribute.")
51
+
52
+ # --- Get Implementation Part ---
53
+ if hasattr(target_object, 'textual_implementation'):
54
+ impl_obj = target_object.textual_implementation
55
+ if impl_obj and hasattr(impl_obj, 'text'):
56
+ try:
57
+ implementation_code = impl_obj.text
58
+ print("DEBUG: Got implementation text.")
59
+ except Exception as impl_read_err:
60
+ print("ERROR: Failed to read implementation text: %s" % impl_read_err)
61
+ implementation_code = "/* ERROR reading implementation: %s */" % impl_read_err
62
+ else:
63
+ print("WARN: textual_implementation exists but is None or has no 'text' attribute.")
64
+ else:
65
+ print("WARN: No textual_implementation attribute.")
66
+
67
+
68
+ print("Code retrieved for: %s" % target_name)
69
+ # Print declaration between markers, ensuring markers are on separate lines
70
+ print("\\n" + DECL_START_MARKER)
71
+ print(declaration_code)
72
+ print(DECL_END_MARKER + "\\n")
73
+ # Print implementation between markers
74
+ print(IMPL_START_MARKER)
75
+ print(implementation_code)
76
+ print(IMPL_END_MARKER + "\\n")
77
+
78
+ # --- LEGACY MARKERS for backward compatibility if needed ---
79
+ # Combine both for old marker format, adding a separator line
80
+ # legacy_combined_code = declaration_code + "\\n\\n// Implementation\\n" + implementation_code
81
+ # print(CODE_START_MARKER); print(legacy_combined_code); print(CODE_END_MARKER)
82
+ # --- END LEGACY ---
83
+
84
+ print("SCRIPT_SUCCESS: Code retrieved.")
85
+ sys.exit(0)
86
+ except Exception as e:
87
+ detailed_error = traceback.format_exc()
88
+ error_message = "Error getting code for object '%s' in project '%s': %s\\n%s" % (POU_FULL_PATH, PROJECT_FILE_PATH, e, detailed_error)
89
+ print(error_message)
90
+ print("SCRIPT_ERROR: %s" % error_message)
91
+ sys.exit(1)
@@ -0,0 +1,72 @@
1
+ import sys, scriptengine as script_engine, os, traceback
2
+
3
+ # Import ensure_project_open function from the template
4
+ # This will be prepended by the script loader
5
+ def ensure_project_open(target_project_path):
6
+ # Function implementation will be included from ensure_project_open.py
7
+ pass
8
+
9
+ def get_object_structure(obj, indent=0, max_depth=10): # Add max_depth
10
+ lines = []; indent_str = " " * indent
11
+ if indent > max_depth:
12
+ lines.append("%s- Max recursion depth reached." % indent_str)
13
+ return lines
14
+ try:
15
+ name = "Unnamed"; obj_type = type(obj).__name__
16
+ guid_str = ""
17
+ folder_str = ""
18
+ try:
19
+ name = getattr(obj, 'get_name', lambda: "Unnamed")() or "Unnamed" # Safer get_name
20
+ if hasattr(obj, 'guid'): guid_str = " {%s}" % obj.guid
21
+ if hasattr(obj, 'is_folder') and obj.is_folder: folder_str = " [Folder]"
22
+ except Exception as name_err:
23
+ print("WARN: Error getting name/guid/folder status for an object: %s" % name_err)
24
+ name = "!!! Error Getting Name !!!"
25
+
26
+ lines.append("%s- %s (%s)%s%s" % (indent_str, name, obj_type, folder_str, guid_str))
27
+
28
+ # Get children only if the object potentially has them
29
+ children = []
30
+ can_have_children = hasattr(obj, 'get_children') and (
31
+ not hasattr(obj, 'is_folder') or # If it's not clear if it's a folder (e.g., project root)
32
+ (hasattr(obj, 'is_folder') and obj.is_folder) or # If it is a folder
33
+ # Add known container types explicitly, check marker interfaces too
34
+ hasattr(obj, 'is_project') or hasattr(obj, 'is_application') or hasattr(obj, 'is_device') or hasattr(obj,'is_pou')
35
+ )
36
+
37
+ if can_have_children:
38
+ try:
39
+ children = obj.get_children(False)
40
+ # print("DEBUG: %s has %d children" % (name, len(children))) # Verbose
41
+ except Exception as get_child_err:
42
+ lines.append("%s ERROR getting children: %s" % (indent_str, get_child_err))
43
+ # traceback.print_exc() # Optional
44
+
45
+ for child in children:
46
+ lines.extend(get_object_structure(child, indent + 1, max_depth)) # Recurse
47
+
48
+ except Exception as e:
49
+ lines.append("%s- Error processing node: %s" % (indent_str, e))
50
+ traceback.print_exc() # Print detailed error for this node
51
+ return lines
52
+
53
+ try:
54
+ print("DEBUG: Getting structure for: %s" % PROJECT_FILE_PATH)
55
+ primary_project = ensure_project_open(PROJECT_FILE_PATH)
56
+ project_name = os.path.basename(PROJECT_FILE_PATH)
57
+ print("DEBUG: Getting structure for project: %s" % project_name)
58
+ # Use the project object obtained from ensure_project_open
59
+ structure_list = get_object_structure(primary_project, max_depth=15) # Set a reasonable depth
60
+ structure_output = "\\n".join(structure_list)
61
+ # Ensure markers are printed distinctly
62
+ print("\\n--- PROJECT STRUCTURE START ---")
63
+ print(structure_output)
64
+ print("--- PROJECT STRUCTURE END ---\\n")
65
+ print("SCRIPT_SUCCESS: Project structure retrieved.")
66
+ sys.exit(0)
67
+ except Exception as e:
68
+ detailed_error = traceback.format_exc()
69
+ error_message = "Error getting structure for %s: %s\\n%s" % (PROJECT_FILE_PATH, e, detailed_error)
70
+ print(error_message)
71
+ print("SCRIPT_ERROR: %s" % error_message)
72
+ sys.exit(1)
@@ -0,0 +1,25 @@
1
+ import sys, scriptengine as script_engine, os, traceback
2
+
3
+ # Import ensure_project_open function from the template
4
+ # This will be prepended by the script loader
5
+ def ensure_project_open(target_project_path):
6
+ # Function implementation will be included from ensure_project_open.py
7
+ pass
8
+
9
+ try:
10
+ project = ensure_project_open(PROJECT_FILE_PATH)
11
+ # Get name from object if possible, otherwise use path basename
12
+ proj_name = "Unknown"
13
+ try:
14
+ if project: proj_name = project.get_name() or os.path.basename(PROJECT_FILE_PATH)
15
+ else: proj_name = os.path.basename(PROJECT_FILE_PATH) + " (ensure_project_open returned None?)"
16
+ except Exception:
17
+ proj_name = os.path.basename(PROJECT_FILE_PATH) + " (name retrieval failed)"
18
+ print("Project Opened: %s" % proj_name)
19
+ print("SCRIPT_SUCCESS: Project opened successfully.")
20
+ sys.exit(0)
21
+ except Exception as e:
22
+ error_message = "Error opening project %s: %s" % (PROJECT_FILE_PATH, e)
23
+ print(error_message)
24
+ traceback.print_exc()
25
+ print("SCRIPT_ERROR: %s" % error_message); sys.exit(1)
@@ -0,0 +1,29 @@
1
+ import sys, scriptengine as script_engine, os, traceback
2
+
3
+ # Import ensure_project_open function from the template
4
+ # This will be prepended by the script loader
5
+ def ensure_project_open(target_project_path):
6
+ # Function implementation will be included from ensure_project_open.py
7
+ pass
8
+
9
+ try:
10
+ primary_project = ensure_project_open(PROJECT_FILE_PATH)
11
+ # Get name from object if possible, otherwise use path basename
12
+ project_name = "Unknown"
13
+ try:
14
+ if primary_project: project_name = primary_project.get_name() or os.path.basename(PROJECT_FILE_PATH)
15
+ else: project_name = os.path.basename(PROJECT_FILE_PATH) + " (ensure_project_open returned None?)"
16
+ except Exception:
17
+ project_name = os.path.basename(PROJECT_FILE_PATH) + " (name retrieval failed)"
18
+
19
+ print("DEBUG: Saving project: %s (%s)" % (project_name, PROJECT_FILE_PATH))
20
+ primary_project.save()
21
+ print("DEBUG: project.save() executed.")
22
+ print("Project Saved: %s" % project_name)
23
+ print("SCRIPT_SUCCESS: Project saved successfully.")
24
+ sys.exit(0)
25
+ except Exception as e:
26
+ error_message = "Error saving project %s: %s" % (PROJECT_FILE_PATH, e)
27
+ print(error_message)
28
+ traceback.print_exc()
29
+ print("SCRIPT_ERROR: %s" % error_message); sys.exit(1)
@@ -0,0 +1,104 @@
1
+ import sys, scriptengine as script_engine, os, traceback
2
+
3
+ # Import ensure_project_open function from the template
4
+ # This will be prepended by the script loader
5
+ def ensure_project_open(target_project_path):
6
+ # Function implementation will be included from ensure_project_open.py
7
+ pass
8
+
9
+ # Import find_object_by_path function from the template
10
+ # This will be prepended by the script loader
11
+ def find_object_by_path_robust(start_node, full_path, target_type_name="object"):
12
+ # Function implementation will be included from find_object_by_path.py
13
+ pass
14
+
15
+ POU_FULL_PATH = "{POU_FULL_PATH}" # Expecting format like "Application/MyPOU" or "Folder/SubFolder/MyPOU"
16
+ DECLARATION_CONTENT = """{DECLARATION_CONTENT}"""
17
+ IMPLEMENTATION_CONTENT = """{IMPLEMENTATION_CONTENT}"""
18
+
19
+ try:
20
+ print("DEBUG: set_pou_code script: POU_FULL_PATH='%s', Project='%s'" % (POU_FULL_PATH, PROJECT_FILE_PATH))
21
+ primary_project = ensure_project_open(PROJECT_FILE_PATH)
22
+ if not POU_FULL_PATH: raise ValueError("POU full path empty.")
23
+
24
+ # Find the target POU/Method/Property object
25
+ target_object = find_object_by_path_robust(primary_project, POU_FULL_PATH, "target object")
26
+ if not target_object: raise ValueError("Target object not found using path: %s" % POU_FULL_PATH)
27
+
28
+ target_name = getattr(target_object, 'get_name', lambda: POU_FULL_PATH)()
29
+ print("DEBUG: Found target object: %s" % target_name)
30
+
31
+ # --- Set Declaration Part ---
32
+ declaration_updated = False
33
+ # Check if the content is actually provided (might be None/empty if only impl is set)
34
+ has_declaration_content = 'DECLARATION_CONTENT' in locals() or 'DECLARATION_CONTENT' in globals()
35
+ if has_declaration_content and DECLARATION_CONTENT is not None: # Check not None
36
+ if hasattr(target_object, 'textual_declaration'):
37
+ decl_obj = target_object.textual_declaration
38
+ if decl_obj and hasattr(decl_obj, 'replace'):
39
+ try:
40
+ print("DEBUG: Accessing textual_declaration...")
41
+ decl_obj.replace(DECLARATION_CONTENT)
42
+ print("DEBUG: Set declaration text using replace().")
43
+ declaration_updated = True
44
+ except Exception as decl_err:
45
+ print("ERROR: Failed to set declaration text: %s" % decl_err)
46
+ traceback.print_exc() # Print stack trace for detailed error
47
+ else:
48
+ print("WARN: Target '%s' textual_declaration attribute is None or does not have replace(). Skipping declaration update." % target_name)
49
+ else:
50
+ print("WARN: Target '%s' does not have textual_declaration attribute. Skipping declaration update." % target_name)
51
+ else:
52
+ print("DEBUG: Declaration content not provided or is None. Skipping declaration update.")
53
+
54
+
55
+ # --- Set Implementation Part ---
56
+ implementation_updated = False
57
+ has_implementation_content = 'IMPLEMENTATION_CONTENT' in locals() or 'IMPLEMENTATION_CONTENT' in globals()
58
+ if has_implementation_content and IMPLEMENTATION_CONTENT is not None: # Check not None
59
+ if hasattr(target_object, 'textual_implementation'):
60
+ impl_obj = target_object.textual_implementation
61
+ if impl_obj and hasattr(impl_obj, 'replace'):
62
+ try:
63
+ print("DEBUG: Accessing textual_implementation...")
64
+ impl_obj.replace(IMPLEMENTATION_CONTENT)
65
+ print("DEBUG: Set implementation text using replace().")
66
+ implementation_updated = True
67
+ except Exception as impl_err:
68
+ print("ERROR: Failed to set implementation text: %s" % impl_err)
69
+ traceback.print_exc() # Print stack trace for detailed error
70
+ else:
71
+ print("WARN: Target '%s' textual_implementation attribute is None or does not have replace(). Skipping implementation update." % target_name)
72
+ else:
73
+ print("WARN: Target '%s' does not have textual_implementation attribute. Skipping implementation update." % target_name)
74
+ else:
75
+ print("DEBUG: Implementation content not provided or is None. Skipping implementation update.")
76
+
77
+
78
+ # --- SAVE THE PROJECT TO PERSIST THE CODE CHANGE ---
79
+ # Only save if something was actually updated to avoid unnecessary saves
80
+ if declaration_updated or implementation_updated:
81
+ try:
82
+ print("DEBUG: Saving Project (after code change)...")
83
+ primary_project.save() # Save the overall project file
84
+ print("DEBUG: Project saved successfully after code change.")
85
+ except Exception as save_err:
86
+ print("ERROR: Failed to save Project after setting code: %s" % save_err)
87
+ detailed_error = traceback.format_exc()
88
+ error_message = "Error saving Project after code change for '%s': %s\\n%s" % (target_name, save_err, detailed_error)
89
+ print(error_message); print("SCRIPT_ERROR: %s" % error_message); sys.exit(1)
90
+ else:
91
+ print("DEBUG: No code parts were updated, skipping project save.")
92
+ # --- END SAVING ---
93
+
94
+ print("Code Set For: %s" % target_name)
95
+ print("Path: %s" % POU_FULL_PATH)
96
+ print("SCRIPT_SUCCESS: Declaration and/or implementation set successfully.")
97
+ sys.exit(0)
98
+
99
+ except Exception as e:
100
+ detailed_error = traceback.format_exc()
101
+ error_message = "Error setting code for object '%s' in project '%s': %s\\n%s" % (POU_FULL_PATH, PROJECT_FILE_PATH, e, detailed_error)
102
+ print(error_message)
103
+ print("SCRIPT_ERROR: %s" % error_message)
104
+ sys.exit(1)
@@ -1,13 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "WebFetch(domain:github.com)",
5
- "Bash(git add:*)",
6
- "Bash(git commit:*)",
7
- "Bash(grep:*)",
8
- "Bash(npm run build:*)",
9
- "Bash(ls:*)"
10
- ],
11
- "deny": []
12
- }
13
- }
package/CONTRIBUTING.md DELETED
@@ -1,72 +0,0 @@
1
- # Contributing to @codesys/mcp-toolkit
2
-
3
- Thank you for considering contributing to the CODESYS MCP Toolkit! This document provides guidelines and steps for contributing.
4
-
5
- ## Code of Conduct
6
-
7
- Please be respectful and considerate of others when contributing to this project. We aim to foster an inclusive and welcoming community.
8
-
9
- ## How Can I Contribute?
10
-
11
- ### Reporting Bugs
12
-
13
- Bug reports help improve the project! When reporting bugs:
14
-
15
- 1. Check if the bug has already been reported
16
- 2. Use the bug report template
17
- 3. Include detailed steps to reproduce the issue
18
- 4. Describe the expected vs. actual behavior
19
- 5. Include screenshots if applicable
20
- 6. Provide environment details (OS, Node.js version, etc.)
21
-
22
- ### Suggesting Features
23
-
24
- We welcome feature suggestions! When suggesting features:
25
-
26
- 1. Describe the problem your feature would solve
27
- 2. Explain how your feature would work
28
- 3. Consider potential alternatives
29
- 4. Provide examples of similar features in other projects (if applicable)
30
-
31
- ### Pull Requests
32
-
33
- 1. Fork the repository
34
- 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
35
- 3. Make your changes
36
- 4. Run tests and ensure they pass
37
- 5. Commit your changes (`git commit -m 'Add amazing feature'`)
38
- 6. Push to your branch (`git push origin feature/amazing-feature`)
39
- 7. Open a Pull Request
40
-
41
- ## Development Setup
42
-
43
- 1. Clone the repository
44
- ```bash
45
- git clone https://github.com/yourusername/codesys-mcp-toolkit.git
46
- cd codesys-mcp-toolkit
47
- ```
48
-
49
- 2. Install dependencies
50
- ```bash
51
- npm install
52
- ```
53
-
54
- 3. Build the project
55
- ```bash
56
- npm run build
57
- ```
58
-
59
- ## Style Guidelines
60
-
61
- - Follow existing code formatting patterns
62
- - Use meaningful variable and function names
63
- - Add comments where necessary to explain complex logic
64
- - Update documentation when changing functionality
65
-
66
- ## Testing
67
-
68
- - Add tests for new features
69
- - Ensure all tests pass before submitting a PR
70
- - Consider edge cases in your tests
71
-
72
- Thank you for contributing!