---
name: beam-update
description: Use when the user invokes /beam-update or asks to update beam-react, the Beam plugin, or the Beam MCP. Detects version drift, surfaces the changelog, and automates the npm + plugin cache update. The only manual step left for the user is /reload-plugins.
---

# beam-update

> **Network access:** this skill fetches migration guides from `https://react.beam.viasat.com` via `curl`. This is the one authorized outbound request the skill makes.

Step 7 may involve editing Beam component usage to apply migration steps. When it does, follow the canonical rules in `references/rules-preamble.md` (token rule, composition rule, honesty rule).

## Activation gate

Read `package.json`. If `@viasat/beam-react` is not in `dependencies` or `devDependencies`, tell the user this skill requires a project that depends on `@viasat/beam-react` and stop.

## Checklist

1. **Check versions.** Run both commands via Bash:

   ```bash
   node -p "require('./node_modules/@viasat/beam-react/package.json').version"
   npm view @viasat/beam-react version --@viasat:registry=https://registry.npmjs.org
   ```

   If installed matches latest, tell the user they're already up to date and stop.

2. **Surface the changelog.** The changelog is bundled at the root of the installed package. Read exactly `./node_modules/@viasat/beam-react/CHANGELOG.md` via Bash (do not look elsewhere or fetch it remotely). Extract the entries for versions between installed (exclusive) and latest (inclusive). Present them in a brief summary, breaking changes first, then notable additions.

   If the file is absent (installed versions predating changelog bundling won't ship it), note that the changelog couldn't be found locally and continue. Do not block the update on this.

3. **Check migration guides.** The running MCP is pinned to the *installed* version and cannot see guides published in the target version, so fetch from the public prod site with `curl` (not WebFetch):

   ```bash
   curl -s https://react.beam.viasat.com/llms.txt
   ```

   Extract the `## Migrations` section. Each entry looks like `- [<title>](llms/<slug>.txt): <description>` (e.g. `[v2.35.0 to v2.36.0](llms/migrations-v2-35-0-to-v2-36-0.txt)`). Titles use inconsistent granularity (point-release vs major-span), so judge which entries' version span intersects installed (exclusive) → target (inclusive). For each applicable guide, fetch the full body:

   ```bash
   curl -s https://react.beam.viasat.com/llms/<slug>.txt
   ```

   Summarize the required migration steps, breaking/manual changes (renamed tokens, API changes) first. If no guide applies, say so and continue. If either `curl` fails (offline / VPN), note that migration guides could not be fetched and continue. Never block the update on this.

4. **Assess real impact on this codebase.** Do not tell the user to grep for themselves. You do the read-only scan and report exactly what applies to them. For each applicable guide, translate its concrete changes into searchable signals.

   Search the user's source with Grep/Glob (exclude `node_modules`, `dist`, and build output). Report actual exposure grouped by change: the impacted files with `file:line` references, or, if nothing matches, state plainly that this migration does not affect their code. This scan is read-only and runs **before** the update so it can inform the decision.

5. **Confirm with the user.** Present the installed → latest delta, the migration summary from step 3, and the concrete impact from step 4 (which files change, or "no impact found"), then ask: "Update from X to Y? (yes / no)"

   Make clear that confirming commits them to applying the migration steps (with your help, or manually). The update creates a window where their code and the installed package disagree until the migration is done. If step 4 found no impact, note that the update is expected to be a clean bump. Do not proceed until the user explicitly confirms.

6. **Update, then verify the bump.** Run via Bash and report each command's output. If a command fails, stop, show the error, and do not continue.

   ```bash
   npm update @viasat/beam-react
   ```

   Re-read the installed version and confirm it actually reached the target latest from step 1:

   ```bash
   node -p "require('./node_modules/@viasat/beam-react/package.json').version"
   ```

   `npm update` respects the semver range in `package.json`, so if the range is too narrow it is a silent no-op and the version stays put. If the installed version is still not the target, fall back to an explicit install (this also rewrites the `@viasat/beam-react` range in `package.json`):

   ```bash
   npm install @viasat/beam-react@<latest>
   ```

   Re-read the version once more. If it still has not reached the target, stop and report the mismatch instead of proceeding; something is wrong (lockfile, workspace constraint, or registry) and the plugin cache must not be refreshed against a stale install. Only once the install is confirmed at the target version, refresh the plugin cache:

   ```bash
   claude plugin marketplace update beam
   claude plugin update beam-react-claude-plugin@beam
   ```

7. **Apply migration steps (interactive).** If step 4 found impacted sites, offer to apply the changes to exactly those sites now, *after* the update, so edits are made against the newly installed version and can be verified. Walk each change (renamed tokens, API updates) with per-change approval, and verify as you go (typecheck / lint) where practical. If step 4 found no impact, there is nothing to apply, so skip. Skip too if the user declines. This must happen **before** the reload, since `/reload-plugins` restarts the session.

8. **Tell the user to reload.** Respond with:

   > Update complete. Run `/reload-plugins` to pick up the new version in this session.

   Explain that `/reload-plugins` is required because Claude loads plugins into memory at session start; the update takes effect only after reload.

## Red flags, STOP and re-check

| Rationalization | Reality |
|---|---|
| "npm update might break other deps, skip it" | `npm update @viasat/beam-react` respects semver ranges in `package.json`; it won't arbitrarily upgrade unrelated packages. |
| "Just update the plugin cache, skip npm" | The plugin's assets (skills, references) live in the npm package. Without the npm update the cache still holds the old content. |
| "Skip `claude plugin update`, marketplace update is enough" | The marketplace update refreshes the index; `claude plugin update` applies the new version to Claude's plugin cache. Both steps are required. |
| "Skip the migration check, the changelog covers it" | The changelog lists *what* changed; the migration guide lists *what the user must do* (renamed tokens, API changes). They are not interchangeable. |
| "Apply migration edits before running the update" | Migration guides target the new version's API. Editing before the update writes to code that isn't installed yet and can't be verified. Update first, then migrate. |
| "Use the MCP `getConcept` for migration guides" | The running MCP is pinned to the *installed* version and won't have guides published in the target version. Fetch from `react.beam.viasat.com` via `curl`. |
| "Tell the user to grep for impacted usages themselves" | You have read access to their source, so scan it and report the exact `file:line` sites. Handing the user a command to run is the UX this skill exists to remove. |
| "The guide lists changes, so it must affect them" | A guide is generic; the user may use none of the changed tokens/APIs. Scan first: a migration with zero matches is a clean bump, and saying so is valuable. |
| "`npm update` exited cleanly, so it upgraded" | `npm update` is a silent no-op when the range in `package.json` does not allow the new version. Always re-read the installed version after; if it did not move, run `npm install @viasat/beam-react@<latest>` and verify again before touching the plugin cache. |

## Not in scope

Upgrading unrelated dependencies, modifying `package.json` version ranges for anything other than `@viasat/beam-react`, resolving peer dependency conflicts, or updating other `@viasat/*` packages independently.
