From 888a035c0c2ee13dbcceb52dbb0ca818bac16341 Mon Sep 17 00:00:00 2001 From: Karstein Phobic Nyvold Kvistad Date: Sun, 26 Apr 2026 19:18:31 +0200 Subject: [PATCH] feat(list_project_libraries): capture project compiler version Calls primary_project.get_compilerversion() (ScriptEngine 4.2.0.0+) and emits the result through the JSON payload. Renders as: - library.md: a 'Project compiler version' row in the Versions table - list_project_libraries chat output: a 'Compiler version: X.Y.Z.W' line in the header section Motivation: changing the project's compiler version (Project > Project Settings > Compiler version, or set_compilerversion_to_newest()) only touched the .project binary -- mirror_export couldn't see it, so the release classifier had to fall back to SHA comparison and emitted the generic 'device-tree / library refs / task config / visu / Save() touch' classification. Compiler-version changes now leave a textual diff in mcp-mirror/library.md, letting the classifier issue an honest revision bump instead of the bare build-bump SHA fallback. Defensive: get_compilerversion() is wrapped in try/except so older ScriptEngines (< 4.2.0.0) that lack the method don't crash the tool; they just emit compiler_version=null and the field is omitted from output. --- src/scripts/list_project_libraries.py | 15 +++++++++++++++ src/server.ts | 7 ++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/scripts/list_project_libraries.py b/src/scripts/list_project_libraries.py index 87665b4..a9d9953 100644 --- a/src/scripts/list_project_libraries.py +++ b/src/scripts/list_project_libraries.py @@ -160,7 +160,21 @@ try: project_info = collect_project_info(primary_project) devices = collect_devices(primary_project) ide_version = sys.version # IronPython under CODESYS reports the IDE + # Project-wide compiler version selector. Available since ScriptEngine + # 4.2.0.0; older IDEs return None / raise. Captured here so a manual + # change in the IDE ("Project > Project Settings > Compiler version") + # leaves a textual trace in mcp-mirror/library.md instead of being + # invisible to the release classifier (binary-only diff -> SHA fallback). + compiler_version = None + try: + if hasattr(primary_project, 'get_compilerversion'): + cv = primary_project.get_compilerversion() + if cv is not None: + compiler_version = str(cv) + except Exception as e: + print("DEBUG: get_compilerversion() failed: %s" % e) print("DEBUG: project_info: %s" % project_info) + print("DEBUG: compiler_version: %s" % compiler_version) print("DEBUG: %d device(s) found." % len(devices)) containers = find_libman_containers(primary_project) @@ -170,6 +184,7 @@ try: 'project': project_basename, 'project_info': project_info, 'ide_version': ide_version, + 'compiler_version': compiler_version, 'devices': devices, 'containers': [], 'total_references': 0, diff --git a/src/server.ts b/src/server.ts index f10bab8..4ec9a9c 100644 --- a/src/server.ts +++ b/src/server.ts @@ -253,7 +253,7 @@ interface ContainerData { interface LibrariesData { project?: string; project_info?: { version?: string | null; title?: string | null; company?: string | null; author?: string | null }; - ide_version?: string; devices?: DeviceData[]; containers: ContainerData[]; total_references: number; + ide_version?: string; compiler_version?: string | null; devices?: DeviceData[]; containers: ContainerData[]; total_references: number; } interface PouEntry { path: string; type?: string; declaration?: string; implementation?: string; } @@ -273,6 +273,7 @@ function renderLibraryMd(libs: LibrariesData, runtimeAnchorVersion?: string): st if (pi.company) L.push(`| Project Information.Company | ${pi.company} |`); if (pi.author) L.push(`| Project Information.Author | ${pi.author} |`); if (libs.ide_version) L.push(`| CODESYS Development System | \`${libs.ide_version.replace(/\s+/g, ' ').trim()}\` |`); + if (libs.compiler_version) L.push(`| Project compiler version | \`${libs.compiler_version}\` |`); if (runtimeAnchorVersion) L.push(`| Runtime anchor | \`_MCP_PROJECT_VERSION.sVersion := "${runtimeAnchorVersion}"\` |`); L.push(''); if (libs.devices && libs.devices.length > 0) { @@ -1692,6 +1693,7 @@ export async function startMcpServer(config: ServerConfig): Promise { project?: string; project_info?: ProjectInfo; ide_version?: string; + compiler_version?: string | null; devices?: Device[]; containers: Container[]; total_references: number; @@ -1760,6 +1762,9 @@ export async function startMcpServer(config: ServerConfig): Promise { if (parsed.ide_version) { headerLines.push(`IDE: ${parsed.ide_version.replace(/\s+/g, ' ').trim()}`); } + if (parsed.compiler_version) { + headerLines.push(`Compiler version: ${parsed.compiler_version}`); + } if (parsed.devices && parsed.devices.length > 0) { headerLines.push(`Devices (${parsed.devices.length}):`); for (const d of parsed.devices) {