TIATool

Changelog

What changed, release by release.

Built from the CHANGELOG in the product repository, so it lists exactly what shipped. The current status of every capability is in the capability matrix under Docs.

What changed in each TIATool release, written for the people who use it.

[0.8.0] - 2026-10-13

  • No free tier. Without an active licence or trial, TIATool refuses tools and verbs with "activate or buy" (tiax-agent license activate <key>, or EUR 99.99/month / EUR 999.99/year). doctor, setup, init, license, help and version still run unlicensed.
  • Neutral, synthetic fixtures and examples throughout; workspace fields are now site/serial/standard and templates carry compliance_notes.
  • Website: two plans only; transactional mail via Unosend (UNOSEND_API_KEY); Stripe live keys are refused outside production.

The self-extending, verify-first release. TIATool can now explore the whole Openness object model, run C# scripts against your project inside a transaction, and promote the ones that work into reusable extensions. Every write still goes through the same rails: preview, a person's approval, backup, write, journal, verify. On top of that: a policy file for administrators, approvals the AI cannot give itself, a tamper-evident journal, explicit PLC/HMI targets, incremental export, a trial and air-gapped licences, and a rebuilt website.

Safety

  • No MCP argument can switch a rail off. Fixed: a crafted argument such as build_from_source{delete_blocks: "--no-backup"}, or a value with a quote or trailing backslash, could reach the child process as an option and disable the automatic backup. Now:
    • every call is checked against the tool's schema before anything runs. Undeclared arguments, wrong types, values outside an enum, missing required arguments and NUL characters are refused with a message naming the argument. A value that starts with - is refused, except in free-text fields (search text, notes, titles) that never reach a command line;
    • child processes get --key=value arguments only, on a command line escaped exactly the way Windows splits it;
    • a last check refuses to start a child whose arguments carry a rail switch (--no-backup, --allow-tia-running, --in-place, ...).
  • Previews are previews. dry_run / what_if only skip the licence, journal and verify on the tools that honour them (build_from_source, clean_sources, io_list_import, unified_build). On the command line, a --dry-run / --what-if that a verb would ignore (for example tiax compile --dry-run) is refused with exit 64 instead of running for real.
  • Explicit PLC and HMI targets. In a project with several PLCs or HMIs, writes no longer pick the first one. Name the target (--plc / --hmi, MCP plc / hmi) on build, import-block, hmi, compile and scl-apply; an ambiguous target is refused with AMBIGUOUS_TARGET, an unknown one with NOT_FOUND, before anything changes. HMI screen and tag-table imports used to go into every HMI; they now go into the named one. A "station" in hardware.json must exist (no more falling back to the first station that holds a PLC).
  • Downloads never reset data silently. plc_download cancels a download that would re-initialise data blocks, or that can only download ALL blocks (every DB back to its start values), unless you approved it with allow_reinit.
  • Every write refuses while TIA Portal is open (UI_SESSION_OPEN); reads can attach to the open UI instead (see Openness).
  • Fixed: baseline_set name=".." could replace the snapshots folder; a task id could move a post-write snapshot out of the workspace; two writes in the same second shared one snapshot folder.

Understanding a project (offline, no TIA Portal)

  • Truer answers. Block interfaces list their real sections only (nested struct/UDT members were reported as extra sections, every member twice). STL networks count as unreadable (opaque), so the readable percentage no longer overstates. who_writes_tag / who_reads_tag always end with the blind spots they could not look into: STL, GRAPH, lossy reconstructions, know-how protected blocks.
  • Stable caches on every machine. Block ids no longer change between scans, line ends are LF, and device folders are read in a fixed order: the same export scans to identical files on Windows and Linux.
  • Faster scans on multi-core PCs, with byte-identical output.
  • Nothing missing silently. A failed watch/force-table group, external-source group or tag-table read error is now listed under NOT EXPORTED (exit 2) instead of only being logged.
  • Docs export: "Called by" is filled in, and tag tables no longer appear in the block catalogue.
  • Project text that goes back to the AI (comments, titles, HMI texts) is fenced as untrusted data, a mitigation against instructions hidden in a project.

Self-extension (new, Labs)

  • Object-model explorer. tiax openness <project> browse|get|set|invoke --path=... and the MCP tools openness_browse, openness_get (free), openness_set, openness_invoke (licensed, approved, backed up, journaled). Paths such as plc:PLC_1/BlockGroup/Blocks["Main"]@ProgrammingLanguage reach anything Openness exposes, in any TIA version.
  • C# scripts. script_check compiles a script against your TIA version's Openness assemblies and checks it against a guard rail, with line:column diagnostics. script_run in read mode is free and runs inside a transaction that is never committed or saved. Write mode needs a licence and a person's approval, then backs up, commits only on success, saves, journals and verifies. The guard rail refuses processes, registry, network, code loading and file deletion; it is a guard rail, not a sandbox.
  • Extensions. extension_list, extension_show, extension_run and extension_save (promote a script that ran, with provenance). Built-in pack: 43 live Openness scripts (watch/force tables, text lists, technology objects, software units, libraries, network, HMI connections and alarm classes, UMAC users and roles, PLC tags and UDTs, block attributes, cross-reference, catalog search; 7 of them write) and 10 offline cache queries. Your own extensions live in %APPDATA%\TIATool\extensions or the workspace and override built-ins.
  • cache_query: JavaScript over the scanned cache (time and memory limited, no .NET access).
  • Learning knowledge base: knowledge_add records a fix; explain_error and tool errors find it next time (marked "not reviewed").
  • New MCP prompt extend_tiatool and the guide docs/self-extension.md.

Openness depth and speed (Labs)

  • Incremental export: tiax export --incremental, MCP export_project{incremental:true}. Only blocks, tag tables and types changed since the last export are exported again; deleted ones are removed. The verify after every write uses it by default, so it no longer re-exports the whole project.
  • Export mirror: an export into a git work tree (or over a previous export) removes the XML of blocks you deleted or renamed and reports them; .tiax-export.json records what was exported.
  • Project lifecycle: tiax project create|archive|retrieve, MCP project_create (licensed), project_archive and project_retrieve (free; retrieve only into a new folder).
  • Read-only attach: --attach on tiax export / tiax devices (MCP attach:true) reads through the TIA Portal UI that has the project open.
  • SCL edit loop: scl_lint (free) checks a source for the problems TIA reports badly (three-part VERSION, unbalanced blocks, undeclared symbols, ...). scl_apply / tiax scl-apply lints, backs up, generates through a temporary source that is deleted again, and compiles that PLC only. compile_project{block} / tiax compile --block compiles single blocks. Compiler messages come back structured, with knowledge-base hits.
  • WinCC Unified panels are compiled (they used to report "not compiled").
  • Online compare (Labs): plc_compare_online / tiax pro online-compare lists what differs between the project and the PLC; it never downloads.

Trust and policy

  • Policy file. %ProgramData%\TIATool\policy.json (administrators; /etc/tiatool/policy.json on Linux) over <workspace>\policy.json: allow/deny tools, read-only, online access, scripts (off/read/write), allowed project and output folders, tools that need confirmation, writes per hour, approval channel. A broken file refuses every write until it is fixed. Tools a policy denies are not even listed to the AI. New: tiax-agent policy show prints the effective policy with the file behind every value; tiax-agent policy init writes a commented example. Examples: docs/security/policy.md.
  • Approval the AI cannot give itself. plc_download, an in-place restore, write scripts, generic Openness writes and anything the policy lists ask a person: as a form in the AI client (MCP elicitation; the model never sees a token), or, when the client cannot ask, with tiax-agent approve <id> in a terminal.
  • Tamper-evident journal. Every entry records the Windows user, host, AI client and approval, in a SHA-256 hash chain; tiax journal verify|export [--csv]. The first write to a project now creates a workspace for it automatically, so journal and verify are on by default.
  • Tools carry MCP annotations (read-only, destructive, idempotent) and structured results.

Usability and CI

  • Smaller tool lists. tiax-agent mcp --toolset explore|generate|commission|admin|extend|all; explore lists 28 tools (~9k tokens of definitions) instead of 75 (~31k). Every tool stays callable, and find_tool searches the full catalog.
  • Eight AI clients. tiax-agent setup registers Claude Desktop, Cursor, VS Code, Claude Code, Windsurf, Cline, Codex CLI and Gemini CLI (--all = the ones installed). Backups are timestamped and never overwritten. For long calls in Claude Code set MCP_TOOL_TIMEOUT=600000.
  • Try it without TIA Portal: tiax-agent init --demo builds a sample workspace and registers it as tiatool-demo.
  • Support: rolling logs in %LOCALAPPDATA%\TIATool\logs, tiax-agent support-bundle (redacted, nothing uploaded), tiax-agent privacy (every endpoint TIATool can contact; no telemetry).
  • CI: tiax-agent analyze audit|diff|verify on caches or export folders, as SARIF, JUnit, Markdown or JSON; a GitHub Action (.github/actions/tiatool-analyze) and an example workflow.
  • Live selftest: tiax selftest --live has 23 steps; the new ones prove incremental export, project archive/retrieve, the explorer, script rollback and commit, the extension pack and the SCL loop on your machine.
  • Security: the agent's SQLite (full-text search) is updated to a version without the known high-severity advisory (GHSA-2m69-gcr7-jv3q).

Licensing

  • 14-day trial from the command line: tiax-agent license trial --email you@company.com (one per company domain and PC).
  • Air-gapped PCs: tiax-agent license request-offline writes a request file, the website returns a licence file, tiax-agent license import installs it (yearly, enterprise, offline and edu plans).
  • Licences refresh in the background, fail over between licence servers and work through authenticating (NTLM/Kerberos) proxies. tiax-agent update --check tells you about new releases; it never installs anything.
  • restore_backup listing and restore into a new folder are free (only in-place restore needs a licence).
  • Every 0.5–0.7 licence keeps working.

Website and customer account

  • One marketing landing page: install in three real commands, what it does, self-extension, safety and trust, an honest status summary generated from the capability registry, TIA version compatibility, a dated and sourced comparison (including where the alternatives are ahead), pricing and FAQ. The old standalone pages redirect to their section or to /docs.
  • Every number comes from the product: tool count, capability statuses, the free-vs-licensed tool matrix, compatibility, changelog.
  • A real customer account: sign up and sign in with an email link (confirmed by a button, so mail scanners cannot use it up; no account enumeration; rate limited), a 14-day trial on sign-up, an overview with your own install and activation steps, licences (show/copy the key, seats, machines and their activity, remove a machine, regenerate the key, air-gapped licence files from a request file), billing (plan, renewal, invoices, Stripe portal, switch to yearly, more seats) and settings (profile, company and VAT for invoices, email change, sign out everywhere, data export, account deletion).
  • Licensing and billing hardening: an unverified command-line trial can never attach to someone else's account or carry into their purchase; offline licence files keep their PC's seat until they expire and need a paid current period; refunds of seat or plan changes no longer suspend a licence; Stripe webhooks are processed exactly once even after a crash.
  • Security headers on every page (CSP, HSTS, no framing, nosniff, referrer and permissions policies); the installer checksum is pinned in the release metadata and install.ps1 stops on a missing or wrong hash instead of telling you to click "Run anyway".
  • Legal pages (terms, privacy, EULA, imprint) are drafts pending legal review.
  • Deploy note: run npm run db:migrate (migrations 002-004) before deploying the web app.

Hardening from the 0.8 security and correctness review

  • Scripts cannot write, copy, delete or move files, start threads or timers, or use dynamic; approval and policy files touched during any script run are restored and the run is refused (script_tamper in the journal).
  • An extension_run approval shows the extension's code and binds to its SHA-256; replaced code needs a new approval.
  • The scripts licence feature is enforced for write scripts and for saving write extensions.
  • Export mirroring and incremental export never act through symlinks or junctions; default mirroring removes only files the previous manifest lists; incremental export re-exports blocks whose types or called FBs changed.
  • Engine reliability: one queue per session thread (a timed-out call cannot reset the next one), atomic licence saves with a refresh lock, script timeouts counted from the script's start, cleanup of the engine's own Portal processes after a crash, rolling baselines and snapshot pruning in implicit workspaces.
  • plc_compare_online reports "no differences" only when TIA says the root is identical.
  • cache_query refuses oversized arrays and strings before allocating them.

Upgrade notes

  1. Argument rails. MCP calls with undeclared arguments, or with a value starting with - outside free-text fields, are refused. On the command line, --dry-run / --what-if on a verb that ignores it exits 64.
  2. dry_run semantics. Only build_from_source, clean_sources, io_list_import (dry_run) and unified_build (what_if) treat a preview as free; on every other tool the argument is refused.
  3. Multi-PLC / multi-HMI projects need --plc / --hmi (MCP plc / hmi) on build, import-block, hmi, compile and scl-apply. HMI imports go into the named HMI only.
  4. Re-scan your caches. The cache record revision is now 2 (corrected interface sections, STL opaque, stable ids). Older caches still load and ask for a re-scan (tiax scan or refresh_scan).
  5. Online tools need a policy. allow_online defaults to false: plc_download, plc_online and plc_compare_online are refused and not listed until a policy allows them. As administrator: tiax-agent policy init --machine --allow-online; for one workspace: tiax-agent policy init --workspace <folder> --allow-online.
  6. Approvals. Downloads, in-place restores, write scripts and Openness writes are approved by a person through the AI client's form (elicitation) or tiax-agent approve <id>. The old two-step confirm_token only works under a policy with "confirm_mode": "in_band".
  7. Journal and verify are on by default. Without a configured workspace, the first write to a project creates one under %LOCALAPPDATA%\TIATool\workspaces\ and every write is followed by export → scan → verify (incremental). verify=false skips it for one call; pipeline.incremental_export: false in the workspace turns incremental export off. Pre-0.8 journals stay readable; the hash chain starts with the first 0.8 entry.
  8. plc_download and data blocks. A download that must re-initialise data blocks or download ALL blocks is cancelled unless you pass allow_reinit=true (plus allow_stop when the CPU must stop).
  9. Exports mirror in a git work tree or over a previous export: the XML of deleted blocks is removed. Pass --no-mirror to keep it.
  10. Client configuration. Re-run tiax-agent setup once: it removes the ineffective MCP_TIMEOUT entry it used to write. In Claude Code, set MCP_TOOL_TIMEOUT=600000 in your environment.

Known limits of this release: the Labs features above have not yet run against TIA Portal; a licence token's scripts feature is defined but not yet checked by the script tools (write is).