Files
wwtools/graccesscli
Joseph Doherty 65537570b8 graccesscli: enumerate ScriptExtension via canonical text-attribute suffixes
`object scripts list` previously walked obj.Attributes through a
substring heuristic (`IsScriptAttribute`) that matched any name
containing "script", "expression", "execute", "startup", "shutdown",
or "scan". Two failure modes:

- "deSCRIPTion" contains "script", so every `MoveIn*.Description` /
  `MoveOut*.Description` attribute on `$MESReceiver` (and any other
  object with `.Description` UDAs) was mis-emitted as a script.
- `ScanState` / `ScanStateCmd` (ordinary attribute UDAs) leaked in via
  the "scan" keyword.

Net result on $MESReceiver: 25 entries, all false positives, zero
true ScriptExtensions.

The GRAccess COM API does not expose an `IScriptExtension` enumerable
(verified against ArchestrA.GRAccess.dll string table — only
`AddExtensionPrimitive` / `DeleteExtensionPrimitive` /
`RenameExtensionPrimitive` mutators exist). The only attribute-side
signal that an object carries a real ScriptExtension is the canonical
text-attribute suffix list documented in docs/script-parsing.md:
ExecuteText, DeclarationsText, StartupText, ShutdownText, OnScanText,
OffScanText, Expression.

Replace `IsScriptAttribute` with `ScriptExtensionPrefix(name)` that
detects exactly those suffixes, then group attributes by prefix:
- Each ScriptExtension yields one logical entry named by its prefix.
- The Fields[] list reports which text attributes are present.
- Sibling `<prefix>.TriggerType` / `<prefix>.TriggerPeriod` attributes
  are surfaced as TriggerType / TriggerPeriod when present.
- ExtensionType is always "ScriptExtension".

Outer `ObjectScripts(IGalaxy, IgObject, PackageSnapshot)` updated to:
- Thread ExtensionType / Fields / TriggerType / TriggerPeriod through.
- Look up body content by prefix first, then fall back to
  `<prefix>.ExecuteText` (the package's serialized bodies are keyed
  by full attribute name).
- Mark every `<prefix>.<field>` as emitted so the package-fallback
  branch doesn't re-emit each text field as its own entry.

Drop dead `IsScriptAttribute` (no other callers).

Validation against live ZB galaxy:
- $MESReceiver: 25 → 0 (correct: no ScriptExtensions on this template)
- $TestMachine: 1 entry — UpdateTestChangingInt with body
  "Me.TestChangingInt = System.Random().Next(1,1000);" + all 7 fields
  + trigger metadata.
- $DelmiaReceiver: 2 entries — ProcessRecipe + Reset, both with bodies
  ("Me.RecipeDownloadFlag = false;") + trigger metadata.

61/61 existing tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 14:54:41 -04:00
..

graccesscli

A .NET Framework 4.8 / x86 CliFx-based CLI for automating AVEVA / Wonderware System Platform Galaxy configuration through the ArchestrA GRAccess COM interop library (ZB.MOM.WW.GRAccess.Cli).

Hard constraints

GRAccess is a 32-bit COM stack. Skipping any of these will fail at load or corrupt Galaxy state:

  • Target framework / arch: net48, x86, [STAThread]. No exceptions.
  • Cannot be loaded from a .NET 10 / x64 process — see GRAccess-DLL-and-DotNet10-Notes.md.
  • AVEVA System Platform must be installed locally (or ArchestrA.GRAccess.dll registered in the GAC at C:\Windows\assembly\GAC\Archestra.GRAccess\1.7.0.0_23106a86e706d0ae\). The bundled copy in lib/ is for build-time reference only.
  • In daemon mode, every COM call must be marshalled through Session/StaComThread.cs; calling GRAccess from any other thread will deadlock or corrupt state.
  • Keep the root GRAccessApp alive for the lifetime of any derived IGalaxy / IgObject handle.
  • Mutation flow is fixed: CheckOut → modify → Save → CheckIn(comment). Skipping CheckIn leaves the object locked in the Galaxy repo.
  • Build requires Visual Studio / MSBuild with the x86 platform target.

Layout

graccesscli/
  ZB.MOM.WW.GRAccess.Cli.slnx        # solution
  lib/ArchestrA.GRAccess.dll         # bundled COM interop assembly (reference only)
  src/ZB.MOM.WW.GRAccess.Cli/        # CLI project (net48, x86, CliFx)
  tests/ZB.MOM.WW.GRAccess.Cli.Tests # test project
  docs/                              # CLI workflows, LLM contract, parsing/editing guides
  AGENTS.md                          # coding-agent rules for this tool
  CLAUDE.md                          # detailed agent guide
  graccess_documentation.md          # full GRAccess API reference
  graccess_operations.md             # GRAccess operations grouped by functional area
  usage.md                           # compatibility copy of docs/usage.md
  GRAccess-DLL-and-DotNet10-Notes.md # platform / 32-bit COM / .NET 10 incident notes
  requirements-mutation-typelib-fix.md # active mutation-path defect tracker

Resource index

Task Go to
Coding-agent rules for working in this folder AGENTS.md
General agent guide (project overview, references) CLAUDE.md
Full GRAccess API surface (types, methods) graccess_documentation.md
GRAccess operations grouped by functional area, with page refs graccess_operations.md
CLI commands, options, session mode, IPC protocol docs/usage.md
LLM-facing operating contract (envelopes, safety, batch) docs/llm-integration.md
Add a new CLI command end-to-end docs/adding-features.md
Inspect / read existing templates (read-only) docs/template-parsing.md
Parse template attributes and setting families docs/attribute-parsing.md
Parse script libraries and object-level scripts docs/script-parsing.md
Edit existing templates safely docs/template-editing.md
Create / edit template instances, areas, engine assignments, I/O docs/template-instance-editing.md
Edit template attributes, UDAs, extensions, setting families docs/attribute-editing.md
Edit script libraries and script-bearing template content docs/script-editing.md
Live ZB galaxy reference (read-only capture) docs/zb-galaxy.md
Live ZB $TestMachine template family reference docs/zb-testmachine.md
CliFx framework reference (commands, options, DI, testing) docs/clifx_reference.md
GRAccess DLL / 32-bit COM / .NET 10 platform notes GRAccess-DLL-and-DotNet10-Notes.md
Active mutation-path COM lifecycle defects requirements-mutation-typelib-fix.md
Index for docs/ only docs/README.md

Maintenance

Documentation rules live in ../DOCS-GUIDE.md; the root task → tool index lives in ../CLAUDE.md. When adding, renaming, or removing any doc in this folder, update the resource index above in the same change. When the user-facing CLI surface changes, update docs/usage.md (and keep usage.md aligned).