From c12fbc5988e6037340d31ab16d5c9ca70baec6fa Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Tue, 5 May 2026 15:52:57 -0400 Subject: [PATCH] graccesscli/docs: document the package-only writeback boundary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- graccesscli/docs/script-parsing.md | 37 ++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/graccesscli/docs/script-parsing.md b/graccesscli/docs/script-parsing.md index 7f48df6..0c58e9d 100644 --- a/graccesscli/docs/script-parsing.md +++ b/graccesscli/docs/script-parsing.md @@ -88,6 +88,43 @@ $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: