# OfficeCLI Commands: Understanding set, add, remove, move, and swap

> Understand OfficeCLI commands set, add, remove, move, and swap for modifying Office files. Learn their distinct functions: update, create, delete, reposition, or exchange elements.

- Repository: [OfficeAI/OfficeCLI](https://github.com/iofficeai/OfficeCLI)
- Tags: how-to-guide
- Published: 2026-08-08

---

**OfficeCLI commands `set`, `add`, `remove`, `move`, and `swap` represent five distinct document mutation operations that modify Microsoft Office files through a resident server architecture, differing primarily in whether they update properties, create elements, delete nodes, reposition items, or exchange positions between two elements.**

The iOfficeAI/OfficeCLI repository provides a command-line interface for programmatically manipulating Microsoft Office documents. These five core **OfficeCLI commands** form the complete mutation API for modifying document structure, content, and properties through a centralized request handler.

## Command Architecture Overview

All five verbs follow an identical four-stage execution pipeline implemented in [`src/officecli/ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/ResidentServer.cs):

1. **Command reception** – The CLI wraps arguments in a `ResidentRequest` object
2. **Editable promotion** – `PromoteToEditable()` opens the document in write-mode
3. **Verb-specific execution** – The request routes to dedicated `Execute*` methods
4. **Watch notification** – The server notifies attached UI components of changes

This architecture ensures consistent permission handling and state management across all mutation operations.

## Detailed Breakdown of OfficeCLI Mutation Commands

### set – Update Existing Properties

The `set` command modifies properties of existing elements without creating or deleting nodes. In [`src/officecli/ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/ResidentServer.cs) at lines 10890-10892, the implementation calls `ExecuteSet(request)` followed by `NotifyWatchSlideChanged(request.GetArg("path"))`.

Use this command to change attributes like colors, styles, or text content. The notification targets only the parent slide containing the modified element.

### add – Create New Elements

The `add` command inserts new elements under specified parents, such as charts, tables, or slides. The implementation at lines 10994-11004 captures the previous slide count via `GetPptSlideCount()`, executes `ExecuteAdd(request)`, then determines notification type based on the parent location.

Root-level additions (path `/`) trigger *root-changed* notifications for slide-count updates. Child element additions emit *slide-changed* notifications for the target slide.

### remove – Delete Elements or Slides

The `remove` command deletes existing elements or entire slides. Lines 11066-11076 show the handler storing the initial slide count and path, executing `ExecuteRemove(request)`, then checking if the removed path represents a top-level slide using `WatchMessage.ExtractSlideNum(path) > 0 && !path.Contains("/shape[")`.

Top-level slide removals emit *root-changed* notifications. Other deletions send *slide-changed* messages for the containing slide.

### move – Relocate Elements

The `move` command repositions elements between locations without altering content. Implemented at lines 11188-11191, it calls `ExecuteMove(request)` followed by `NotifyWatchSlideChanged(request.GetArg("path"))` for the destination slide.

This efficiently handles reordering shapes between slides or adjusting slide sequences while minimizing UI refresh scope.

### swap – Exchange Elements Atomically

The `swap` command performs atomic exchanges between two elements or slides. Unlike other commands, this triggers a **full document refresh** because the operation may affect multiple slides or deck ordering. Lines 11224-11227 implement this through `ExecuteSwap(request)` followed by `NotifyWatchFullRefresh()`.

## Source Code Implementation

The command dispatch logic resides in [`src/officecli/ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/ResidentServer.cs) within the main processing loop. Each verb case follows the pattern:

```csharp
PromoteToEditable();
Execute[Verb](request);
[NotificationMethod]();

```

The resident server treats these as state-changing mutations requiring write-mode document access through the editable handler.

Verb definitions and shorthand aliases appear in [`src/officecli/Help/SchemaHelpFlatRenderer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Help/SchemaHelpFlatRenderer.cs) at lines 46-48, where single-letter shortcuts map to these primary commands.

## Practical Usage Examples

```bash

# set - Modify paragraph formatting

officecli set report.docx /body/p[1] --prop bold=true

```

```bash

# add - Insert new shape on slide 2

officecli add deck.pptx /slide[2] --type shape --prop text=Hello --prop fill=yellow

```

```bash

# remove - Delete slide 5

officecli remove deck.pptx /slide[5]

```

```bash

# move - Relocate shape between slides

officecli move deck.pptx /slide[3]/shape[2] --to /slide[4]

```

```bash

# swap - Exchange slide positions

officecli swap deck.pptx /slide[1] /slide[7]

```

## Summary

- **set** updates properties of existing elements and triggers slide-specific notifications via `NotifyWatchSlideChanged`
- **add** creates new elements with type and property specifications, emitting root-changed or slide-changed alerts based on parent hierarchy
- **remove** deletes nodes or slides, with notification type determined by whether the target is a top-level slide
- **move** repositions elements between locations while preserving content, notifying only the destination slide
- **swap** exchanges two elements atomically and forces a full document refresh through `NotifyWatchFullRefresh` due to potential widespread impact

## Frequently Asked Questions

### What is the difference between OfficeCLI move and swap commands?

The `move` command relocates a single element to a new position, while `swap` exchanges the positions of two elements atomically. According to the source code in [`ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ResidentServer.cs), `move` triggers a slide-specific notification for the destination, whereas `swap` invokes `NotifyWatchFullRefresh()` because the operation may affect document-wide ordering and require complete UI synchronization.

### When should I use set versus add in OfficeCLI?

Use `set` when modifying existing element properties like colors, text styles, or formatting without changing document structure. Use `add` when creating new elements such as slides, shapes, or tables. The `set` command never creates nodes, while `add` always inserts new content under the specified parent path.

### Why does the swap command trigger a full document refresh?

The `swap` command triggers `NotifyWatchFullRefresh()` because exchanging two elements—particularly slides—can alter the ordering and numbering across the entire document. This ensures connected UI components refresh the complete view rather than individual slides, maintaining consistency when deck order changes.

### How does OfficeCLI handle permissions for mutation commands?

All five mutation commands (`set`, `add`, `remove`, `move`, `swap`) call `PromoteToEditable()` before execution, which opens the document in write-mode through the editable handler. This centralized permission check in [`ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ResidentServer.cs) ensures modifications only occur when the resident server has appropriate write access to the target file.