Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions .claude/skills/outdated-packages/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
---
name: outdated-packages
description: Check for outdated packages in the repo.
---

You are an expert dependency auditor specializing in JavaScript/TypeScript monorepo ecosystems. Your primary function is to generate comprehensive, well-organized reports of outdated packages with changelog intelligence.

## Your Mission

Generate a concise, unified markdown report of all outdated packages across this pnpm monorepo, categorized by update safety, with changelog URLs and summaries of what changed.

## Step-by-Step Process

### Step 1: Get Outdated Packages

Run the following command from the repository root:
```bash
pnpm check-updates
```

This will show all outdated packages across all workspace packages. Parse the output carefully to extract:
- Package name
- Current version
- Available version

If no outdated packages are found, report: "All packages are up to date" and stop.

### Step 2: Maintain Changelog Registry

Check if `workspace-changelogs.json` exists in the root directory. If not, create it as an empty JSON object `{}`.

For every outdated package identified:
1. First check if `workspace-changelogs.json` already contains a changelog URL for that package
2. If not found, search for the changelog URL:
- Check the package's repository on GitHub/GitLab for a CHANGELOG.md or releases page
- Check the package's npm page for repository links
- Use common patterns like `https://github.com/<org>/<repo>/releases` or `https://github.com/<org>/<repo>/blob/main/CHANGELOG.md`
3. Add newly discovered URLs to `workspace-changelogs.json`

**CRITICAL:** After all updates, ensure the keys in `workspace-changelogs.json` are in strict alphabetical order. Rewrite the file if needed to maintain this ordering.

The format of `workspace-changelogs.json` should be:
```json
{
"ajv-formats": "https://github.com/ajv-validator/ajv-formats/releases",
"eslint": "https://github.com/eslint/eslint/releases",
"typescript": "https://github.com/microsoft/TypeScript/releases"
}
```

### Step 3: Categorize Updates

For each outdated package, determine if it's a safe update or a major update:

- **Safe Updates**: Minor or patch version bumps (e.g., 9.37.0 β†’ 9.38.0, 7.1.7 β†’ 7.1.8)
- **Major Updates**: Major version bumps (e.g., 2.2.0 β†’ 3.1.2)

For packages that do NOT follow standard semver (e.g., 0.x versions or non-standard versioning):
- Check the changelog to determine if there are breaking changes
- If breaking changes are found, categorize as Major
- If you cannot determine, note this uncertainty explicitly

### Step 4: Gather Changelog Summaries

For every outdated package, visit the changelog URL from `workspace-changelogs.json` and read the relevant release notes between the current version and the available version. Write a concise one-line summary of the most important changes.

For major updates, prefix the summary with **BREAKING** and describe what broke.

If you cannot access or find a changelog, note: "Changelog not available"

### Step 5: Format the Report

Produce the report in this exact structure:

```markdown
# Updates
- <package>: <current> => <available> | <changelog-url>
- <package>: <current> => <available> | <changelog-url>

# Safe to Update
- <package>: <current> => <available>
- <package>: <current> => <available>

# Major Updates
- <package>: <current> => <available>
- <package>: <current> => <available>

# Summary

- **<Package> <version>**: <concise description of changes>
- **<Package> <version>**: BREAKING - <description of breaking changes>
```

## Formatting Rules

- List each package individually β€” do NOT group packages by common prefix (e.g., list `@vue/compiler-core` and `@vue/compiler-dom` separately)
- Do NOT separate root dependencies vs package dependencies β€” produce one unified list
- Sort packages alphabetically within each section
- Keep summaries to one line each, focusing on the most impactful changes
- If a section would be empty (e.g., no major updates), still include the heading with a note like "None"

## Quality Checks

Before presenting the report:
1. Verify every package in the Updates section appears in exactly one of Safe/Major sections
2. Verify every package has a summary entry
3. Verify `workspace-changelogs.json` keys are alphabetically ordered
4. Verify no packages are duplicated
5. Verify version numbers match the `pnpm check-updates` output exactly
150 changes: 150 additions & 0 deletions .claude/skills/update-packages/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
---
name: update-packages
description: "Update packages from the most recent /outdated report. Usage: /update-packages [safe|major] (default: safe). Requires /outdated to have been run first."
---

You are a dependency update assistant for a pnpm monorepo.

## Prerequisite

This skill requires that the `/outdated` skill has already been run in this conversation and produced a report with "Safe to Update" and/or "Major Updates" sections. If you cannot see these sections from a previous `/outdated` report in this conversation, tell the user:

> The `/outdated` skill needs to be run first so I can identify which packages to update.

Then stop. Do NOT attempt to determine packages on your own.

## Arguments

- **`safe`** (default): Update packages from the "Safe to Update" section
- **`major`**: Update packages from the "Major Updates" section

If no argument is provided, default to `safe`.

---

## Supply Chain Security Verification (applies to both modes)

Before updating any packages, and after all updates complete, run security checks. This step is critical β€” supply chain attacks via compromised npm packages are increasingly common.

### Pre-update: Capture Baseline

Before starting updates, capture the current audit state so you can compare after:
```bash
pnpm audit 2>&1 | tail -5
```

### During Updates: Trust Policy

pnpm's `trust-policy=no-downgrade` is active in this repo. If `pnpm update` fails with a `ERR_PNPM_TRUST_DOWNGRADE` error, this means the new version lost provenance attestation compared to an earlier version. This is a potential supply chain compromise signal. **Do NOT bypass this check.** Report the package as blocked and move on.

### Post-update: Audit and Verify

After all updates complete (and before running `pnpm run all`):

1. **Run `pnpm audit`** and compare against the baseline. If new vulnerabilities were introduced by the updates, report them to the user immediately.

2. **Check for suspicious install scripts** in updated packages:
```bash
pnpm ls --json -r | grep -A2 '"postinstall"\|"preinstall"\|"install"'
```
Flag any updated package that has install scripts β€” these are the most common vector for supply chain attacks. Known-safe install scripts (e.g., `playwright install`, `esbuild` native binary setup) can be ignored.

3. **Verify package provenance** for any package that looks unfamiliar or has low download counts:
```bash
npm view <package> --json | grep -E '"integrity"|"attestations"|"signatures"'
```

If any security issue is found, **stop and report to the user** before proceeding. Do not continue with verification or further updates.

---

## Mode: safe

### Step 1: Extract the Safe Package List

From the most recent `/outdated` report, extract every package and its target version from the "Safe to Update" section.

Present the list to the user and ask for confirmation before proceeding. The user may choose to exclude specific packages.

### Step 2: Update Packages

For each package, run:
```bash
pnpm update <package>@<target-version> -r
```

The `-r` flag ensures the package is updated across all workspace packages that depend on it.

Run updates in batches of related packages to keep things organized:
- Group `@scope/*` packages together (e.g., all `@types/*`, all `@eslint/*`, all `@vitest/*`)
- Run each batch as a single `pnpm update` command with multiple packages

### Step 3: Verify

After all updates complete:
1. Run `pnpm install` to ensure the lockfile is consistent
2. Run `pnpm run all` to check types, lint, and run unit tests
3. If type errors appear due to duplicate transitive dependency versions (e.g., `@lezer/common@1.5.1` vs `@lezer/common@1.5.2`), deduplicate by running `pnpm update <conflicting-package> -r` and re-run `pnpm run all`
4. Report any failures to the user with the specific packages that may have caused them

### Step 4: Summary

Output the summary (see Summary Format below).

---

## Mode: major

### Step 1: Extract the Major Package List

From the most recent `/outdated` report, extract every package and its target version from the "Major Updates" section.

Present the list to the user and ask for confirmation. The user may choose to exclude specific packages or reorder them.

### Step 2: Update Packages One at a Time

For each package, proceed individually:

1. **Show the user** the package name, version change, and the breaking change summary from the `/outdated` report
2. **Ask for confirmation** before updating this specific package
3. Run the update:
```bash
pnpm update <package>@<target-version> -r
```
4. Run `pnpm run all` to check types, lint, and run unit tests
5. If errors occur:
- Analyze the errors and attempt to fix code that broke due to the breaking changes
- Re-run `pnpm run all` after fixes
- If you cannot resolve the errors, **revert the update** and report the issue to the user:
```bash
pnpm update <package>@<old-version> -r
```
6. If type errors appear due to duplicate transitive dependency versions, deduplicate by running `pnpm update <conflicting-package> -r` and re-run `pnpm run all`
7. Report the result before moving to the next package

### Step 3: Summary

Output the summary (see Summary Format below).

---

## Summary Format

Output a summary of what was updated. Include the changelog summary from the `/outdated` report's "Summary" section for each successfully updated package. This makes the output ready to copy into a PR description.

```markdown
# Updated Packages
- <package>: <old-version> => <new-version> βœ“
- <package>: <old-version> => <new-version> βœ“
- <package>: failed - <reason>

# Blocked Packages
- <package>: <old-version> => <new-version> β€” <reason>

# Status
- pnpm run all: βœ“/βœ—

# What Changed
- **<package> <old-version> => <new-version>** <one-line changelog summary from /outdated report>
- **<package> <old-version> => <new-version>** <one-line changelog summary from /outdated report>
```
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ node_modules
/types
/docs
/coverage
.claude

# Claude Code local(user) settings
**/.claude/*.local.*
33 changes: 17 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@
"build-types": "tsc -p ./tsconfig.types.json && tsc-alias -p tsconfig.types.json",
"build-all": "pnpm cleanup && pnpm build && pnpm build-types",
"check-updates": "pnpm -r -l outdated",
"check-upgrade": "pnpm -r -i --latest update"
"check-upgrade": "pnpm -r -i --latest update",
"all": "pnpm build-types && pnpm lint && pnpm test-ci"
},
"keywords": [
"reactivity",
Expand All @@ -64,28 +65,28 @@
"vue"
],
"devDependencies": {
"@eslint/compat": "~2.0.0",
"@eslint/eslintrc": "~3.3.3",
"@eslint/js": "~9.39.2",
"@stylistic/eslint-plugin": "~5.6.1",
"@eslint/compat": "~2.0.5",
"@eslint/eslintrc": "~3.3.5",
"@eslint/js": "~10.0.1",
"@stylistic/eslint-plugin": "~5.10.0",
"@types/lodash": "~4.17.24",
"@vitest/coverage-v8": "~4.0.18",
"eslint": "~9.39.2",
"@vitest/coverage-v8": "~4.1.4",
"eslint": "~10.2.0",
"eslint-plugin-import": "~2.32.0",
"eslint-plugin-unicorn": "~62.0.0",
"globals": "~16.5.0",
"happy-dom": "~20.0.11",
"lodash": "~4.17.23",
"eslint-plugin-unicorn": "~64.0.0",
"globals": "~17.5.0",
"happy-dom": "~20.8.9",
"lodash": "~4.18.1",
"tsc-alias": "~1.8.16",
"typedoc": "~0.28.15",
"typescript": "~5.9.3",
"typescript-eslint": "8.50.0",
"typedoc": "~0.28.19",
"typescript": "~6.0.2",
"typescript-eslint": "8.58.1",
"vite": "~7.3.1",
"vitest": "~4.0.18",
"vitest": "~4.1.4",
"vue3": "npm:vue@~3.5.13"
},
"engines": {
"node": ">=20.11 || >=22.14",
"node": "^22.14 || ^24.14",
"pnpm": ">=10"
},
"packageManager": "pnpm@10.30.3",
Expand Down
Loading
Loading