@codesys/mcp-toolkit 1.5.8 → 2.0.0-alpha.0
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 +153 -189
- package/LICENSE +21 -21
- package/README.md +224 -107
- package/dist/actions.d.ts +28 -0
- package/dist/actions.js +98 -0
- package/dist/actions.js.map +1 -0
- package/dist/bridge/bridge.d.ts +105 -0
- package/dist/bridge/bridge.js +400 -0
- package/dist/bridge/bridge.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +196 -0
- package/dist/cli.js.map +1 -0
- package/dist/codesys/cache.d.ts +48 -0
- package/dist/codesys/cache.js +82 -0
- package/dist/codesys/cache.js.map +1 -0
- package/dist/codesys/changes.d.ts +57 -0
- package/dist/codesys/changes.js +133 -0
- package/dist/codesys/changes.js.map +1 -0
- package/dist/codesys/decl.d.ts +45 -0
- package/dist/codesys/decl.js +251 -0
- package/dist/codesys/decl.js.map +1 -0
- package/dist/codesys/devices.d.ts +34 -0
- package/dist/codesys/devices.js +82 -0
- package/dist/codesys/devices.js.map +1 -0
- package/dist/codesys/diff.d.ts +13 -0
- package/dist/codesys/diff.js +61 -0
- package/dist/codesys/diff.js.map +1 -0
- package/dist/codesys/install.d.ts +40 -0
- package/dist/codesys/install.js +144 -0
- package/dist/codesys/install.js.map +1 -0
- package/dist/codesys/library-browse.d.ts +19 -0
- package/dist/codesys/library-browse.js +57 -0
- package/dist/codesys/library-browse.js.map +1 -0
- package/dist/codesys/outline.d.ts +32 -0
- package/dist/codesys/outline.js +219 -0
- package/dist/codesys/outline.js.map +1 -0
- package/dist/codesys/simulation.d.ts +34 -0
- package/dist/codesys/simulation.js +57 -0
- package/dist/codesys/simulation.js.map +1 -0
- package/dist/codesys/st.d.ts +36 -0
- package/dist/codesys/st.js +69 -0
- package/dist/codesys/st.js.map +1 -0
- package/dist/daemon.d.ts +46 -0
- package/dist/daemon.js +173 -0
- package/dist/daemon.js.map +1 -0
- package/dist/driver.d.ts +25 -0
- package/dist/driver.js +33 -0
- package/dist/driver.js.map +1 -0
- package/dist/panel/sim-panel.html +357 -0
- package/dist/panel/viewer.html +126 -0
- package/dist/panel-types.d.ts +20 -0
- package/dist/panel-types.js +3 -0
- package/dist/panel-types.js.map +1 -0
- package/dist/panel.d.ts +27 -0
- package/dist/panel.js +208 -0
- package/dist/panel.js.map +1 -0
- package/dist/server.d.ts +5 -0
- package/dist/server.js +33 -974
- package/dist/server.js.map +1 -0
- package/dist/tools.d.ts +103 -0
- package/dist/tools.js +793 -0
- package/dist/tools.js.map +1 -0
- package/dist/viewer.d.ts +14 -0
- package/dist/viewer.js +125 -0
- package/dist/viewer.js.map +1 -0
- package/package.json +37 -21
- package/watcher/mcp_compat.py +147 -0
- package/watcher/mcp_ops.py +1178 -0
- package/watcher/mcp_sim.py +246 -0
- package/watcher/watcher.py +255 -0
- package/.claude/settings.local.json +0 -29
- package/CLAUDE.md +0 -26
- package/CONTRIBUTING.md +0 -72
- package/README.md.enhanced +0 -155
- package/codesys-mcp-toolkit-1.2.0.tgz +0 -0
- package/codesys-mcp-toolkit-1.2.1.tgz +0 -0
- package/codesys-mcp-toolkit-1.5.7.tgz +0 -0
- package/codesys-mcp-toolkit-1.5.8.tgz +0 -0
- package/dist/bin.js +0 -75
- package/dist/check_session_paths.js +0 -149
- package/dist/codesys_interop.js +0 -435
- package/dist/direct_session_command.js +0 -293
- package/dist/scriptLoader.js +0 -165
- package/dist/scripts/check_status.py +0 -21
- package/dist/scripts/compile_project.py +0 -65
- package/dist/scripts/create_method.py +0 -80
- package/dist/scripts/create_pou.py +0 -102
- package/dist/scripts/create_project.py +0 -116
- package/dist/scripts/create_property.py +0 -78
- package/dist/scripts/ensure_project_open.py +0 -154
- package/dist/scripts/find_object_by_path.py +0 -111
- package/dist/scripts/get_pou_code.py +0 -91
- package/dist/scripts/get_project_structure.py +0 -72
- package/dist/scripts/open_project.py +0 -25
- package/dist/scripts/save_project.py +0 -29
- package/dist/scripts/session_status.py +0 -281
- package/dist/scripts/set_pou_code.py +0 -109
- package/dist/scripts/start_session.py +0 -809
- package/dist/scripts/stop_session.py +0 -324
- package/dist/sessionManager.js +0 -798
- package/docs/configuration.md +0 -141
- package/docs/index.md +0 -26
- package/docs/installation.md +0 -84
- package/docs/session_management.md +0 -110
- package/examples/README.md +0 -78
- package/examples/sample_config.json +0 -32
- package/replacements_session_status.txt +0 -16
- package/scriptDoc.txt +0 -8679
- package/scripts/build.js +0 -25
- package/scripts/fix_fstrings.py +0 -76
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** The device tree and its I/O mapping, as CODESYS exports it. Pure: parsing and formatting only. */
|
|
2
|
+
export interface DeviceInfo {
|
|
3
|
+
/** Path from the project root, e.g. "Device/Plc Logic/..." or "PLCWinNT/EtherCAT_Master/EL1008". */
|
|
4
|
+
path: string;
|
|
5
|
+
name: string;
|
|
6
|
+
depth: number;
|
|
7
|
+
type?: number | null;
|
|
8
|
+
id?: string;
|
|
9
|
+
version?: string;
|
|
10
|
+
enabled?: boolean | null;
|
|
11
|
+
/** The device's I/O mapping in CODESYS's CSV export format (only when it has channels). */
|
|
12
|
+
io_csv?: string;
|
|
13
|
+
io_error?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface IoChannel {
|
|
16
|
+
/** The mapped variable, e.g. "Application.GVL_IO.xValve"; empty when nothing is mapped. */
|
|
17
|
+
variable: string;
|
|
18
|
+
/** "Parameter name @ counter in device", e.g. "Input@1" or "Bit0@3". */
|
|
19
|
+
parameter: string;
|
|
20
|
+
unit: string;
|
|
21
|
+
description: string;
|
|
22
|
+
/** IEC address, e.g. "%IX0.0". */
|
|
23
|
+
address: string;
|
|
24
|
+
device: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parse CODESYS's I/O mapping export ("//CoDeSys Mapping Export V1.2"): comment lines start
|
|
28
|
+
* with "//"; the column header names "Mapped variable", "Parameter name @ counter in device",
|
|
29
|
+
* "Unit", "Description", "IEC address", "Device name". The separator is taken from that header.
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseIoMappingCsv(text: string): IoChannel[];
|
|
32
|
+
/** "Application.GVL_IO.xValve" -> "GVL_IO.xValve" (the toolkit's paths are relative to the application). */
|
|
33
|
+
export declare const shortVariable: (v: string) => string;
|
|
34
|
+
export declare function describeDevices(devices: DeviceInfo[]): string;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/** The device tree and its I/O mapping, as CODESYS exports it. Pure: parsing and formatting only. */
|
|
2
|
+
/** Split one CSV line, honouring double quotes. */
|
|
3
|
+
function splitCsv(line, sep) {
|
|
4
|
+
const out = [];
|
|
5
|
+
let cur = "";
|
|
6
|
+
let quoted = false;
|
|
7
|
+
for (let i = 0; i < line.length; i++) {
|
|
8
|
+
const c = line[i];
|
|
9
|
+
if (c === '"') {
|
|
10
|
+
if (quoted && line[i + 1] === '"') {
|
|
11
|
+
cur += '"';
|
|
12
|
+
i++;
|
|
13
|
+
}
|
|
14
|
+
else
|
|
15
|
+
quoted = !quoted;
|
|
16
|
+
}
|
|
17
|
+
else if (c === sep && !quoted) {
|
|
18
|
+
out.push(cur);
|
|
19
|
+
cur = "";
|
|
20
|
+
}
|
|
21
|
+
else
|
|
22
|
+
cur += c;
|
|
23
|
+
}
|
|
24
|
+
out.push(cur);
|
|
25
|
+
return out.map((s) => s.trim());
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parse CODESYS's I/O mapping export ("//CoDeSys Mapping Export V1.2"): comment lines start
|
|
29
|
+
* with "//"; the column header names "Mapped variable", "Parameter name @ counter in device",
|
|
30
|
+
* "Unit", "Description", "IEC address", "Device name". The separator is taken from that header.
|
|
31
|
+
*/
|
|
32
|
+
export function parseIoMappingCsv(text) {
|
|
33
|
+
const lines = text.split(/\r?\n/);
|
|
34
|
+
const header = lines.find((l) => /mapped variable/i.test(l)) ?? "";
|
|
35
|
+
const sep = [";", "\t", ","].find((s) => header.includes(s)) ?? ",";
|
|
36
|
+
const names = splitCsv(header, sep).map((h) => h.replace(/^\/\//, "").trim().toLowerCase());
|
|
37
|
+
const col = (re, fallback) => {
|
|
38
|
+
const i = names.findIndex((n) => re.test(n));
|
|
39
|
+
return i >= 0 ? i : fallback;
|
|
40
|
+
};
|
|
41
|
+
const at = {
|
|
42
|
+
variable: col(/^mapped variable/, 0),
|
|
43
|
+
parameter: col(/^parameter/, 1),
|
|
44
|
+
unit: col(/^unit/, 2),
|
|
45
|
+
description: col(/^description/, 3),
|
|
46
|
+
address: col(/address$/, 4),
|
|
47
|
+
device: col(/^device/, 5),
|
|
48
|
+
};
|
|
49
|
+
const out = [];
|
|
50
|
+
for (const l of lines) {
|
|
51
|
+
if (!l.trim() || l.startsWith("//"))
|
|
52
|
+
continue;
|
|
53
|
+
const c = splitCsv(l, sep);
|
|
54
|
+
out.push({
|
|
55
|
+
variable: c[at.variable] ?? "",
|
|
56
|
+
parameter: c[at.parameter] ?? "",
|
|
57
|
+
unit: c[at.unit] ?? "",
|
|
58
|
+
description: c[at.description] ?? "",
|
|
59
|
+
address: c[at.address] ?? "",
|
|
60
|
+
device: c[at.device] ?? "",
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
/** "Application.GVL_IO.xValve" -> "GVL_IO.xValve" (the toolkit's paths are relative to the application). */
|
|
66
|
+
export const shortVariable = (v) => v.replace(/^[A-Za-z_][A-Za-z0-9_]*\.(?=[A-Za-z_][A-Za-z0-9_]*\.)/, "");
|
|
67
|
+
export function describeDevices(devices) {
|
|
68
|
+
if (!devices.length)
|
|
69
|
+
return "No devices in the project.";
|
|
70
|
+
const lines = [];
|
|
71
|
+
for (const d of devices) {
|
|
72
|
+
const ident = d.id ? ` (type ${d.type ?? "?"}, id ${d.id}, version ${d.version ?? "?"})` : "";
|
|
73
|
+
const channels = d.io_csv ? parseIoMappingCsv(d.io_csv) : [];
|
|
74
|
+
const mapped = channels.filter((c) => c.variable).length;
|
|
75
|
+
lines.push(`${" ".repeat(d.depth)}${d.name}${ident}${d.enabled === false ? " [disabled]" : ""}${channels.length ? `: ${channels.length} channel(s), ${mapped} mapped` : ""}${d.io_error ? ` (I/O mapping not readable: ${d.io_error})` : ""}`);
|
|
76
|
+
for (const c of channels) {
|
|
77
|
+
lines.push(`${" ".repeat(d.depth + 1)}${(c.address || "-").padEnd(10)} ${c.parameter}${c.description ? ` ${c.description}` : ""}${c.unit ? ` [${c.unit}]` : ""} -> ${c.variable ? shortVariable(c.variable) : "(not mapped)"}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return lines.join("\n");
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=devices.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"devices.js","sourceRoot":"","sources":["../../src/codesys/devices.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Line diff (LCS) and unified-style formatting. Pure: also bundled into the panel. */
|
|
2
|
+
export type DiffOp = {
|
|
3
|
+
op: " " | "+" | "-";
|
|
4
|
+
text: string;
|
|
5
|
+
};
|
|
6
|
+
/** Line diff (LCS). Falls back to remove-all/add-all for very large inputs. */
|
|
7
|
+
export declare function lineDiff(a: string, b: string): DiffOp[];
|
|
8
|
+
export declare const countDiff: (ops: DiffOp[]) => {
|
|
9
|
+
plus: number;
|
|
10
|
+
minus: number;
|
|
11
|
+
};
|
|
12
|
+
/** Unified-style hunks with line numbers of the new text and `context` lines around changes. */
|
|
13
|
+
export declare function formatDiff(ops: DiffOp[], context?: number): string[];
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/** Line diff (LCS) and unified-style formatting. Pure: also bundled into the panel. */
|
|
2
|
+
/** Line diff (LCS). Falls back to remove-all/add-all for very large inputs. */
|
|
3
|
+
export function lineDiff(a, b) {
|
|
4
|
+
const x = a ? a.split("\n") : [];
|
|
5
|
+
const y = b ? b.split("\n") : [];
|
|
6
|
+
if (x.length * y.length > 4_000_000)
|
|
7
|
+
return [...x.map((t) => ({ op: "-", text: t })), ...y.map((t) => ({ op: "+", text: t }))];
|
|
8
|
+
const n = x.length;
|
|
9
|
+
const m = y.length;
|
|
10
|
+
const L = Array.from({ length: n + 1 }, () => new Uint32Array(m + 1));
|
|
11
|
+
for (let i = n - 1; i >= 0; i--)
|
|
12
|
+
for (let j = m - 1; j >= 0; j--)
|
|
13
|
+
L[i][j] = x[i] === y[j] ? L[i + 1][j + 1] + 1 : Math.max(L[i + 1][j], L[i][j + 1]);
|
|
14
|
+
const ops = [];
|
|
15
|
+
let i = 0;
|
|
16
|
+
let j = 0;
|
|
17
|
+
while (i < n && j < m) {
|
|
18
|
+
if (x[i] === y[j]) {
|
|
19
|
+
ops.push({ op: " ", text: x[i] });
|
|
20
|
+
i++;
|
|
21
|
+
j++;
|
|
22
|
+
}
|
|
23
|
+
else if (L[i + 1][j] >= L[i][j + 1])
|
|
24
|
+
ops.push({ op: "-", text: x[i++] });
|
|
25
|
+
else
|
|
26
|
+
ops.push({ op: "+", text: y[j++] });
|
|
27
|
+
}
|
|
28
|
+
while (i < n)
|
|
29
|
+
ops.push({ op: "-", text: x[i++] });
|
|
30
|
+
while (j < m)
|
|
31
|
+
ops.push({ op: "+", text: y[j++] });
|
|
32
|
+
return ops;
|
|
33
|
+
}
|
|
34
|
+
export const countDiff = (ops) => ({ plus: ops.filter((o) => o.op === "+").length, minus: ops.filter((o) => o.op === "-").length });
|
|
35
|
+
/** Unified-style hunks with line numbers of the new text and `context` lines around changes. */
|
|
36
|
+
export function formatDiff(ops, context = 2) {
|
|
37
|
+
const out = [];
|
|
38
|
+
let newLine = 0;
|
|
39
|
+
const numbered = ops.map((o) => {
|
|
40
|
+
if (o.op !== "-")
|
|
41
|
+
newLine++;
|
|
42
|
+
return { ...o, line: o.op === "-" ? undefined : newLine };
|
|
43
|
+
});
|
|
44
|
+
const keep = new Set();
|
|
45
|
+
numbered.forEach((o, k) => {
|
|
46
|
+
if (o.op !== " ")
|
|
47
|
+
for (let d = -context; d <= context; d++)
|
|
48
|
+
keep.add(k + d);
|
|
49
|
+
});
|
|
50
|
+
let last = -2;
|
|
51
|
+
numbered.forEach((o, k) => {
|
|
52
|
+
if (!keep.has(k))
|
|
53
|
+
return;
|
|
54
|
+
if (k !== last + 1 && out.length)
|
|
55
|
+
out.push(" ...");
|
|
56
|
+
out.push(`${o.op} ${o.line !== undefined ? String(o.line).padStart(4) : " "} | ${o.text}`);
|
|
57
|
+
last = k;
|
|
58
|
+
});
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/codesys/diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export interface CodesysInstall {
|
|
2
|
+
/** Full path to CODESYS.exe */
|
|
3
|
+
exe: string;
|
|
4
|
+
/** Profile names found in the Profiles folder, newest first. */
|
|
5
|
+
profiles: string[];
|
|
6
|
+
/** Templates folder (holds Standard.project), if present. */
|
|
7
|
+
templatesDir?: string;
|
|
8
|
+
/** Install folder name, e.g. "CODESYS 3.5.21.0". */
|
|
9
|
+
label: string;
|
|
10
|
+
/** Add-on folder passed as --additionalfolder (SP22 and later). */
|
|
11
|
+
additionalFolder?: string;
|
|
12
|
+
}
|
|
13
|
+
/** The workspace folder: created when missing, with a clear error when it can't be used. */
|
|
14
|
+
export declare function ensureWorkspace(dir: string, log: (m: string) => void): string;
|
|
15
|
+
/**
|
|
16
|
+
* The add-on folder CODESYS's own shortcuts start this install with
|
|
17
|
+
* (`--additionalfolder`). SP22 installs add-ons such as Scripting there:
|
|
18
|
+
* `<CODESYS>\AdditionalFolders\Default`, or the only folder in AdditionalFolders.
|
|
19
|
+
*/
|
|
20
|
+
export declare function findAdditionalFolder(base: string): string | undefined;
|
|
21
|
+
export declare function describeInstall(exe: string, additionalFolder?: string): CodesysInstall;
|
|
22
|
+
/** Scan Program Files for CODESYS installs (Windows only). */
|
|
23
|
+
export declare function findInstalls(): CodesysInstall[];
|
|
24
|
+
/** "CODESYS V3.5 SP22 Patch 1" -> a key that sorts numerically (SP9 < SP21 < SP22 < SP22 Patch 1). */
|
|
25
|
+
export declare function profileKey(name: string): string;
|
|
26
|
+
/** Newest profile first; names without a version last, alphabetically. */
|
|
27
|
+
export declare function compareProfiles(a: string, b: string): number;
|
|
28
|
+
export interface ResolvedCodesys {
|
|
29
|
+
exe: string;
|
|
30
|
+
profile: string;
|
|
31
|
+
install: CodesysInstall;
|
|
32
|
+
/** Why this install was picked, for the log. */
|
|
33
|
+
reason: string;
|
|
34
|
+
/** Something to log about the profile, when it couldn't be confirmed. */
|
|
35
|
+
warning?: string;
|
|
36
|
+
}
|
|
37
|
+
/** Pick the CODESYS exe + profile from options, falling back to the newest install. */
|
|
38
|
+
export declare function resolveCodesys(exe?: string, profile?: string, additionalFolder?: string): ResolvedCodesys;
|
|
39
|
+
/** "newest of 2 installs found (CODESYS 3.5.22.40, CODESYS 3.5.21.0); --codesys-path picks another" */
|
|
40
|
+
export declare function pickedNewest(labels: string[]): string;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/** Find CODESYS installations, their profiles and project templates. */
|
|
2
|
+
import { existsSync, mkdirSync, readdirSync, statSync } from "node:fs";
|
|
3
|
+
import { basename, dirname, join } from "node:path";
|
|
4
|
+
const isCodesysExe = (exe) => basename(exe).toLowerCase() === "codesys.exe";
|
|
5
|
+
/**
|
|
6
|
+
* The folder holding an install's Profiles and Templates. CODESYS keeps them
|
|
7
|
+
* two levels above the program (`<root>\CODESYS\Common\CODESYS.exe`). Products
|
|
8
|
+
* built on CODESYS can lay this out differently, so look a few levels up.
|
|
9
|
+
*/
|
|
10
|
+
function installBase(exe) {
|
|
11
|
+
let dir = dirname(exe);
|
|
12
|
+
for (let level = 0; level < 3; level++) {
|
|
13
|
+
for (const base of [dir, join(dir, "CODESYS")])
|
|
14
|
+
if (existsSync(join(base, "Profiles")))
|
|
15
|
+
return base;
|
|
16
|
+
dir = dirname(dir);
|
|
17
|
+
}
|
|
18
|
+
return dirname(dirname(exe));
|
|
19
|
+
}
|
|
20
|
+
/** The workspace folder: created when missing, with a clear error when it can't be used. */
|
|
21
|
+
export function ensureWorkspace(dir, log) {
|
|
22
|
+
try {
|
|
23
|
+
if (existsSync(dir)) {
|
|
24
|
+
if (!statSync(dir).isDirectory())
|
|
25
|
+
throw new Error("it is a file, not a folder");
|
|
26
|
+
return dir;
|
|
27
|
+
}
|
|
28
|
+
mkdirSync(dir, { recursive: true });
|
|
29
|
+
log(`created the workspace folder ${dir}`);
|
|
30
|
+
return dir;
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
throw new Error(`Can't use the workspace ${dir}: ${e.message}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The add-on folder CODESYS's own shortcuts start this install with
|
|
38
|
+
* (`--additionalfolder`). SP22 installs add-ons such as Scripting there:
|
|
39
|
+
* `<CODESYS>\AdditionalFolders\Default`, or the only folder in AdditionalFolders.
|
|
40
|
+
*/
|
|
41
|
+
export function findAdditionalFolder(base) {
|
|
42
|
+
const root = join(base, "AdditionalFolders");
|
|
43
|
+
if (!existsSync(root))
|
|
44
|
+
return undefined;
|
|
45
|
+
const dirs = readdirSync(root, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
46
|
+
const pick = dirs.find((d) => d.toLowerCase() === "default") ?? (dirs.length === 1 ? dirs[0] : undefined);
|
|
47
|
+
return pick ? join(root, pick) : undefined;
|
|
48
|
+
}
|
|
49
|
+
function profilesIn(dir) {
|
|
50
|
+
const profilesDir = join(dir, "Profiles");
|
|
51
|
+
if (!existsSync(profilesDir))
|
|
52
|
+
return [];
|
|
53
|
+
return readdirSync(profilesDir)
|
|
54
|
+
.filter((f) => f.toLowerCase().endsWith(".profile.xml"))
|
|
55
|
+
.map((f) => f.slice(0, -".profile.xml".length));
|
|
56
|
+
}
|
|
57
|
+
export function describeInstall(exe, additionalFolder) {
|
|
58
|
+
const base = installBase(exe);
|
|
59
|
+
const extra = additionalFolder ?? findAdditionalFolder(base);
|
|
60
|
+
const profiles = [...new Set([...profilesIn(base), ...(extra ? profilesIn(extra) : [])])].sort(compareProfiles);
|
|
61
|
+
const templatesDir = join(base, "Templates");
|
|
62
|
+
return {
|
|
63
|
+
exe,
|
|
64
|
+
profiles,
|
|
65
|
+
templatesDir: existsSync(templatesDir) ? templatesDir : undefined,
|
|
66
|
+
label: isCodesysExe(exe) ? (dirname(base).split(/[\\/]/).pop() ?? base) : dirname(exe).split(/[\\/]/).slice(-2).join(" "),
|
|
67
|
+
...(extra ? { additionalFolder: extra } : {}),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/** Scan Program Files for CODESYS installs (Windows only). */
|
|
71
|
+
export function findInstalls() {
|
|
72
|
+
const roots = [process.env["ProgramFiles"], process.env["ProgramFiles(x86)"], process.env["ProgramW6432"]]
|
|
73
|
+
.filter((r) => !!r)
|
|
74
|
+
.filter((r, i, a) => a.indexOf(r) === i);
|
|
75
|
+
const found = [];
|
|
76
|
+
for (const root of roots) {
|
|
77
|
+
if (!existsSync(root))
|
|
78
|
+
continue;
|
|
79
|
+
for (const dir of readdirSync(root)) {
|
|
80
|
+
if (!/^codesys/i.test(dir))
|
|
81
|
+
continue;
|
|
82
|
+
const exe = join(root, dir, "CODESYS", "Common", "CODESYS.exe");
|
|
83
|
+
if (existsSync(exe))
|
|
84
|
+
found.push(describeInstall(exe));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Newest version first ("CODESYS 3.5.21.0" > "CODESYS 3.5.19.50").
|
|
88
|
+
return found.sort((a, b) => versionKey(b.label).localeCompare(versionKey(a.label)));
|
|
89
|
+
}
|
|
90
|
+
/** "CODESYS V3.5 SP22 Patch 1" -> a key that sorts numerically (SP9 < SP21 < SP22 < SP22 Patch 1). */
|
|
91
|
+
export function profileKey(name) {
|
|
92
|
+
const m = /V(\d+)\.(\d+)(?:\.(\d+))?(?:\s*SP\s*(\d+))?(?:\s*Patch\s*(\d+))?/i.exec(name);
|
|
93
|
+
if (!m)
|
|
94
|
+
return "";
|
|
95
|
+
return [m[1], m[2], m[3], m[4], m[5]].map((n) => (n ?? "0").padStart(4, "0")).join(".");
|
|
96
|
+
}
|
|
97
|
+
/** Newest profile first; names without a version last, alphabetically. */
|
|
98
|
+
export function compareProfiles(a, b) {
|
|
99
|
+
return profileKey(b).localeCompare(profileKey(a)) || a.localeCompare(b);
|
|
100
|
+
}
|
|
101
|
+
function versionKey(label) {
|
|
102
|
+
const m = label.match(/(\d+)\.(\d+)\.(\d+)\.(\d+)/);
|
|
103
|
+
return m ? m.slice(1).map((n) => n.padStart(4, "0")).join(".") : label;
|
|
104
|
+
}
|
|
105
|
+
/** Pick the CODESYS exe + profile from options, falling back to the newest install. */
|
|
106
|
+
export function resolveCodesys(exe, profile, additionalFolder) {
|
|
107
|
+
if (additionalFolder && !existsSync(additionalFolder))
|
|
108
|
+
throw new Error(`CODESYS additional folder not found: ${additionalFolder}`);
|
|
109
|
+
let install;
|
|
110
|
+
let reason;
|
|
111
|
+
if (exe) {
|
|
112
|
+
if (!existsSync(exe))
|
|
113
|
+
throw new Error(`CODESYS executable not found: ${exe}`);
|
|
114
|
+
install = describeInstall(exe, additionalFolder);
|
|
115
|
+
reason = "set with --codesys-path";
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
const all = findInstalls();
|
|
119
|
+
const withProfile = profile ? all.find((i) => i.profiles.includes(profile)) : undefined;
|
|
120
|
+
install = withProfile ?? all[0];
|
|
121
|
+
if (!install)
|
|
122
|
+
throw new Error("No CODESYS installation found. Pass --codesys-path <...\\CODESYS\\Common\\CODESYS.exe>.");
|
|
123
|
+
reason = withProfile ? `it has profile "${profile}"` : pickedNewest(all.map((i) => i.label));
|
|
124
|
+
if (additionalFolder)
|
|
125
|
+
install = { ...install, additionalFolder };
|
|
126
|
+
}
|
|
127
|
+
const prof = profile ?? install.profiles[0];
|
|
128
|
+
if (!prof)
|
|
129
|
+
throw new Error(`No CODESYS profile found next to ${install.exe}. Pass --codesys-profile "<name>".`);
|
|
130
|
+
let warning;
|
|
131
|
+
if (profile && !install.profiles.some((p) => p.toLowerCase() === profile.toLowerCase())) {
|
|
132
|
+
const known = install.profiles.join(", ");
|
|
133
|
+
// Only CODESYS.exe is known to name its profiles after these files; other products get the benefit of the doubt.
|
|
134
|
+
if (known && isCodesysExe(install.exe))
|
|
135
|
+
throw new Error(`Profile "${profile}" isn't installed next to ${install.exe}. Installed profiles: ${known}.`);
|
|
136
|
+
warning = known ? `profile "${profile}" isn't among those found next to ${install.exe} (${known}); trying it anyway` : `no Profiles folder found near ${install.exe}, so profile "${profile}" can't be checked`;
|
|
137
|
+
}
|
|
138
|
+
return { exe: install.exe, profile: prof, install, reason, ...(warning ? { warning } : {}) };
|
|
139
|
+
}
|
|
140
|
+
/** "newest of 2 installs found (CODESYS 3.5.22.40, CODESYS 3.5.21.0); --codesys-path picks another" */
|
|
141
|
+
export function pickedNewest(labels) {
|
|
142
|
+
return labels.length === 1 ? "the only install found" : `newest of ${labels.length} installs found (${labels.join(", ")}); --codesys-path picks another`;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/codesys/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface BrowseEntry {
|
|
2
|
+
name: string;
|
|
3
|
+
comment?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface InstalledLibrary {
|
|
6
|
+
title: string;
|
|
7
|
+
version: string;
|
|
8
|
+
company: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function parseBrowseCache(xml: string): BrowseEntry[];
|
|
11
|
+
/** The newest of several installed versions, compared as numbers (3.5.22 is newer than 3.5.9). */
|
|
12
|
+
export declare function newestLibrary<T extends {
|
|
13
|
+
version: string;
|
|
14
|
+
}>(libs: T[]): T | undefined;
|
|
15
|
+
/** The library's browse cache in one of the repositories CODESYS reports. */
|
|
16
|
+
export declare function browseCacheFile(repositories: string[], lib: InstalledLibrary): string | undefined;
|
|
17
|
+
export declare function readBrowseCache(file: string): BrowseEntry[];
|
|
18
|
+
/** A library's objects as text; `symbol` narrows it to names or descriptions containing that text. */
|
|
19
|
+
export declare function describeBrowse(head: string, entries: BrowseEntry[], symbol?: string, maxLines?: number): string;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What CODESYS's own library browser knows about an installed library. Each
|
|
3
|
+
* library in a repository has a `browsercache` XML file listing its objects
|
|
4
|
+
* and their descriptions. Scripting can't read a compiled library's contents,
|
|
5
|
+
* and this works for libraries the project doesn't reference yet.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
const decode = (s) => s
|
|
10
|
+
.replace(/</g, "<")
|
|
11
|
+
.replace(/>/g, ">")
|
|
12
|
+
.replace(/"/g, '"')
|
|
13
|
+
.replace(/'/g, "'")
|
|
14
|
+
.replace(/&#x([0-9a-fA-F]+);/g, (_, h) => String.fromCodePoint(parseInt(h, 16)))
|
|
15
|
+
.replace(/&#(\d+);/g, (_, d) => String.fromCodePoint(parseInt(d, 10)))
|
|
16
|
+
.replace(/&/g, "&");
|
|
17
|
+
export function parseBrowseCache(xml) {
|
|
18
|
+
const out = [];
|
|
19
|
+
for (const node of xml.matchAll(/<Node\s+([^>]*?)\/?>/g)) {
|
|
20
|
+
const attrs = new Map([...node[1].matchAll(/(\w+)="([^"]*)"/g)].map((a) => [a[1], decode(a[2])]));
|
|
21
|
+
const name = attrs.get("Name");
|
|
22
|
+
if (!name)
|
|
23
|
+
continue;
|
|
24
|
+
const comment = attrs.get("Comment")?.trim().replace(/\s+/g, " ");
|
|
25
|
+
out.push({ name, ...(comment ? { comment } : {}) });
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
const versionParts = (v) => v.split(".").map((n) => Number.parseInt(n, 10) || 0);
|
|
30
|
+
/** The newest of several installed versions, compared as numbers (3.5.22 is newer than 3.5.9). */
|
|
31
|
+
export function newestLibrary(libs) {
|
|
32
|
+
return [...libs].sort((a, b) => {
|
|
33
|
+
const [x, y] = [versionParts(a.version), versionParts(b.version)];
|
|
34
|
+
for (let i = 0; i < Math.max(x.length, y.length); i++)
|
|
35
|
+
if ((x[i] ?? 0) !== (y[i] ?? 0))
|
|
36
|
+
return (y[i] ?? 0) - (x[i] ?? 0);
|
|
37
|
+
return 0;
|
|
38
|
+
})[0];
|
|
39
|
+
}
|
|
40
|
+
/** The library's browse cache in one of the repositories CODESYS reports. */
|
|
41
|
+
export function browseCacheFile(repositories, lib) {
|
|
42
|
+
return repositories.map((root) => join(root, lib.company, lib.title, lib.version, "browsercache")).find((f) => existsSync(f));
|
|
43
|
+
}
|
|
44
|
+
export function readBrowseCache(file) {
|
|
45
|
+
return parseBrowseCache(readFileSync(file, "utf8"));
|
|
46
|
+
}
|
|
47
|
+
/** A library's objects as text; `symbol` narrows it to names or descriptions containing that text. */
|
|
48
|
+
export function describeBrowse(head, entries, symbol, maxLines = 300) {
|
|
49
|
+
const want = symbol?.toLowerCase();
|
|
50
|
+
const shown = want ? entries.filter((e) => e.name.toLowerCase().includes(want) || e.comment?.toLowerCase().includes(want)) : entries;
|
|
51
|
+
if (want && !shown.length)
|
|
52
|
+
return `${head} has nothing matching '${symbol}'.`;
|
|
53
|
+
const lines = shown.slice(0, maxLines).map((e) => `- ${e.name}${e.comment ? ` :: ${e.comment}` : ""}`);
|
|
54
|
+
const more = shown.length > maxLines ? [`... ${shown.length - maxLines} more. Pass symbol to narrow it.`] : [];
|
|
55
|
+
return [`${head}: ${want ? `${shown.length} of ` : ""}${entries.length} objects, from CODESYS's library browser. Parameters aren't listed here; test a call with compile.`, ...lines, ...more].join("\n");
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=library-browse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"library-browse.js","sourceRoot":"","sources":["../../src/codesys/library-browse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project outline for the model: what exists, how to call it, and what runs
|
|
3
|
+
* it, without reading every object. Built from the CODESYS export (all ST
|
|
4
|
+
* text in one call) and the task list.
|
|
5
|
+
*/
|
|
6
|
+
import type { TreeNode } from "./st.js";
|
|
7
|
+
export interface OutlineTask {
|
|
8
|
+
name: string;
|
|
9
|
+
interval?: string | null;
|
|
10
|
+
interval_unit?: string | null;
|
|
11
|
+
priority?: string | null;
|
|
12
|
+
kind?: string | null;
|
|
13
|
+
pous: string[];
|
|
14
|
+
}
|
|
15
|
+
export interface OutlineOptions {
|
|
16
|
+
/** An object or folder path: details for an object, an overview of a folder. */
|
|
17
|
+
path?: string;
|
|
18
|
+
/** Max lines of output (default 400). */
|
|
19
|
+
maxLines?: number;
|
|
20
|
+
}
|
|
21
|
+
export declare function buildOutline(nodes: TreeNode[], tasks: OutlineTask[], o?: OutlineOptions): string;
|
|
22
|
+
export interface IoEntry {
|
|
23
|
+
owner: string;
|
|
24
|
+
name: string;
|
|
25
|
+
at: string;
|
|
26
|
+
type: string;
|
|
27
|
+
direction: "input" | "output" | "memory";
|
|
28
|
+
comment?: string;
|
|
29
|
+
placeholder: boolean;
|
|
30
|
+
}
|
|
31
|
+
/** Variables with AT addresses (including the %I* and %Q* placeholders), from GVLs and POUs. */
|
|
32
|
+
export declare function ioList(nodes: TreeNode[]): IoEntry[];
|