> For the complete documentation index, see [llms.txt](https://docs.appmixer.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.appmixer.com/build-connectors-with-a-coding-agent/shipping-changes.md).

# Shipping Changes

After the first publish in chapter 4, every change — a fix from testing, a review finding, a new field, a new component — goes out the same way: you publish again. There is no update command.

What this chapter covers is what publishing again actually *does* — to what the instance serves, and to the flows already running on it — and why the command that looks like the way to force it is the most dangerous one in the CLI.

## The prompt

> Don't remove anything on the instance. Bump the version in component.json of every component you changed since the last publish, then publish.

It reads like over-instruction, and it is not. The `test-connector` skill tells the agent that the way to deal with a component that looks stale on the instance is to remove it and publish it again, with the commands written out. Left alone, an agent that sees something it did not expect follows that instruction — no stop, no question. Given this prompt, it compares the instance's packages with your files, bumps only what changed, and publishes.

## What publishing again does

**The instance serves the version you published last**, whatever `component.json` called it. Publishing stores a new copy and retires the ones before it: they stay in storage, but nothing is served from them any more.

| You published                         | What the instance serves     | What it means                                       |
| ------------------------------------- | ---------------------------- | --------------------------------------------------- |
| a changed component, version bumped   | the new version only         | Running flows move to it by themselves — see below  |
| a changed component, **same version** | the new code, within seconds | It works, but nothing records that anything changed |
| an unchanged component                | the same thing as before     | Harmless                                            |

**Bump `component.json`'s version whenever that component changes** anyway, and the bundle's with a changelog line. Not because a same-version republish is unpredictable — it is not — but because the version is the only record of what is running, the only thing a changelog can point at, and the difference between a change that flows pick up on their own and one that stops them ([Flows follow the version](#flows-follow-the-version)).

Shared files — `lib.js`, `auth.js`, `quota.js` — sit beside the components, so editing one changes components whose own files did not move. Treat it as a change to every component that uses it.

## Bump the bundle, and say what changed

Nothing bumps `bundle.json` for you:

```json
{
    "name": "acme.eventbrite",
    "version": "1.1.0",
    "changelog": {
        "1.1.0": [
            "Create Event: Currency is now a dropdown of the 25 currencies Eventbrite accepts."
        ]
    }
}
```

A change that breaks existing accounts or flows is a major version, and the changelog should say so. The usual one is an auth change — [Day-to-Day Work](/build-connectors-with-a-coding-agent/daily.md#changing-the-auth-type-of-a-published-connector).

## Seeing what the instance actually serves

```bash
appmixer component ls -m <vendor>.<connector> --json     # the manifests, with their versions
```

Without `-m` the listing is component names only, and the version — the thing you are checking — is not in it.

`appmixer component get` is a different question. It hands you **every copy ever published** of that component, newest and retired alike, all under the same path inside the zip:

```bash
appmixer component get <vendor>.<connector>.<module>.<Component> -o /tmp/published.zip
unzip -l /tmp/published.zip      # one line per historical copy
```

Repeated paths there are history, not a broken instance. `unzip` extracts only the last of them, so a quick look tells you nothing either way. Read the versions out of the archive without extracting it if you want to see what has been published over time.

## Flows follow the version

A flow names the version of each component it uses — E2E flow files in `artifacts/test-flows/` carry a `version` next to each `type` — but that name is a **floor, not a pin**. At every execution the engine takes the newest published version compatible with it, which means the same major:

| You publish                        | A running flow that names `1.0.0`                                  |
| ---------------------------------- | ------------------------------------------------------------------ |
| `1.0.1`, `1.1.0`                   | switches to it within seconds, by itself. No re-import, no restart |
| `1.1.0` again, with different code | runs the new code, just as quietly                                 |
| `2.0.0`                            | **stops processing at that component**                             |

The first two are what makes shipping a fix cheap: publish, and the flows that use it are already on it. The flow file still says `1.0.0`; what ran is in the logs, as `componentVersion`.

{% hint style="danger" %}
**A major bump of a `component.json` stops flows without saying so.** The flow stays `running` and its trigger keeps firing, but the component behind the bump never executes again: no error, nothing in the logs, nothing in dead letters. Starting such a flow afresh at least fails loudly, with `No compatible version of <type> found for requested version <old>` or `Missing component.json <type>` and a `400`.

So a component major is a change you have to carry out yourself: update the version in every flow that uses it, import them again, and restart them. For E2E flows that is the flow file plus `appmixer e2e import`.
{% endhint %}

After an ordinary bump, re-running the E2E flows needs nothing special:

```bash
appmixer e2e run <flowId> --fix
```

After a major, update the `version` in the flow files first, then import and run:

```bash
appmixer e2e import src/<vendor>/<connector>/artifacts/test-flows
appmixer e2e run <flowId> --fix
```

## Never remove to update

```bash
appmixer remove <vendor>.<connector>                          # every component
appmixer remove <vendor>.<connector>.<module>.<Component>     # one component
```

{% hint style="danger" %}
`appmixer remove` cannot be undone. Until the next publish the components do not exist on the instance, and **any running flow that uses them fails**. On a shared or production instance that is an outage.
{% endhint %}

A version bump ships a change; `remove` never needs to. Its legitimate use is clearing components you renamed, so the old names stop being offered. For components you deleted from the connector, use `appmixer publish --replace-all`.

**Do not count on your agent to stop first.** Nothing in the skills requires a stop before `appmixer remove`; some agents ask on their own, some do not. Draw the line yourself:

* **In the prompt** — "Before any command that removes or overwrites something on the instance, stop and ask me."
* **In the agent's permissions** — set the agent to always ask before `appmixer remove`. How, per agent, is in `docs/agents.md` in the [appmixer-skills](https://github.com/Appmixer-ai/appmixer-skills) repository.

After any remove, confirm it happened before publishing again — a `502` or `504` may or may not have done anything:

```bash
appmixer component ls <vendor>.<connector>
```

## Verify

```bash
appmixer component ls -m <vendor>.<connector> --json      # the versions now served
```

The component you changed is at its new version, and the ones you did not touch are where they were. `appmixer bundle ls` cannot answer this — it lists installed bundles, and publishing does not register one. Then re-run the E2E flows: a patch or minor bump reaches them by itself, a major one needs their pins updated first.

Next: [Day-to-Day Work](/build-connectors-with-a-coding-agent/daily.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.appmixer.com/build-connectors-with-a-coding-agent/shipping-changes.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
