c12fbc5988
Adds a new "Editing Script Content" section to script-parsing.md that
explains the IAttribute.SetValue silent-no-op behavior on
MxCategoryPackageOnly* attributes, enumerates which ScriptExtension
fields fall on each side of the boundary (text fields = no, trigger
settings = yes), names the EnsureMutableViaSetValue safety check that
landed in bd95ace, and includes a one-liner for inspecting any
object's package-only attributes via `object attributes --configurable`.
Closes the documentation gap surfaced when validating the round-trip
script edit on \$DelmiaReceiver.ProcessRecipe — the previous docs
described the read path comprehensively but said nothing about which
attributes can actually be written.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
168 lines
8.7 KiB
Markdown
168 lines
8.7 KiB
Markdown
# Parsing Scripts And Script Libraries
|
|
|
|
This guide describes how to capture scripts related to a template such as `TestMachine`.
|
|
|
|
GRAccess exposes script libraries directly through `IScriptLibraries` and `IScriptLibrary`. Object-level scripts are less direct: depending on object type and System Platform version, they may appear as attributes, extension attributes, or only inside exported object packages.
|
|
|
|
Run commands from `graccess_cli`. Examples assume an active session:
|
|
|
|
```powershell
|
|
graccess session start --galaxy ZB --node .
|
|
```
|
|
|
|
Without a session, add `--node .` to each command.
|
|
|
|
For LLM workflows, include object script metadata in the snapshot first:
|
|
|
|
```powershell
|
|
graccess object snapshot --galaxy ZB --name TestMachine --type template --llm-json
|
|
graccess object scripts list --galaxy ZB --name TestMachine --type template --llm-json
|
|
graccess object scripts get --galaxy ZB --name TestMachine --type template --script UpdateTestChangingInt.ExecuteText --llm-json
|
|
graccess object scripts get --galaxy ZB --name TestMachine --type template --script UpdateTestChangingInt --llm-json
|
|
```
|
|
|
|
Direct object script body readback is version-specific. The CLI tries direct GRAccess metadata first, then exports the target object to a temporary `.aaPKG`, recurses through nested package archives, and parses binary UTF-16 package records for `ScriptExtension` content. For script extension names, a bare script such as `UpdateTestChangingInt` resolves to `UpdateTestChangingInt.ExecuteText`. Explicit fields such as `UpdateTestChangingInt.StartupText` are preserved.
|
|
|
|
The exported package fallback can read script text fields such as `ExecuteText`, `DeclarationsText`, `StartupText`, `ShutdownText`, `OnScanText`, `OffScanText`, and `Expression` when present. When body access is unavailable from both direct GRAccess and package data, `object scripts get` reports that in structured output.
|
|
|
|
## Script Library Inventory
|
|
|
|
List script libraries:
|
|
|
|
```powershell
|
|
graccess script-library list --galaxy ZB --json
|
|
```
|
|
|
|
The current CLI returns library names. The underlying GRAccess API for `IScriptLibrary` exposes `Name` and `Export(path)`.
|
|
|
|
## Export Script Libraries
|
|
|
|
Export is the authoritative way to preserve script library content:
|
|
|
|
```powershell
|
|
$out = '.\template-snapshots\script-libraries'
|
|
New-Item -ItemType Directory -Force -Path $out | Out-Null
|
|
|
|
graccess script-library export --galaxy ZB --name CommonScripts --output "$out\CommonScripts.aaslib" --confirm --confirm-target "$out\CommonScripts.aaslib"
|
|
```
|
|
|
|
`script-library export` writes a local file, so the CLI requires confirmation and a matching `--confirm-target` equal to the output path.
|
|
|
|
To export every listed script library, parse the JSON list and call export for each name:
|
|
|
|
```powershell
|
|
$galaxy = 'ZB'
|
|
$out = '.\template-snapshots\script-libraries'
|
|
New-Item -ItemType Directory -Force -Path $out | Out-Null
|
|
|
|
$libs = graccess script-library list --galaxy $galaxy --json | ConvertFrom-Json
|
|
foreach ($lib in $libs) {
|
|
$name = $lib.Name
|
|
$path = Join-Path $out "$name.aaslib"
|
|
graccess script-library export --galaxy $galaxy --name $name --output $path --confirm --confirm-target $path
|
|
}
|
|
```
|
|
|
|
## Object-Level Script Discovery
|
|
|
|
For a template such as `TestMachine`, first inspect attributes and extended attributes for script-like names:
|
|
|
|
```powershell
|
|
graccess object attributes --galaxy ZB --name TestMachine --type template --json
|
|
graccess object extended-attributes --galaxy ZB --name TestMachine --type template --json
|
|
```
|
|
|
|
PowerShell classification:
|
|
|
|
```powershell
|
|
$attrs = Get-Content '.\template-snapshots\TestMachine.attributes.json' -Raw | ConvertFrom-Json
|
|
$extended = Get-Content '.\template-snapshots\TestMachine.extended-attributes.json' -Raw | ConvertFrom-Json
|
|
$all = (@($attrs) + @($extended)) | Sort-Object Name -Unique
|
|
|
|
$scripts = $all | Where-Object {
|
|
$_.Name -match '(?i)script|execute|trigger|expression|declaration|startup|shutdown|scan'
|
|
}
|
|
|
|
$scripts | Sort-Object Name | Select-Object Name, DataType, Category, Locked
|
|
```
|
|
|
|
This discovers script-related setting names and metadata. For bodies, prefer `object scripts get --llm-json` or `object snapshot --llm-json`; both can include package-backed script text when GRAccess export is available. Normal CLI script parsing must not query the Galaxy SQL database; SQL is development verification/debug-only.
|
|
|
|
## Editing Script Content
|
|
|
|
`IAttribute.SetValue` is **not** a complete editor for ScriptExtension content. The GRAccess COM API silently no-ops writes to any attribute whose `AttributeCategory` is `MxCategoryPackageOnly` or `MxCategoryPackageOnly_Lockable` — the call returns `Successful=true`, the surrounding checkout/save/checkin sequence completes cleanly, and a verify-read via direct `IAttribute.GetValue` confirms the value is unchanged.
|
|
|
|
For a `ScriptExtension` primitive named `Foo`, the package-only fields are:
|
|
|
|
| Field | Editable via `SetValue` | Editable via |
|
|
|---|---|---|
|
|
| `Foo.ExecuteText` | no — `MxCategoryPackageOnly_Lockable` | System Platform IDE |
|
|
| `Foo.DeclarationsText` | no — `MxCategoryPackageOnly_Lockable` | IDE |
|
|
| `Foo.StartupText` | no — `MxCategoryPackageOnly_Lockable` | IDE |
|
|
| `Foo.ShutdownText` | no — `MxCategoryPackageOnly_Lockable` | IDE |
|
|
| `Foo.OnScanText` | no — `MxCategoryPackageOnly_Lockable` | IDE |
|
|
| `Foo.OffScanText` | no — `MxCategoryPackageOnly_Lockable` | IDE |
|
|
| `Foo.Expression` | no — `MxCategoryPackageOnly_Lockable` | IDE |
|
|
| `Foo.TriggerType` | yes — `MxCategoryWriteable_C_Lockable` | `object scripts settings set --trigger-type` |
|
|
| `Foo.TriggerPeriod` | yes — `MxCategoryWriteable_C_Lockable` | `object scripts settings set --trigger-period-ms` |
|
|
|
|
The CLI guards every `SetValue` site with `EnsureMutableViaSetValue`. Writes to package-only attributes fail fast with `exit 1` and a message naming the category, instead of returning a misleading `success: true`. This applies to:
|
|
|
|
- `object scripts set` (any `--field` that's package-only, including the default `ExecuteText`)
|
|
- `object scripts settings set --expression`
|
|
- `object attribute value set` (any direct write to a package-only attribute)
|
|
|
|
`object scripts create` (which calls `AddExtensionPrimitive`) and `object scripts delete` (which calls `DeleteExtensionPrimitive`) are NOT affected — primitive add/delete uses a different COM path and does persist.
|
|
|
|
To inspect which attributes are package-only on a given object, use:
|
|
|
|
```powershell
|
|
graccess object attributes --galaxy ZB --name '$DelmiaReceiver' --type template --configurable --json |
|
|
ConvertFrom-Json |
|
|
Where-Object { $_.Category -like 'MxCategoryPackageOnly*' } |
|
|
Select-Object Name, Category
|
|
```
|
|
|
|
There is no documented GRAccess COM path that bypasses this restriction; the IDE edits script bodies through a separate Object Editor channel (IDM) that is not exposed to GRAccess clients. Bulk script changes that need automation should be staged via the IDE and exported to `.aaPKG`, then the package promoted between Galaxies via `objects export` / `galaxy import-objects`.
|
|
|
|
## Export Template Objects For Script Bodies
|
|
|
|
Use object export when you need the full object configuration, including script bodies, declarations, triggers, and extension payloads that are not exposed as simple attribute metadata:
|
|
|
|
```powershell
|
|
$out = '.\template-snapshots\TestMachine'
|
|
New-Item -ItemType Directory -Force -Path $out | Out-Null
|
|
$pkg = Join-Path $out 'TestMachine.aaPKG'
|
|
|
|
graccess objects export --galaxy ZB --type template --name TestMachine --output $pkg --confirm --confirm-target $pkg
|
|
```
|
|
|
|
The exported package should be treated as the complete vendor-owned representation. Use it as the source of truth when CLI JSON and GRAccess attribute metadata do not expose script content.
|
|
|
|
For a galaxy-wide reference export:
|
|
|
|
```powershell
|
|
$pkg = '.\template-snapshots\ZB.export.aaPKG'
|
|
graccess galaxy export-all --galaxy ZB --output $pkg --json
|
|
```
|
|
|
|
`galaxy export-all` is read-only from the galaxy perspective but writes an output file.
|
|
|
|
## Suggested Parse Bundle
|
|
|
|
A practical template parse bundle should include:
|
|
|
|
| File | Command |
|
|
|---|---|
|
|
| `object.json` | `object get` |
|
|
| `attributes.json` | `object attributes` |
|
|
| `configurable-attributes.json` | `object attributes --configurable` |
|
|
| `extended-attributes.json` | `object extended-attributes` |
|
|
| `attribute-groups.json` | Local classifier from `attribute-parsing.md` |
|
|
| `template.aaPKG` | `objects export` |
|
|
| `script-libraries/*.aaslib` | `script-library export` |
|
|
|
|
## Notes On GRAccess Script Collections
|
|
|
|
Some GRAccess examples refer to `Template.Scripts[index].ScriptString`. The local installed GRAccess interop and docs used by this CLI expose `ScriptExtension` content through script-like attributes and exported package records instead. Use `object scripts list/get` as the supported discovery and readback contract for this repository.
|