# Editing Existing Templates

This guide describes how to edit an existing GRAccess template such as `TestMachine` with `graccess_cli`.

Use this document as the top-level workflow. For deeper coverage, also read:

- `attribute-editing.md` - attribute values, locks, security, buffers, UDAs, extensions, and settings families such as history, I/O, and alarms.
- `script-editing.md` - script-library import/export and the current options for object-level script edits.
- `template-instance-editing.md` - create and edit instances from templates, including areas, engines, and I/O assignment.
- `template-parsing.md` - read-only inspection workflow to run before and after edits.

Run commands from `graccess_cli`. Examples assume the CLI is available as `graccess`. During local development, replace `graccess` with:

```powershell
dotnet run --project src/ZB.MOM.WW.GRAccess.Cli/ZB.MOM.WW.GRAccess.Cli.csproj --
```

## Safety Model

Every mutating command requires `--confirm`. Template/object mutation commands also require `--confirm-target` matching the exact object name being edited. File import/export commands use the file path as the confirmation target.

For template edits, use this pattern:

```powershell
--confirm --confirm-target TestMachine
```

For LLM-driven edits, validate the final command or batch plan before mutation:

```powershell
graccess object attribute value set --galaxy ZB --name TestMachine --type template --attribute Description --value Updated --data-type string --confirm --confirm-target TestMachine --dry-run --llm-json
graccess batch --file plan.json --mode validate --llm-json
```

Do not edit production templates directly unless the target, backup, and rollback path are explicit. For risky work, derive or export a test copy first.

## Session Setup

Start a session for repeated edits:

```powershell
graccess session start --galaxy ZB --node .
```

With a session active, omit `--node` on logged-in commands:

```powershell
graccess object get --galaxy ZB --name TestMachine --type template --json
```

Use `object snapshot --llm-json` for before/after verification when an LLM is planning or executing the edit:

```powershell
graccess object snapshot --galaxy ZB --name TestMachine --type template --llm-json
```

Without a session, include `--node .` on each command.

## Pre-Edit Snapshot

Take a read-only snapshot before changing anything:

```powershell
$galaxy = 'ZB'
$name = 'TestMachine'
$out = ".\template-snapshots\$name-before"
New-Item -ItemType Directory -Force -Path $out | Out-Null

graccess object get --galaxy $galaxy --name $name --type template --json `
  | Set-Content "$out\object.json"

graccess object attributes --galaxy $galaxy --name $name --type template --json `
  | Set-Content "$out\attributes.json"

graccess object attributes --galaxy $galaxy --name $name --type template --configurable --json `
  | Set-Content "$out\configurable-attributes.json"

graccess object extended-attributes --galaxy $galaxy --name $name --type template --json `
  | Set-Content "$out\extended-attributes.json"
```

For a fuller snapshot, follow `template-parsing.md`, `attribute-parsing.md`, and `script-parsing.md`.

## Optional Backup Export

For a rollback artifact, export the template before editing:

```powershell
$pkg = '.\template-snapshots\TestMachine-before\TestMachine.aaPKG'
graccess objects export --galaxy ZB --type template --name TestMachine --output $pkg --confirm --confirm-target $pkg
```

`objects export` writes a file and therefore requires `--confirm-target` equal to the output path.

## Standard Edit Flow

GRAccess object changes should follow:

```text
CheckOut -> mutate -> Save -> CheckIn(comment)
```

With `graccess_cli`:

```powershell
graccess object checkout --galaxy ZB --name TestMachine --type template --confirm --confirm-target TestMachine

# Run one or more mutation commands here.

graccess object save --galaxy ZB --name TestMachine --type template --confirm --confirm-target TestMachine
graccess object checkin --galaxy ZB --name TestMachine --type template --comment 'Edited TestMachine' --confirm --confirm-target TestMachine
```

If you need to discard changes:

```powershell
graccess object undo-checkout --galaxy ZB --name TestMachine --type template --confirm --confirm-target TestMachine
```

`object unload` releases the object from the GRAccess cache:

```powershell
graccess object unload --galaxy ZB --name TestMachine --type template --confirm --confirm-target TestMachine
```

## Edit Object Properties

Use `object set` for supported object-level properties:

| Property | Command value | Notes |
|---|---|---|
| Tagname | `tagname` | Renames the object tagname |
| Contained name | `contained-name` | Changes contained name |
| Area | `area` | Object reference or accepted GRAccess value |
| Host | `host` | Object reference or accepted GRAccess value |
| Container | `container` | Object reference or accepted GRAccess value |
| Toolset | `toolset` | Toolset reference or accepted GRAccess value |
| Security group | `security-group` | Security group reference or accepted GRAccess value |

Example:

```powershell
graccess object checkout --galaxy ZB --name TestMachine --type template --confirm --confirm-target TestMachine
graccess object set --galaxy ZB --name TestMachine --type template --property contained-name --value TestMachineEdited --confirm --confirm-target TestMachine
graccess object save --galaxy ZB --name TestMachine --type template --confirm --confirm-target TestMachine
graccess object checkin --galaxy ZB --name TestMachine --type template --comment 'Update contained name' --confirm --confirm-target TestMachine
```

When renaming `tagname`, the command target is the current name. After a successful rename, use the new name for later commands:

```powershell
graccess object checkout --galaxy ZB --name TestMachine --type template --confirm --confirm-target TestMachine
graccess object set --galaxy ZB --name TestMachine --type template --property tagname --value TestMachineV2 --confirm --confirm-target TestMachine
graccess object save --galaxy ZB --name TestMachineV2 --type template --confirm --confirm-target TestMachineV2
graccess object checkin --galaxy ZB --name TestMachineV2 --type template --comment 'Rename template' --confirm --confirm-target TestMachineV2
```

Validate tagname renames in a test galaxy first. If the local GRAccess cache cannot find the object by the new name before `Save`, the CLI needs a combined rename/save/checkin command that keeps the same COM object reference for the full operation.

Object-reference properties such as area, host, container, toolset, and security group depend on what the local GRAccess COM property setter accepts. If a string value fails, extend the CLI to resolve the named target object first and assign the COM object instead of the raw string.

## Edit Attributes And Settings

Use `attribute-editing.md` for the full attribute workflow.

Common commands:

```powershell
graccess object attribute set --galaxy ZB --name TestMachine --type template --attribute Description --value 'Updated description' --data-type string --confirm --confirm-target TestMachine

graccess object attribute lock --galaxy ZB --name TestMachine --type template --attribute Description --locked MxPropertyUnlocked --confirm --confirm-target TestMachine

graccess object attribute security --galaxy ZB --name TestMachine --type template --attribute Description --security MxSecurityOperate --confirm --confirm-target TestMachine

graccess object attribute buffer --galaxy ZB --name TestMachine --type template --attribute Description --has-buffer --confirm --confirm-target TestMachine
```

The current CLI supports attribute value types `string`, `bool`, `int`, `float`, and `double`.

History, I/O, alarm, and script settings are usually represented as attributes, extended attributes, object package content, or extension-specific payloads. For value-level edits beyond the current `object attribute set` support, use export/import or add CLI support for safe `IAttribute.Value` parsing and serialization.

## Edit UDAs

UDAs are object mutations and should be wrapped in checkout/save/checkin.

Add a UDA:

```powershell
graccess object checkout --galaxy ZB --name TestMachine --type template --confirm --confirm-target TestMachine
graccess object uda add --galaxy ZB --name TestMachine --type template --uda CustomCode --data-type MxString --category MxCategoryWriteable_USC --security MxSecurityUndefined --confirm --confirm-target TestMachine
graccess object save --galaxy ZB --name TestMachine --type template --confirm --confirm-target TestMachine
graccess object checkin --galaxy ZB --name TestMachine --type template --comment 'Add CustomCode UDA' --confirm --confirm-target TestMachine
```

Rename a UDA:

```powershell
graccess object uda rename --galaxy ZB --name TestMachine --type template --uda CustomCode --new-name CustomCode2 --confirm --confirm-target TestMachine
```

Update UDA metadata:

```powershell
graccess object uda update --galaxy ZB --name TestMachine --type template --uda CustomCode2 --data-type MxString --category MxCategoryWriteable_USC --security MxSecurityUndefined --confirm --confirm-target TestMachine
```

Delete a UDA:

```powershell
graccess object uda delete --galaxy ZB --name TestMachine --type template --uda CustomCode2 --confirm --confirm-target TestMachine
```

## Edit Extensions

Extension primitives are object mutations and should be wrapped in checkout/save/checkin.

Add an extension primitive:

```powershell
graccess object extension add --galaxy ZB --name TestMachine --type template --extension-type ScriptExtension --primitive OnScan --object-extension --confirm --confirm-target TestMachine
```

Rename an extension primitive:

```powershell
graccess object extension rename --galaxy ZB --name TestMachine --type template --extension-type ScriptExtension --primitive OnScan --new-name OnScan2 --object-extension --confirm --confirm-target TestMachine
```

Delete an extension primitive:

```powershell
graccess object extension delete --galaxy ZB --name TestMachine --type template --extension-type ScriptExtension --primitive OnScan2 --object-extension --confirm --confirm-target TestMachine
```

Exact extension type and primitive names must match what the local System Platform installation and template support.

## Derive A Template

Derive a test template before editing a production template directly. This is also how you extend a base System Platform template, such as deriving `$TestMachine` from `$gMachine`.

```powershell
graccess template derive --galaxy ZB --name TestMachine --type template --new-name TestMachine_EditTest --create-contained --confirm --confirm-target TestMachine
```

Then edit `TestMachine_EditTest`:

```powershell
graccess object checkout --galaxy ZB --name TestMachine_EditTest --type template --confirm --confirm-target TestMachine_EditTest
```

To extend `$gMachine` with a new machine template:

```powershell
graccess template derive --galaxy ZB --name '$gMachine' --type template --new-name '$MyMachine' --confirm --confirm-target '$gMachine' --llm-json
graccess object snapshot --galaxy ZB --name '$MyMachine' --type template --llm-json
```

Use `--create-contained` only when the source template has contained templates/objects that should be copied into the derived template. For a family like `$TestMachine`, contained templates such as `$TestMachine.DelmiaReceiver` and `$TestMachine.MESReceiver` are part of the template design and should be verified after derivation:

```powershell
graccess template derive --galaxy ZB --name '$TestMachine' --type template --new-name '$MyMachine' --create-contained --confirm --confirm-target '$TestMachine' --llm-json
graccess template list --galaxy ZB --pattern '%MyMachine%' --llm-json
```

If the derived family does not include expected embedded templates, do not hand-edit production objects to compensate. Add or validate CLI support for contained template creation against a disposable test family first.

## Edit Embedded Template Objects

Contained templates are edited by targeting the contained template tagname. For the `TestMachine` family:

```powershell
graccess object snapshot --galaxy ZB --name '$TestMachine.DelmiaReceiver' --type template --llm-json
graccess object checkout --galaxy ZB --name '$TestMachine.DelmiaReceiver' --type template --confirm --confirm-target '$TestMachine.DelmiaReceiver'
graccess object attribute value set --galaxy ZB --name '$TestMachine.DelmiaReceiver' --type template --attribute DownloadPath --value 'C:\Recipes' --data-type string --confirm --confirm-target '$TestMachine.DelmiaReceiver' --llm-json
graccess object save --galaxy ZB --name '$TestMachine.DelmiaReceiver' --type template --confirm --confirm-target '$TestMachine.DelmiaReceiver'
graccess object checkin --galaxy ZB --name '$TestMachine.DelmiaReceiver' --type template --comment 'Update Delmia receiver download path' --confirm --confirm-target '$TestMachine.DelmiaReceiver'
```

Contained template edits flow to future instances and may affect derived/instantiated objects depending on lock and override state. Before editing an embedded template, snapshot representative existing child instances such as `DelmiaReceiver_001` and compare after checkin.

## Instantiate For Validation

Create a test instance from the edited template:

```powershell
graccess template instantiate --galaxy ZB --name TestMachine_EditTest --type template --new-name TestMachine_EditTest_001 --create-contained --confirm --confirm-target TestMachine_EditTest
```

Use instance deployment commands only against explicitly named test instances:

```powershell
graccess instance deploy --galaxy ZB --name TestMachine_EditTest_001 --type instance --confirm --confirm-target TestMachine_EditTest_001
```

## Edit Scripts

Use `script-editing.md` for script-library import/export and object-level script guidance.

The current CLI can import script libraries:

```powershell
graccess script-library import --galaxy ZB --path '.\scripts\CommonScripts.aaslib' --confirm --confirm-target '.\scripts\CommonScripts.aaslib'
```

The current CLI does not expose direct JSON editing for object-level script bodies. Use object export/import for full-fidelity script body edits, or add a dedicated command that exposes script primitives and script-valued attributes.

## Post-Edit Verification

After checkin, take a second snapshot:

```powershell
$galaxy = 'ZB'
$name = 'TestMachine'
$out = ".\template-snapshots\$name-after"
New-Item -ItemType Directory -Force -Path $out | Out-Null

graccess object get --galaxy $galaxy --name $name --type template --json `
  | Set-Content "$out\object.json"

graccess object attributes --galaxy $galaxy --name $name --type template --json `
  | Set-Content "$out\attributes.json"

graccess object attributes --galaxy $galaxy --name $name --type template --configurable --json `
  | Set-Content "$out\configurable-attributes.json"

graccess object extended-attributes --galaxy $galaxy --name $name --type template --json `
  | Set-Content "$out\extended-attributes.json"
```

Compare before and after snapshots:

```powershell
Compare-Object `
  (Get-Content '.\template-snapshots\TestMachine-before\attributes.json') `
  (Get-Content '.\template-snapshots\TestMachine-after\attributes.json')
```

Also verify command summaries after each mutation. GRAccess returns `CommandResult` or `CommandResults`; failed calls should be treated as failed edits even if the CLI process exits after printing output.

## Rollback Options

Rollback depends on what changed:

| Change type | Rollback path |
|---|---|
| Unchecked-in edit | `object undo-checkout` |
| Attribute value/metadata edit | Restore previous value with another edit cycle |
| UDA or extension edit | Reverse the add/delete/rename/update operation |
| Derived test template | Delete the derived template after validation |
| Full object/package edit | Re-import the pre-edit export package with explicit confirmation |

Importing packages is production-impacting and requires exact confirmation:

```powershell
graccess galaxy import-objects --galaxy ZB --file '.\template-snapshots\TestMachine-before\TestMachine.aaPKG' --overwrite --confirm --confirm-target '.\template-snapshots\TestMachine-before\TestMachine.aaPKG'
```

## Current CLI Gaps For Full-Fidelity Editing

The current CLI can edit object properties, attribute values, locks, security classifications, buffers, UDAs, extensions, derived templates, instances, and script libraries. Full-fidelity template editing still has gaps:

| Area | Current status | Recommended next step |
|---|---|---|
| Attribute value readback | Values are not emitted by `object attributes` | Add defensive `IAttribute.Value` serialization |
| History/I/O/alarm value editing | Possible only when the setting is a known attribute and supported value type | Add typed setting commands or broader `MxValue` support |
| Object-level script bodies | Not exposed as JSON | Add `object scripts get/set` or use export/import |
| Object-reference property assignment | Raw string assignment may fail for some COM properties | Resolve named GRAccess objects before assignment |
| Validation details | `object get` does not emit all errors/warnings/status fields | Extend object detail output defensively |

Prefer implementing those gaps as read-only parse support first, then mutation support with confirmation guards.
