> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mirurobotics.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Config editor

export const OperatorBadge = ({size = "md"}) => {
  return <Tooltip tip="Members with the operator role can execute this action." cta="Workspace roles" href="/admin/users/access-control">
            <Badge icon="wrench" color="orange" size={size}>operator</Badge>
        </Tooltip>;
};

export const Framed = ({image, background, link, alt = "Framed content", borderWidth = "24px", outerRadius = "10px", innerRadius = "6px"}) => {
  const parseShorthand = value => {
    const values = String(value).trim().split(/\s+/);
    switch (values.length) {
      case 1:
        return [values[0], values[0], values[0], values[0]];
      case 2:
        return [values[0], values[1], values[0], values[1]];
      case 3:
        return [values[0], values[1], values[2], values[1]];
      default:
        return values.slice(0, 4);
    }
  };
  const isZero = v => parseFloat(v) === 0;
  const padding = parseShorthand(borderWidth);
  const outer = parseShorthand(outerRadius);
  const cornerMasks = [];
  if (isZero(padding[0]) && isZero(padding[3])) {
    cornerMasks.push(`radial-gradient(circle at 0% 0%, transparent ${outer[0]}, black ${outer[0]})`);
  }
  if (isZero(padding[0]) && isZero(padding[1])) {
    cornerMasks.push(`radial-gradient(circle at 100% 0%, transparent ${outer[1]}, black ${outer[1]})`);
  }
  if (isZero(padding[2]) && isZero(padding[1])) {
    cornerMasks.push(`radial-gradient(circle at 100% 100%, transparent ${outer[2]}, black ${outer[2]})`);
  }
  if (isZero(padding[2]) && isZero(padding[3])) {
    cornerMasks.push(`radial-gradient(circle at 0% 100%, transparent ${outer[3]}, black ${outer[3]})`);
  }
  const backgroundMask = cornerMasks.length > 0 ? cornerMasks.join(", ") : undefined;
  const innerImage = <img src={image} alt={alt} noZoom={link ? true : false} style={{
    display: "block",
    width: "100%",
    margin: 0,
    borderRadius: 0
  }} />;
  return <div style={{
    display: "inline-block",
    position: "relative",
    borderRadius: outerRadius,
    overflow: "hidden"
  }}>
            {}
            {background && <div style={{
    position: "absolute",
    inset: 0,
    backgroundImage: `url(${background})`,
    backgroundSize: "cover",
    maskImage: backgroundMask,
    WebkitMaskImage: backgroundMask,
    maskComposite: "intersect",
    WebkitMaskComposite: "source-in"
  }} />}
            {}
            <div style={{
    position: "relative",
    padding: borderWidth
  }}>
                <div style={{
    borderRadius: innerRadius,
    overflow: "hidden",
    lineHeight: 0
  }}>
                    {link ? <a href={link}>{innerImage}</a> : innerImage}
                </div>
            </div>
        </div>;
};

<Framed background="https://assets.mirurobotics.com/docs/v04/images/devices/background.jpeg" image="https://assets.mirurobotics.com/docs/v04/images/devices/editor/config-editor-v3.png" borderWidth="30px 30px 0 0" innerRadius="0 8px 0 0" />

The config editor is the primary way to view and edit a device's configuration files. To edit a device's configurations, you must hold the <OperatorBadge size="sm" /> role.

Open the editor by clicking into a device from the
[Devices page](https://app.mirurobotics.com/devices) and selecting the **Editor**
tab at the top.

## Layout

The editor is split into two resizable panels:

* **Editor panel** — A code editor for editing configuration files or viewing
  historical versions.
* **Controls panel** — Controls what the editor displays and provides actions
  like deploying changes or browsing deployment history.

<Frame>
  ![Config Editor Layout](https://assets.mirurobotics.com/docs/v04/images/devices/editor/layout-temp.png)
</Frame>

***

## Draft

When the **Draft** tab is selected in the controls panel, the editor enters
edit mode. You can modify any configuration file directly in the editor.
Changes are tracked locally until you deploy them.

A draft is automatically created when you open the editor. If the device has
existing deployments, the draft is based on the most recent one. If this is a
new device with no deployments, the draft is initialized from the release's
default configuration.

### Change list

The controls panel shows a **change list** that summarizes every modification in
the current draft. Changes are grouped by file, with each file section showing
its name and a change count (e.g., "3 changes") or "New file" for newly added
files. Within each section, individual changes are listed with:

* The **type** of change — added, modified, or deleted — color-coded green,
  yellow, or red respectively.
* The **JSON path** of the affected value (e.g., `settings > network > ip`).
  Long paths are truncated; hover to see the full path.

Files with no changes show a "No changes" label.

<Frame>
  ![Draft Changelog](https://assets.mirurobotics.com/docs/v04/images/devices/editor/draft-changelog.png)
</Frame>

### Deploying changes

Click the **Deploy** button to start the deployment process.

<Frame>
  ![Deploy Dialog](https://assets.mirurobotics.com/docs/v04/images/devices/editor/deploy-dialog.png)
</Frame>

<Steps>
  <Step title="Review the summary">
    See the summary of changes for each file.
  </Step>

  <Step title="Add a description">
    Enter a description for the deployment. This field is required.
  </Step>

  <Step title="Confirm the device name">
    Type the device name exactly as shown to confirm the deployment.
  </Step>

  <Step title="Deploy">
    Click **Deploy** to push the changes. After a successful deployment, the
    editor automatically switches to the History tab and selects the new
    deployment.
  </Step>
</Steps>

<Note>
  The Deploy button is disabled when:

  * The device is offline.
  * The draft has no changes.
  * Any file contains JSON syntax errors.

  Hover over the disabled button to see the reason.
</Note>

***

## History

When the **History** tab is selected, the editor switches to read-only mode and
displays past deployments.

### Deployment list

The controls panel shows all deployments grouped by release version. Within
each group, deployments are listed from most recent to oldest with each entry showing:

* Description
* Deployment status and ID
* Who created it and when

Click a deployment to view it's contents. The selected deployment is called the
**head** deployment, and its configuration files are loaded into the editor.
The head deployment is highlighted with a solid left border and a subtle
background. When a base deployment is selected for diffing, it is indicated with
a dashed left border.

<Frame>
  ![History List](https://assets.mirurobotics.com/docs/v04/images/devices/editor/history-list.png)
</Frame>

**Right-click** a deployment to open a context menu with options to:

* **Redeploy** — Restore an archived deployment (see [Redeploy](#redeploy)).
* **Set as diff base** — Use this deployment as the comparison baseline.
* **Copy ID** or **Copy description**.

<Frame>
  ![Context Menu](https://assets.mirurobotics.com/docs/v04/images/devices/editor/context-menu.png)
</Frame>

### Diff and read-only modes

In the History tab, the editor supports two view modes:

* **Read-only** — Displays the head deployment's files without any diff
  highlighting.
* **Diff** — Highlights the differences between the head and base deployments
  using color-coded decorations:
  * **Green** — Added lines.
  * **Yellow** — Modified lines, showing the old and new values.
  * **Red** — Deleted lines, showing the removed content.
    content.

<Frame>
  ![View Modes](https://assets.mirurobotics.com/docs/v04/images/devices/editor/view-modes.png)
</Frame>

### Diff navigation

When viewing a diff, navigation controls appear as a floating overlay above the
footer:

* **Change navigation** — Step through individual changes within the current
  file using the previous/next buttons. A position label (e.g., "1 of 3")
  tracks your place. Open the changes dropdown to see all changes listed by
  type and JSON path, and jump to any one directly.
* **File navigation** — When multiple files contain changes, use the file
  navigation controls to jump between them. A label (e.g., "1 of 3 files")
  shows your position.

The currently focused change is highlighted with a flash animation.

<Frame>
  ![Diff Navigation](https://assets.mirurobotics.com/docs/v04/images/devices/editor/diff-navigation.png)
</Frame>

### Base vs. Head

The diff view compares two deployments:

* **Base** — The older deployment used as the comparison starting point.
  Defaults to the deployment immediately before the head. You can change it
  using the diff selector in the toolbar or by right-clicking a deployment and
  selecting "Set as diff base." Only deployments older than the head are
  available as a base.
* **Head** — The currently selected deployment. Shown as a read-only label in
  the diff selector.

<Frame>
  ![Base vs. Head](https://assets.mirurobotics.com/docs/v04/images/devices/editor/base-head.png)
</Frame>

### Redeploy

You can redeploy the configurations from any archived deployment. Right-click the
deployment in the history list and select **Redeploy** to open the redeploy
dialog.

The redeploy dialog shows:

* A card with the original deployment's details (description, status, ID,
  creator, and date).
* A description field (pre-filled with a reference to the original deployment).

<Frame>
  ![Redeploy Dialog](https://assets.mirurobotics.com/docs/v04/images/devices/editor/redeploy.png)
</Frame>

***

## Deployment alert

If another user (or system) deploys to the same device while you have the editor
open, an alert appears with the new deployment's details. The alert offers different
options depending on whether you have unsaved edits:

**No edits in progress:**

* **Acknowledge** — Accepts the external deployment and resets your draft to
  match it.

**Edits in progress:**

* **Discard** — Discards your edits and resets the draft to the external
  deployment.
* **Keep** — Merges your edits on top of the external deployment using a
  three-way JSON merge, preserving your changes where possible.

<Frame>
  ![Deployment Alert](https://assets.mirurobotics.com/docs/v04/images/devices/editor/deployment-alert.png)
</Frame>

***

## Editor settings

Three **admin-only** workspace settings control how the editor behaves.

<Frame>
  ![Editor Settings](https://assets.mirurobotics.com/docs/v04/images/devices/editor/settings.png)
</Frame>

* **Allow offline deployments** (off by default) — Allow deployments to
  devices that are currently offline. When off, the Deploy button is disabled
  on offline devices.
* **Skip deploy confirmation** (off by default) — Remove the device-name
  confirmation step from the [deploy dialog](#deploying-changes). When off,
  you must type the device name to confirm each deployment.
* **Format files on deploy** (on by default) — Automatically format config
  files before each deployment.

Formatting fires when the deploy dialog opens. With this setting off, you can
still format any open file manually from the editor's overflow menu (**⋯**) —
click **Format file** or press **⌘⇧F** (Mac) / **Ctrl+Shift+F**
(Windows/Linux).

<Frame>
  ![Format action](https://assets.mirurobotics.com/docs/v04/images/devices/editor/format-action.png)
</Frame>
