vitest tests/integration/e2e.test.ts:
- 10 new template-prep assertions, one per Symbol Configuration tool.
Each asserts no leftover {PLACEHOLDER} in the rendered script and
that the relevant CODESYS API method names appear (get_all_signatures,
application.create_symbol_config, configured_access, etc.).
- Drive-by: fix the existing add_library e2e test that was missing the
ALLOW_UNRESOLVED placeholder (added when the resolution gate landed
in d414c77). Test was previously failing on /\{[A-Z_]+\}/ regex.
Suite is now 107/107 green (excluding the orphan .worktrees/phobics-tui
suite that's been failing pre-this-change).
README.md:
- Tool count 31 -> 41.
- New "Symbol Configuration Tools" section under Library Management
with one row per tool.
- Project-structure tool count footnote updated.
docs/function-test-2026-04-28.md:
- Append "Symbol Configuration tools (added 2026-04-28 evening)" block
with a per-tool vitest/live status grid.
- Live SP22 column is deferred: the MCP tool list is negotiated at
Claude Code session start and doesn't refresh mid-session, so the
new tools aren't callable in the session that built them. Document
the round-trip cycle so a fresh session can run it.
- Note the SymbolAccess enum-value probe risk per the plan
(docs/superpowers/plans/2026-04-28-symbol-config-tools.md).
Python 3 ast.parse run against all 10 new + 1 helper scripts -- 11/11
parsed cleanly (catches the obvious IronPython 2.7 syntax issues that
Py3 would also flag).
Two real bugs surfaced today:
1. compile_project / get_compile_messages reported 0 errors even when
the IDE's download path saw real compile errors. Root cause: both
scripts queried get_message_objects() with no category arg, which
returns only the IDE's last-active message tab (typically "Other"
for the WATCHER startup messages). Build/Code-Generation errors
live in a different category and were never queried.
Fix: enumerate script_engine.system.message_categories AND probe a
set of well-known V3.5 category GUIDs (Compile, Build, Online,
LibMan); query target_app.get_message_objects(cat) and
system.get_message_objects(cat) per category; aggregate dedup'd
entries (severity, text, object, line). Each entry now carries its
originating category label.
2. add_library's post-add _is_resolved() check trusted is_placeholder
== False as proof of resolution. CODESYS lets you call
add_placeholder(name_str) for a name that is NOT in the installed
Library Repository -- the resulting reference reports
is_placeholder=False yet has empty effective_version and the IDE
shows it with a yellow-warning triangle in Library Manager (no
Effective Version column populated). Karstein hit this with
"OPC UA PubSub SL": list_project_libraries reported it as
[managed] but compile failed because the IDE couldn't resolve it.
Fix: for the non-placeholder branch, probe effective_version /
resolved_version / version / resolved_library / managed_library /
library. ALL must be empty/None for the ref to be considered
hollow. Logs a DEBUG with the ref's attribute list so the next
such bug is diagnosable without source spelunking.
Bumped 0.6.2 -> 0.6.3.
API surface mapped against the SP22 stub at
ScriptLib/Stubs/scriptengine/ScriptSymbolConfigObject.pyi and the
docs at helpme-codesys.com/en/ScriptingEngine/ScriptSymbolConfigObject.html.
Phases 0-7 with file lists, per-tool args, enum mapping, idempotency
expectations, risks (esp. SymbolAccess enum values needing a one-shot
probe before lock-in), and verification plan against MCPTest2 then
X33.
Out-of-scope notes: no build_symbol_config tool (the API doesn't have
one; compile_project's application.build() emits the symbol XML as a
side effect), no comms-settings tab, no viz symbol lists.
Both the per-day verification docs and the references to them.
git mv preserves history:
docs/SMOKE-TEST-2026-04-25.md -> docs/FUNCTION-TEST-2026-04-25.md
docs/SMOKE-TEST-2026-04-28.md -> docs/FUNCTION-TEST-2026-04-28.md
Internal H1 + footer line updated to match. README.md and
OPEN-BUGS-CROSS-REFERENCE.md links retargeted.
Closes the 'vitest pass / live verify pending' gap from the 2026-04-25
sweep: each of `57ad449` (list_project_libraries), `fc49e7f`
(add_library dedup+placeholder), `763a307` (compile JSON-long
defensive walker), and `0f8981d` (rename_object reference rewrite)
was tool-called against MCPTest2 on SP22 Patch 1, with PLC_PRG-level
side-effects audited via get_all_pou_code and a 0/0 compile after
each mutation.
Result: 4/4 verified, 0 regressions. The fifth bug from the original
tracker (c87f3a9 create_folder) was already verified end-to-end in
its own commit body.
Two caveats logged:
- compile_project deliberate-error injection didn't propagate (CODESYS
scripting build() appears to short-circuit on cached state); the
defensive walker still ran on the watcher startup messages without
crashing, validating non-regression but not full repro of the
original 0xFFFFFFFFFFFF severity-long crash.
- Cosmetic: server.ts add_library always renders "added" even on the
dedup no-op branch -- the data-level dedup is correct, but the
user-facing message would benefit from threading the script's
branch outcome through formatModifyingResponse.
Bubble Tea-style ink TUI shipped inside this fork. Three roles:
browser over mcp-mirror/, approve gate for set_pou_code, and selection
beacon (state file) so MCP tools can ground actions in what the user
is looking at.
Phased: v0.1 read-only browser+approve, v0.2 get_user_selection MCP
tool, v0.3 inline live values (gated on connect_to_device fix), v0.4
full online dashboard sketched only.
Decisions locked: bin name phobiCS-tui, approve via two file paths,
inline live values, v0.4 future-only. Open: approve-gate default
on/off.
Branch was deleted after main caught up. server.ts auto-generates
library.md and pou-dump.md headers in user projects, so the broken
URL was leaking into every consumer of those tools. Now points at
the repo root (main is the only branch).
Two parallel smoke-test files had drifted out of sync:
docs/SMOKE-TEST-2026-04-25.md (morning v1, 28 invocations,
pre device-side fix)
docs/SMOKE-TEST-2026-04-25-v2.md (afternoon v2, 29 invocations,
post device-side fix)
Neither covered the late-afternoon work (six new git_* tools,
mirror_export, launcher refuse-on-duplicate, list_project_libraries
rewrite). Consolidating to one doc named SMOKE-TEST-2026-04-25.md
that:
- Covers the full 36 distinct tool invocations (28 OK / 4 FAIL /
1 PARTIAL).
- Reduces the open-bugs list from 5 to 4 (list_project_libraries
is fixed; the read/write inconsistency now narrows to
add_library's missing dedupe + placeholder).
- Adds rows for the 7 new tools verified end-to-end on X33 (8
library refs, 91 .st mirror files) and on GitSmokeTest (full
init -> commit -> remote_add -> branch_set_upstream_to -> push
round-trip against gitlab.usv.no via cached HTTPS creds).
- Documents the new infrastructure (PDE-license rewrite, launcher
refuse-on-duplicate) as separate sections rather than bugs.
- Cites the late-afternoon commits in the "What this proves" table
so the smoke test traces every fix back to its source.
The morning v1 is removed; the afternoon v2 file is renamed onto the
canonical filename to preserve git's rename history.
Per the project rule (check helpme-codesys.com first / cross-reference
before any scripting fix), each of the 5 open bugs from
SMOKE-TEST-2026-04-25-v2.md gets:
- Empirical failure as observed today on SP22 Patch 1
- Relevant docs URL on content.helpme-codesys.com
- What the docs confirm (or fail to surface -- many pages are index-
only with method bodies rendered by JS, not WebFetch'able)
- Proposed fix path with rationale and approximate effort
Findings summarised:
1. create_folder kwarg mismatch -> try positional 'create_folder("name")'
(~10 LOC, high-probability fix)
2. compile_project / get_compile_messages JSON long ->
pre-process the dict to coerce IronPython long to int/str before
json.dumps; belt-and-suspenders default=str (~15 LOC, single helper)
3. list_project_libraries returns empty ->
use ScriptLibManObject.get_libraries() (canonical), reuse the
same Library Manager discovery pattern that add_library already
succeeds with (~30 LOC)
4. add_library duplicates / not placeholder ->
pre-check via get_libraries() to dedupe; default to add_placeholder()
to match Standard template convention; opt-in 'direct=true' for
the old behaviour (~40 LOC, mildly breaking)
5. rename_object partial refactor ->
no documented refactor variant in scriptengine; brute-force walk
of every POU + word-boundary regex replace, gated behind
updateReferences=true flag (~80 LOC, biggest fix)
Order-of-attack ranking included. Each fix is its own commit per the
project rule, with the relevant docs URL cited inline in the commit
message.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Refresh of docs/SMOKE-TEST-2026-04-25.md after this afternoon's commits:
e862846 + eee8ce2 connect_to_device login probe + loginWaitSeconds
010811b + 64906c4 write_variable: SP22 prepare-then-write API
b3bf4a8 download_to_device: same login probe + loginWait
All five previously-failing device-side ops (connect/read/write/start_stop/
download/disconnect) now PASS verified end-to-end against:
- SP22 Patch 1
- Control Win V3 runtime up on port 11740
- Test project MCPTest with the user's manual cleanup applied (one
dup library + one rename-without-callers reference fixed by hand
after the morning sweep)
Five upstream bugs remain, each tracked as a separate item with the
proposed cross-reference path to the official scripting docs at
content.helpme-codesys.com:
- create_folder kwarg mismatch
- compile_project / get_compile_messages JSON long serialisation
- list_project_libraries returns empty after successful add_library
- add_library duplicates instead of dedupe / placeholder
- rename_object partial refactor (own decl yes, callers no)
Diff vs morning baseline: 17 -> 22 PASS, 8 -> 5 FAIL.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Verifies the watcher fix end-to-end: every passing tool used to
return the same execute_on_primary_thread marshal error and now
runs cleanly. Documents 5 unrelated pre-existing upstream bugs
exposed by the test (create_folder keyword mismatch, JSON long
serialisation in compile_project / get_compile_messages, online
API drift in connect/download/write_variable, orphaned CODESYS
on shutdown_codesys, library list/add inconsistency).
Test ran on SP21 Patch 5 due to MCP child orphaning during
re-registration churn; same architecture means SP22 is expected
to behave identically.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cite the CODESYS Forge thread, the official scripting docs index,
the Schneider Electric mirror with the historical signature, the
SP21 Patch 5 release notes, and the local ScriptSystem.pyi stub
that is the primary evidence for the API removal.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Investigation of the system.execute_on_primary_thread removal:
- Confirmed gone in SP21 Patch 5 (no entry in ScriptSystem.pyi stubs).
- Single call site is watcher.py:195, structural to the bg-thread design.
- Proposes single-threaded primary-thread loop with system.delay() for
message-pump time. No Node/TypeScript changes needed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>