diff --git a/.claude/skills/updating/SKILL.md b/.claude/skills/updating/SKILL.md new file mode 100644 index 00000000..f97d5548 --- /dev/null +++ b/.claude/skills/updating/SKILL.md @@ -0,0 +1,164 @@ +--- +name: updating +description: Updates all npm dependencies to their latest versions. Triggers when user asks to "update dependencies", "update packages", or prepare for a release. +user-invocable: true +allowed-tools: Bash, Read, Grep, Glob, Edit +--- + +# updating + + +Your task is to update all npm dependencies to their latest versions, ensuring all builds and tests pass. + + + +**What is this?** +This skill updates npm packages for security patches, bug fixes, and new features. + +**Update Targets:** +- npm packages via `pnpm run update` + + + +**Requirements:** +- Start with clean working directory (no uncommitted changes) + +**CI Mode** (detected via `CI=true` or `GITHUB_ACTIONS`): +- Create atomic commits, skip build validation (CI validates separately) +- Workflow handles push and PR creation + +**Interactive Mode** (default): +- Validate updates with build/tests before proceeding +- Report validation results to user + +**Actions:** +- Update npm packages +- Create atomic commits +- Report summary of changes + + + + +## Process + +### Phase 1: Validate Environment + + +Check working directory is clean and detect CI mode: + + +```bash +# Detect CI mode +if [ "$CI" = "true" ] || [ -n "$GITHUB_ACTIONS" ]; then + CI_MODE=true + echo "Running in CI mode - will skip build validation" +else + CI_MODE=false + echo "Running in interactive mode - will validate builds" +fi + +# Check working directory is clean +git status --porcelain +``` + + +- Working directory must be clean +- CI_MODE detected for subsequent phases + + +--- + +### Phase 2: Update npm Packages + + +Run pnpm run update to update npm dependencies: + + +```bash +# Update npm packages +pnpm run update + +# Check if there are changes +if [ -n "$(git status --porcelain pnpm-lock.yaml package.json)" ]; then + git add pnpm-lock.yaml package.json + git commit -m "chore: update npm dependencies + +Updated npm packages via pnpm run update." + echo "npm packages updated" +else + echo "npm packages already up to date" +fi +``` + +--- + +### Phase 3: Final Validation + + +Run build and test suite (skip in CI mode): + + +```bash +if [ "$CI_MODE" = "true" ]; then + echo "CI mode: Skipping final validation (CI will run builds/tests separately)" + echo "Commits created - ready for push by CI workflow" +else + echo "Interactive mode: Running full validation..." + pnpm run fix --all + pnpm run check --all + pnpm test +fi +``` + +--- + +### Phase 4: Report Summary + + +Generate update report: + + +``` +## Update Complete + +### Updates Applied: + +| Category | Status | +|----------|--------| +| npm packages | Updated/Up to date | + +### Commits Created: +- [list commits if any] + +### Validation: +- Build: SUCCESS/SKIPPED (CI mode) +- Tests: PASS/SKIPPED (CI mode) + +### Next Steps: +**Interactive mode:** +1. Review changes: `git log --oneline -N` +2. Push to remote: `git push origin main` + +**CI mode:** +1. Workflow will push branch and create PR +2. CI will run full build/test validation +3. Review PR when CI passes +``` + + + +## Success Criteria + +- All npm packages checked for updates +- Full build and tests pass (interactive mode) +- Summary report generated + +## Context + +This skill is useful for: + +- Weekly maintenance (automated via weekly-update.yml) +- Security patch rollout +- Pre-release preparation + +**Safety:** Updates are validated before committing. Failures stop the process. diff --git a/.claude/skills/updating/reference.md b/.claude/skills/updating/reference.md new file mode 100644 index 00000000..254f5964 --- /dev/null +++ b/.claude/skills/updating/reference.md @@ -0,0 +1,76 @@ +# updating Reference Documentation + +## Table of Contents + +1. [How the Update Script Works](#how-the-update-script-works) +2. [Files Changed After Update](#files-changed-after-update) +3. [Validation Commands](#validation-commands) +4. [Troubleshooting](#troubleshooting) + +--- + +## How the Update Script Works + +`pnpm run update` runs `scripts/update.mjs` which performs: + +```bash +# 1. Run taze recursively with write mode +pnpm exec taze -r -w + +# 2. Force-update Socket scoped packages (bypasses taze maturity period) +pnpm update @socketsecurity/* @socketregistry/* @socketbin/* --latest -r + +# 3. pnpm install runs automatically to reconcile lockfile +``` + +### Repo Structure + +- **Single package** (not a monorepo, no `packages/` directory) +- Has both `dependencies` and `devDependencies` (published package) +- Runtime deps: `@socketregistry/packageurl-js`, `@socketsecurity/lib`, `form-data` +- Dependencies pinned to exact versions in `package.json` + +--- + +## Files Changed After Update + +- `package.json` - Dependency version pins (both deps and devDeps) +- `pnpm-lock.yaml` - Lock file + +--- + +## Validation Commands + +```bash +# Fix lint issues +pnpm run fix --all + +# Run all checks (lint + type check) +pnpm run check --all + +# Run tests +pnpm test +``` + +--- + +## Troubleshooting + +### taze Fails to Detect Updates + +**Cause:** taze has a maturity period for new releases. +**Solution:** Socket packages are force-updated separately via `pnpm update --latest`. + +### Lock File Conflicts + +**Solution:** +```bash +rm pnpm-lock.yaml +pnpm install +``` + +### SDK Regeneration + +If `@socketsecurity/lib` is updated, the generated SDK types may need +regeneration via `pnpm run generate-sdk`. Check if API types in `types/` +are still valid after updating. diff --git a/.github/workflows/weekly-update.yml b/.github/workflows/weekly-update.yml new file mode 100644 index 00000000..07a561a2 --- /dev/null +++ b/.github/workflows/weekly-update.yml @@ -0,0 +1,175 @@ +name: 🔄 Weekly Dependency Update + +on: + schedule: + # Run weekly on Monday at 9 AM UTC + - cron: '0 9 * * 1' + workflow_dispatch: + inputs: + dry-run: + description: 'Check for updates without creating PR' + required: false + type: boolean + default: false + +permissions: + contents: read + +jobs: + check-updates: + name: Check for dependency updates + runs-on: ubuntu-latest + permissions: + contents: read + outputs: + has-updates: ${{ steps.check.outputs.has-updates }} + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Setup Node.js + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + with: + node-version-file: .node-version + cache: '' + + - name: Setup pnpm + uses: pnpm/action-setup@58e6119fe4f3092a76a7771efb55e04d25b6b26f # v5 + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Check for npm updates + id: check + run: | + echo "Checking for npm package updates..." + HAS_UPDATES=false + NPM_UPDATES=$(pnpm outdated 2>/dev/null || true) + if [ -n "$NPM_UPDATES" ] && ! echo "$NPM_UPDATES" | grep -q "No outdated"; then + echo "npm packages have updates available" + HAS_UPDATES=true + fi + echo "has-updates=$HAS_UPDATES" >> $GITHUB_OUTPUT + + apply-updates: + name: Apply updates with Claude Code + needs: check-updates + if: needs.check-updates.outputs.has-updates == 'true' && inputs.dry-run != true + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Setup Node.js + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + with: + node-version-file: .node-version + cache: '' + + - name: Setup pnpm + uses: pnpm/action-setup@58e6119fe4f3092a76a7771efb55e04d25b6b26f # v5 + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Install Claude Code + run: npm install -g @anthropic-ai/claude-code + + - name: Create update branch + id: branch + run: | + BRANCH_NAME="weekly-update-$(date +%Y%m%d)" + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git checkout -b "$BRANCH_NAME" + echo "branch=$BRANCH_NAME" >> $GITHUB_OUTPUT + + - name: Run updating skill with Claude Code + id: claude + timeout-minutes: 30 + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + CI: 'true' + GITHUB_ACTIONS: 'true' + run: | + if [ -z "$ANTHROPIC_API_KEY" ]; then + echo "⚠️ ANTHROPIC_API_KEY not set - skipping automated update" + echo "success=false" >> $GITHUB_OUTPUT + exit 0 + fi + + claude --print --dangerously-skip-permissions \ + --model sonnet \ + "/updating - Run the updating skill to update all dependencies. Create atomic commits for each update. You are running in CI mode - skip builds and tests. Do not push or create a PR." \ + 2>&1 | tee claude-output.log + + if [ $? -eq 0 ]; then + echo "success=true" >> $GITHUB_OUTPUT + else + echo "success=false" >> $GITHUB_OUTPUT + fi + + - name: Check for changes + id: changes + run: | + if [ -n "$(git status --porcelain)" ] || [ "$(git rev-list --count HEAD ^origin/main)" -gt 0 ]; then + echo "has-changes=true" >> $GITHUB_OUTPUT + else + echo "has-changes=false" >> $GITHUB_OUTPUT + fi + + - name: Push branch + if: steps.claude.outputs.success == 'true' && steps.changes.outputs.has-changes == 'true' + env: + BRANCH_NAME: ${{ steps.branch.outputs.branch }} + run: git push origin "$BRANCH_NAME" + + - name: Create Pull Request + if: steps.claude.outputs.success == 'true' && steps.changes.outputs.has-changes == 'true' + env: + GH_TOKEN: ${{ github.token }} + BRANCH_NAME: ${{ steps.branch.outputs.branch }} + run: | + COMMITS=$(git log --oneline origin/main..HEAD) + COMMIT_COUNT=$(git rev-list --count origin/main..HEAD) + + gh pr create \ + --title "chore(deps): weekly dependency update ($(date +%Y-%m-%d))" \ + --body "## Weekly Dependency Update + +Automated weekly update of npm packages. + +### Commits (${COMMIT_COUNT}) + +
+View commit history + +\`\`\` +${COMMITS} +\`\`\` + +
+ +--- + +Generated by [weekly-update.yml](.github/workflows/weekly-update.yml)" \ + --draft \ + --head "$BRANCH_NAME" \ + --base main + + - name: Upload Claude output + if: always() + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: claude-output-${{ github.run_id }} + path: claude-output.log + retention-days: 7 diff --git a/package.json b/package.json index 6f53b062..729178e0 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ }, "dependencies": { "@socketregistry/packageurl-js": "1.3.5", - "@socketsecurity/lib": "5.10.0", + "@socketsecurity/lib": "5.11.2", "form-data": "4.0.5" }, "devDependencies": { @@ -112,7 +112,7 @@ "node": ">=18", "pnpm": ">=10.25.0" }, - "packageManager": "pnpm@10.32.1", + "packageManager": "pnpm@10.33.0", "pnpm": { "ignoredBuiltDependencies": [ "esbuild", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 69fc6fde..91c0223a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,8 +15,8 @@ importers: specifier: 1.3.5 version: 1.3.5 '@socketsecurity/lib': - specifier: 5.10.0 - version: 5.10.0(typescript@5.9.3) + specifier: 5.11.2 + version: 5.11.2(typescript@5.9.3) form-data: specifier: 4.0.5 version: 4.0.5 @@ -919,8 +919,8 @@ packages: resolution: {integrity: sha512-Fl4GNUJ/z3IBJBGj4IsJfuRGUBCRMgX0df0mb5x5buaCPDKC+NhMhAFuxpc3viLSHV12CO2rGaNCf4fBYWI0FA==} engines: {node: '>=18', pnpm: '>=10.16.0'} - '@socketsecurity/lib@5.10.0': - resolution: {integrity: sha512-YontuC7zPxxd/Z4lhngcEf40MwjnQXEQbjzXflXNg6gB391CX4ayyGIHRIk3BxvsV7BXud9dHWcAoGv0v91wiQ==} + '@socketsecurity/lib@5.11.2': + resolution: {integrity: sha512-TS6oTeakMCbOrz73mSin/0lOhAyAr6+tlvzAvaASnMhjhrcQ9tPP816be1ZgtDRYolvQHMT+WPSmajlTHTQHjw==} engines: {node: '>=22', pnpm: '>=10.25.0'} peerDependencies: typescript: '>=5.0.0' @@ -2458,7 +2458,7 @@ snapshots: '@socketregistry/packageurl-js@1.3.5': {} - '@socketsecurity/lib@5.10.0(typescript@5.9.3)': + '@socketsecurity/lib@5.11.2(typescript@5.9.3)': optionalDependencies: typescript: 5.9.3