--- name: maintenance description: > Investigate, adopt, and verify dependency updates — with special handling for `@cyanheads/mcp-ts-core`. Captures what changed, understands why, cross-references against the codebase, adopts framework improvements, syncs project skills, and runs final checks. Supports two entry modes: run the full flow end-to-end, or review updates you already applied. metadata: author: cyanheads version: "2.10" audience: external type: workflow --- ## When to Use - After running `bun update --latest` yourself and wanting to review the impact (**Mode B** — typical) - To run the whole flow end-to-end — outdated check → update → investigate → adopt → verify (**Mode A**) - Periodically, to check for skill drift from the package ## Entry Modes | Mode | Starting Point | First Step | |:-----|:---------------|:-----------| | **A — Full flow** | Lockfile is current; want to update | Step 1 | | **B — Post-update review** | User already ran `bun update --latest` + `bun run rebuild` + `bun run test` | Skip to Step 3 with the update output or a `bun.lock` diff | Both modes converge at Step 3 and end at Step 8. ## Steps ### 1. Survey what's outdated (Mode A only) ```bash bun run devcheck --only outdated ``` Wraps `bun outdated` with the project's `devcheck.config.json` allowlist applied, so intentionally-pinned packages don't surface as actionable. Plain `bun outdated` works too if you want the unfiltered view. Note: `bun update --latest` crosses semver majors; `bun update` alone respects ranges. Use `--latest` unless a package is intentionally pinned. ### 2. Apply the update (Mode A only) ```bash bun update --latest ``` Capture the `↑ package old → new` lines from stdout — these feed Step 3. Alternatively, diff `bun.lock` to surface version deltas after the fact. ### 3. Investigate changelogs Invoke the **`changelog`** skill with the captured list of updated packages. It resolves each repo, fetches release notes (or CHANGELOG entries) between old and new versions, and cross-references changes against actual imports in `src/`. Output per package: what changed, impact on this project, action items. Do not redo this investigation inline — the `changelog` skill handles tag-format detection, monorepo patterns, and fallbacks. If the skill cannot resolve a package (private repo, no tags, no CHANGELOG), note it in Step 8 under "Open decisions" and proceed. ### 4. Framework review (`@cyanheads/mcp-ts-core`) **Skill-version paradox.** If `node_modules/@cyanheads/mcp-ts-core/framework-skills/maintenance/SKILL.md`'s `version` exceeds the one running, run Step 5 Phase A first and re-invoke `maintenance` — otherwise feature-adoption rows added in the new version silently don't surface. After Phase A, confirm the running skill version matches the package before continuing. If the session still has the old skill loaded, exit and restart. If `@cyanheads/mcp-ts-core` was updated, do a deeper pass beyond what the `changelog` skill covers. The framework ships a **directory-based changelog** grouped by minor series (`.x` semver-wildcard convention) — one file per released version at `node_modules/@cyanheads/mcp-ts-core/changelog/.x/.md`. Read only the files between old and new rather than scanning a monolithic file. Example — `0.5.2 → 0.5.4` means reading two new version files: - `node_modules/@cyanheads/mcp-ts-core/changelog/0.5.x/0.5.3.md` - `node_modules/@cyanheads/mcp-ts-core/changelog/0.5.x/0.5.4.md` Cross-series updates span multiple directories — e.g., `0.4.1 → 0.5.2` reads `0.5.x/0.5.0.md`, `0.5.x/0.5.1.md`, `0.5.x/0.5.2.md`. Enumerate the series directories under `node_modules/@cyanheads/mcp-ts-core/changelog/` to find the relevant files. If the per-version directory isn't present (pre-0.5.5 releases, or downstream package that hasn't adopted the convention), fall back to the monolithic rollup at `node_modules/@cyanheads/mcp-ts-core/CHANGELOG.md` and extract the relevant sections manually. Scan specifically for: | Area | Adoption Check | |:-----|:---------------| | New `/errors` surface — factories, typed contracts (`errors[]` + `ctx.fail`), `httpErrorFromResponse` | Replace ad-hoc `new McpError(...)` with factories; declare `errors: [...]` on tools that surface domain-specific failure modes; route declared throws through `ctx.fail(reason, …)` so the conformance lint is happy | | Existing factory choice — semantic audit | Beyond factory-vs-`new McpError`: audit each `throw factory(...)` against intent. `invalidParams` (-32602) is for malformed JSON-RPC params (wrong-shape post-Zod is rare); semantic post-shape validation should use `validationError` (-32007). `notFound` for missing entities, `conflict` for state collisions, `unauthorized` vs `forbidden` for unauth vs scope-denied. Wrong codes degrade `mcp_error_classified_code` observability and break client retry logic — fix during this pass even if not adopting contracts yet. | | New utilities in `/utils` | Identify any that supersede local helper code | | New context capabilities | Added `ctx.*` methods worth adopting | | Provider/service APIs | Updates to `OpenRouterProvider`, `SpeechService`, `GraphService`, etc. | | Deprecations | Migrate now, before the next breaking release | | Config changes | New env vars, renamed keys, changed defaults | | Linter rules | New definition-lint rules that may now flag existing tools/resources | | New or materially-changed skills | Note new skills or workflow changes (renamed steps, new checklist items) worth surfacing at end-of-run. Don't auto-invoke — some skills (e.g. `security-pass`) are user-triggered. The per-version changelog entries (e.g. one calling out `security-pass` v1.0) name what changed. | | New template-scaffolded files | Compare `templates/` in the package against the project root. Files that `init` would create for a new project but don't exist in this project are adoption candidates — create them with project-specific values (version, name, description; user-supplied variables from `server.json` go into `userConfig` + `${user_config.