# Adding GRAccess CLI Features

Use this checklist when adding a new `graccess_cli` command, option, output field, dispatcher operation, or LLM-facing workflow. The goal is to keep human CLI behavior, script compatibility, session routing, and LLM automation aligned.

## First Read

Before editing code, read the relevant source material:

- `graccess_operations.md` for the operation family and page references.
- `graccess_documentation.md` for exact GRAccess signatures, enum names, return types, and object model constraints.
- `docs/usage.md` for the current public CLI contract.
- `docs/llm-integration.md` for machine-facing output, validation, batch, and confirmation rules.
- The domain docs that match the feature: parsing, editing, scripts, attributes, or template instances.

Do not infer COM behavior from names alone. GRAccess methods often return `CommandResult` or `CommandResults` and may expose properties that throw when backing storage is unavailable.

## Decide The Command Shape

Choose the smallest command that maps clearly to the GRAccess operation.

- Use established CliFx patterns: command classes implement `ICommand` and use `[Command]`, `[CommandParameter]`, and `[CommandOption]`.
- Keep galaxy-bound commands routable through `CommandRouter`.
- Keep pre-login galaxy operations one-shot when they cannot use a galaxy-specific session.
- Prefer explicit subcommands over overloaded string modes.
- Preserve existing command names and existing `--json` shapes.
- Add `--llm-json` for machine-stable output when the command is useful to automation.
- Add `--dry-run` to mutating routed commands for validation without invoking mutating COM calls.

For mutating operations, choose the safety rule before implementation:

- All mutations require `--confirm`.
- Destructive, deployment, import/export, restore, migrate, GRLoad, and object configuration changes require `--confirm-target <exact target>`.
- Batch plans must include per-step `confirm: true` and exact `confirm-target`; do not add global mutation confirmation.

## Register Capabilities

Every public command intended for automation must be represented in `Infrastructure/CommandCapabilityRegistry.cs`.

Add or update:

- Command name.
- Required and optional args.
- Whether it mutates state.
- Whether it supports session routing.
- Whether it requires `--confirm`.
- Whether it requires `--confirm-target`, and which target rule applies.
- Output modes, including `text`, `json`, and `llm-json` where supported.
- Schema name for the request or response family.

The registry is the source for `graccess capabilities`, `graccess validate`, batch validation, and tests. Do not scrape docs or help output to discover commands.

## Add The CliFx Wrapper

Put thin command wrappers in the existing command area that matches the feature:

- `Commands/GRAccessSurfaceCommands.cs` for most expanded GRAccess operation surface commands.
- `Commands/Objects/*` for established object list/query commands.
- `Commands/Galaxy/*` for galaxy commands.
- `Commands/LlmCommands.cs` for capabilities, validate, and batch behavior.

Wrapper responsibilities should stay narrow:

- Parse CLI args.
- Build a structured `Dictionary<string, object>` request.
- Pass the request to `CommandRouter` for galaxy-bound work.
- Print text, legacy JSON, or LLM JSON exactly once.

Do not put GRAccess COM logic in command wrappers unless the operation is explicitly one-shot and cannot be session-routed.

## Route Through The Dispatcher

Galaxy-bound behavior belongs in `GRAccess/GRAccessCommandDispatcher.cs`.

When adding a handler:

- Dispatch by command family and subcommand.
- Keep daemon and one-shot behavior identical by using the same dispatcher path.
- Keep all daemon COM access on `StaComThread`.
- Check GRAccess `CommandResult.Successful` or every result in `CommandResults`.
- For object mutations, follow `CheckOut()` -> modify -> `Save()` -> `CheckIn(comment)`.
- Use defensive reads for optional COM-backed properties.
- Represent unreadable fields as structured unavailable data instead of throwing when a partial result is useful.

For object-reference assignment, prefer resolving named GRAccess objects first and only fall back to string assignment when the API allows it.

## Output Rules

Legacy behavior is part of the contract.

- Do not change existing `--json` shapes for existing commands.
- `--llm-json` must use the stable envelope:

```json
{
  "success": true,
  "command": "object get",
  "galaxy": "ZB",
  "target": "TestMachine",
  "data": {},
  "commandResult": null,
  "warnings": [],
  "unavailable": []
}
```

- Failure envelopes must include `success: false`, `error`, `exitCode`, and any useful GRAccess command result details.
- Normal log lines must not pollute `--llm-json` stdout.
- Include unavailable fields in `unavailable` when GRAccess lacks direct support or the local COM layer throws.
- Include `CommandResult` / `CommandResults` details for mutations.

## Validation And Dry Run

Validation should catch request-shape and safety issues before COM mutation.

- Add required args and confirmation rules to `CommandCapabilityRegistry`.
- Ensure `graccess validate --request plan.json --llm-json` catches missing args, unknown commands, and mismatched confirmation targets.
- Ensure `graccess batch --mode validate --llm-json` validates every step.
- Ensure `--dry-run` validates args, routing, and confirmation without calling mutating GRAccess methods.

If a true GRAccess dry-run is not available, document that dry-run is input and routing validation only.

## Tests

Add focused tests for the changed behavior.

Minimum expected coverage:

- Capability registry entry for the new command.
- Command parsing for the public CLI shape.
- Dispatcher request mapping from CliFx wrapper to command/subcommand/args.
- Confirmation guard behavior for normal, dry-run, and batch paths when the command mutates.
- Legacy `--json` compatibility if an existing command changed.
- `--llm-json` success and failure envelope shape when LLM output is supported.
- Structured IPC round-trip if the command uses arrays, condition lists, booleans, enums, or object batches.
- Fake or mocked handler tests for session route and one-shot route equivalence when practical.

Live validation against `ZB` should be read-only unless the test creates an explicitly named disposable object and removes it afterward. Never run wildcard bulk mutation live.

## Documentation Updates

Update docs in the same change as the feature.

Required updates:

- `docs/usage.md` for every user-facing command, option, output mode, and example.
- `docs/llm-integration.md` for every LLM-facing command, envelope field, batch behavior, validation behavior, or safety rule.
- `docs/README.md` if a new documentation page is added.
- `AGENTS.md` and `CLAUDE.md` when agent-critical workflows, constraints, or references change.

Domain-specific updates:

- Parsing commands: update `template-parsing.md`, `attribute-parsing.md`, or `script-parsing.md`.
- Editing commands: update `template-editing.md`, `template-instance-editing.md`, `attribute-editing.md`, or `script-editing.md`.
- IDE intent wrappers: update `template-instance-editing.md` and `llm-integration.md`.
- Safety changes: update all docs that include mutation examples.

Documentation should include:

- Command syntax.
- Required flags.
- Confirmation requirements.
- Session behavior.
- `--llm-json` example when useful.
- Any known GRAccess limitation or unavailable field behavior.

## Implementation Checklist

Use this order for most features:

1. Find the GRAccess API operation and confirm signatures.
2. Design the CLI command and safety rule.
3. Add or update capability registry metadata.
4. Add the CliFx wrapper.
5. Add the dispatcher handler.
6. Preserve legacy output and add `--llm-json` if machine-facing.
7. Add validation, dry-run, and batch support where applicable.
8. Add tests.
9. Update docs.
10. Run build and tests.
11. Run read-only smoke validation against `ZB` when the feature can be safely verified.

## Common Pitfalls

- Loading GRAccess from x64 or non-STA code.
- Letting `GRAccessApp` go out of scope while derived objects are still in use.
- Changing legacy `--json` output while adding `--llm-json`.
- Returning success for unsupported COM behavior instead of structured unavailable details.
- Adding a command wrapper but forgetting `CommandCapabilityRegistry`.
- Adding a dispatcher handler that only works in one-shot mode.
- Running mutating live validation against real objects or wildcard selections.
- Assuming GRAccess collections are zero-based.
- Forgetting to update `docs/usage.md`.
