
Upgrade Pack Generator
- 5 installs
- 5 repo stars
- Updated August 5, 2026
- bjornmelin/dev-skills
Upgrade Pack Generator is a Claude Code skill that generates repo-local dependency-upgrade research packs with a playbook, trigger prompt, operator mode, and canonical manifest.
About
Upgrade Pack Generator creates repo-local dependency-upgrade packs before any code changes are made. Each pack contains a canonical manifest plus a playbook, trigger prompt, and operator mode rendered from it. A developer uses it when an agent needs to research an anchor package, expand related dependencies, detect repo context, and produce a reusable upgrade folder. It is monorepo-aware and produces docs and research only, deferring implementation to a later run.
- Generates repo-local upgrade packs under .agents/plans/upgrade with a playbook, trigger prompt, operator mode, and manif
- Monorepo-aware: locks an explicit owner surface (repo root or owning workspace) for the dependency family
- Docs/research only: detects repo context and confirms official docs via web.run before any implementation
Upgrade Pack Generator by the numbers
- 5 all-time installs (skills.sh)
- Ranked #1,085 of 1,435 DevOps & CI/CD skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
upgrade-pack-generator capabilities & compatibility
- Capabilities
- dependency upgrade · repo context detection · upgrade planning · manifest generation
- Works with
- vercel
- Use cases
- refactoring · research · devops
What upgrade-pack-generator says it does
The generated pack is docs/research only. Do not implement package changes while
The generator is monorepo-aware.
Detect the target repo command family in this order:
npx skills add https://github.com/bjornmelin/dev-skills --skill upgrade-pack-generatorAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 5 |
|---|---|
| repo stars | ★ 5 |
| Last updated | August 5, 2026 |
| Repository | bjornmelin/dev-skills ↗ |
What it does
Generate repo-local dependency upgrade packs with a playbook, trigger prompt, operator mode, and manifest before any implementation.
Who is it for?
Researching and planning a dependency-family upgrade into a reusable repo-local pack before implementation.
Skip if: Implementing the package changes themselves; the pack is docs/research only.
When should I use this skill?
An agent needs to research an anchor package, expand related dependencies, detect repo context, and create an upgrade folder before implementation.
What you get
A reusable repo-local upgrade pack with a manifest, playbook, and research snapshots ready for a separate implementation run.
- upgrade-pack.yaml manifest
- playbook.md
- trigger-prompt.md
By the numbers
- 12-step core workflow
- 6 built-in family lanes
Files
Upgrade Pack Generator
Generate upgrade-pack folders for dependency families in two stages:
1. Author or refine a reusable family override. 2. Instantiate a repo-specific pack from that family plus live repo context.
The generator is monorepo-aware. During enrichment it must lock an explicit owner surface for the family:
- repo root
- one owning workspace
- repo root plus related workspaces
The generated pack is docs/research only. Do not implement package changes while generating the pack.
Core Workflow
1. Read references/workflow.md. 2. Decide the mode:
- family authoring
- repo instantiation
3. Detect repo context first:
python3 scripts/detect_repo_context.py --repo-root /path/to/repo --json4. Bootstrap a manifest from the anchor package:
python3 scripts/bootstrap_manifest.py \
--repo-root /path/to/repo \
--anchor-package lucide-react \
--out /tmp/upgrade-pack.yaml5. Enrich the manifest with live repo probes and official upstream guidance:
python3 scripts/enrich_manifest.py --manifest /tmp/upgrade-pack.yaml6. Refine the enriched manifest further with live research when needed:
$repo-modernize-upgrade-audit$opensrc$opensrc-inspect$technical-writing$hard-cut
7. Validate the manifest:
python3 scripts/validate_upgrade_pack.py /tmp/upgrade-pack.yaml8. Run read-only research:
python3 scripts/research_upgrade_pack.py --manifest /tmp/upgrade-pack.yaml9. Run the mandatory web.run confirmation pass for required official docs and API-reference pages from research-bundle.json and record the results in web-research-findings.json.
10. Re-run read-only research so the snapshot reflects the confirmed official pages:
python3 scripts/research_upgrade_pack.py --manifest /tmp/upgrade-pack.yaml11. Run read-only qualification:
python3 scripts/qualify_upgrade_pack.py --manifest /tmp/upgrade-pack.yaml12. Render the pack:
python3 scripts/render_upgrade_pack.py \
--manifest /tmp/upgrade-pack.yaml \
--output-dir /path/to/repo/.agents/plans/upgrade/<topic>Output Contract
Every generated repo-local pack must contain exactly:
upgrade-pack.yamlresearch-snapshot.jsonresearch-bundle.jsonweb-research-findings.jsonqualification-snapshot.json<basename>-playbook.md<basename>-trigger-prompt.md<basename>-operator-mode.md
The manifest is the canonical source. The markdown files are rendered outputs. research-snapshot.json and qualification-snapshot.json are the canonical machine-readable evidence files for the separate research and qualify stages. research-bundle.json is the raw evidence ledger that backs the research snapshot. web-research-findings.json is the machine-readable record of web.run confirmation for the required official pages.
Rendered file roles:
<basename>-playbook.md- authoritative human handoff doc and the only writable pack file during an
implementation run
<basename>-operator-mode.md- execution delta card that points back to the playbook
<basename>-trigger-prompt.md- thin launcher for a fresh Codex session with a compact repo summary
Do not hand-maintain operator-mode.md or trigger-prompt.md; regenerate them from the manifest.
Family Overrides
Read references/manifest-schema.md before editing any override.
Family overrides live in references/family-overrides/. Use them when a dependency family recurs across repos and benefits from package-specific:
- end-state decisions
- research lanes
- migration questions
- verification proofs
- file naming and slug conventions
Current built-in family lanes:
lucide-reactnextjsexpo-easconvexturboreposhadcn-radix-ui
Keep overrides narrow. Put only family-specific information there. Let the base generator provide the common structure.
Package Manager And Framework Detection
Detect the target repo command family in this order:
1. package.json#packageManager 2. root lockfiles 3. repo docs and CI hints
The generator should write that decision into upgrade-pack.yaml and render package-manager-aware command variables into the pack. Do not force Bun into a pnpm/npm/Yarn repo.
Research Routing
Use the default research lanes in references/research-lanes.md.
Conditional routing:
- use
$bun-devonly when Bun posture is actually relevant - use framework/plugin lanes only when the target repo detects them
- use browser lanes only when the package family affects visible UI
- do not route through
$imagegenunless raster asset generation is truly part
of the package-family surface
Scripts
scripts/detect_repo_context.py- inspects package manager, lockfiles, docs/CI hints, frameworks, and package
manifests
scripts/bootstrap_manifest.py- creates a starter
upgrade-pack.yamlfrom generic defaults plus an optional
family override
scripts/enrich_manifest.py- enriches
upgrade-pack.yamlwith family-specific repo probes, current
package versions, and live official-doc snapshots
scripts/validate_upgrade_pack.py- validates the manifest contract before rendering
scripts/research_upgrade_pack.py- gathers upstream docs, API refs, release notes, examples, source evidence,
repo-usage mapping, package identity, target-version reasoning, source-map drift checks, provenance scores, and the web.run queue into research-snapshot.json plus research-bundle.json
scripts/sync_source_map.py- validates or refreshes the bundled package source-map under
references/source-maps/
scripts/qualify_upgrade_pack.py- runs family-native read-only qualification and writes
qualification-snapshot.json
scripts/render_upgrade_pack.py- renders the repo-local pack from the canonical manifest and qualification
snapshot
Examples
Bootstrap a known family override:
python3 scripts/bootstrap_manifest.py \
--repo-root /path/to/repo \
--anchor-package lucide-react \
--out /tmp/lucide-upgrade-pack.yamlRender a generic pack for a package without an override:
python3 scripts/bootstrap_manifest.py \
--repo-root /path/to/repo \
--anchor-package commander \
--out /tmp/commander-upgrade-pack.yaml
python3 scripts/enrich_manifest.py \
--manifest /tmp/commander-upgrade-pack.yaml
python3 scripts/research_upgrade_pack.py \
--manifest /tmp/commander-upgrade-pack.yaml
python3 scripts/qualify_upgrade_pack.py \
--manifest /tmp/commander-upgrade-pack.yaml
python3 scripts/render_upgrade_pack.py \
--manifest /tmp/commander-upgrade-pack.yaml \
--output-dir /path/to/repo/.agents/plans/upgrade/commanderRefresh an existing repo-local pack after refining the manifest:
python3 scripts/enrich_manifest.py \
--manifest /path/to/repo/.agents/plans/upgrade/lucide-react/upgrade-pack.yaml
python3 scripts/validate_upgrade_pack.py \
/path/to/repo/.agents/plans/upgrade/lucide-react/upgrade-pack.yaml
python3 scripts/research_upgrade_pack.py \
--manifest /path/to/repo/.agents/plans/upgrade/lucide-react/upgrade-pack.yaml
python3 scripts/qualify_upgrade_pack.py \
--manifest /path/to/repo/.agents/plans/upgrade/lucide-react/upgrade-pack.yaml
python3 scripts/render_upgrade_pack.py \
--manifest /path/to/repo/.agents/plans/upgrade/lucide-react/upgrade-pack.yaml \
--output-dir /path/to/repo/.agents/plans/upgrade/lucide-reactinterface:
display_name: "Upgrade Pack Generator"
short_description: "Generate canonical repo-local dependency upgrade packs"
default_prompt: "Use $upgrade-pack-generator to research an anchor package, detect repo context, and generate a 4-file upgrade pack under .agents/plans/upgrade/<topic>/ before implementation."
policy:
allow_implicit_invocation: false
# {{operator_title}}
## Mission
Execute the pack with minimum ambiguity and maximum evidence.
## Read This First
{{operator_read_this_first_block}}
## Non-Negotiable Guardrails
{{operator_guardrails_block}}
## Execute
{{operator_execute_block}}
## Verify
{{verification_commands_block}}
## Exit Criteria
{{operator_exit_criteria_block}}
## Required Closeout
{{operator_required_closeout_block}}
# {{playbook_title}}
## Purpose
{{purpose}}
## Pack Map
{{pack_map_block}}
## Current State And Evidence
### Family Profile
{{family_profile_block}}
### Target Surface
{{target_surface_block}}
### Research Coverage
{{research_summary_block}}
### Qualification Snapshot
{{qualification_summary_block}}
### Repo-Local Skill Overlays
{{repo_local_overlay_block}}
### Use When
{{use_when_block}}
### Source Hierarchy
Use sources in this order:
{{source_hierarchy_block}}
If a claim is unstable or version-sensitive, verify it live before acting.
### Package Manager Detection
{{package_manager_detection_block}}
### Repo Probe Snapshot
{{repo_probes_block}}
### Upstream Validation Snapshot
{{upstream_validation_block}}
### Framework Constraints
{{framework_constraints_block}}
### Supported Features
{{supported_features_block}}
### Unsupported Or Deferred Features
{{unsupported_features_block}}
### Codemod Recommendations
{{codemod_recommendations_block}}
## Decisions And End State
### Primary Goal
{{primary_goal_block}}
### Non-Goals
{{non_goals_block}}
### Persona And Operating Goals
#### Primary persona
{{primary_persona}}
#### Secondary audience
{{secondary_audience}}
#### Operating goals
{{operating_goals_block}}
### Skill, Plugin, And Tool Routing
{{skill_routing_playbook_block}}
### Decision Framework
Use this weighted scoring model for major choices.
| Criterion | Weight | What a high score means |
| --- | --- | --- |
| Solution leverage | 0.35 | Uses current package and framework guidance with minimal custom migration logic |
| Application value | 0.30 | Improves correctness, consistency, and maintainability |
| Maintenance & cognitive load | 0.25 | Deletes duplicated concepts, wrappers, and exceptions |
| Architectural adaptability | 0.10 | Leaves a cleaner path for later repo evolution |
Target final decisions at `9.0+ / 10.0`.
### Default Final Decisions
{{default_final_decisions_block}}
### Questions To Resolve Before Editing
Resolve these explicitly:
{{questions_to_resolve_block}}
### Canonical End State
{{canonical_end_state_block}}
### What To Adopt
{{what_to_adopt_block}}
### What To Avoid
{{what_to_avoid_block}}
## Execution And Verification
### Repo Intake Checklist
{{intake_checklist_block}}
### Required Research
{{required_research_block}}
### Execution Plan
{{execution_plan_block}}
### Verification Matrix
Run the repo-native equivalents of these commands.
{{verification_commands_block}}
## Live Tracker And Closeout
{{live_tracker_and_closeout_block}}
# {{trigger_title}}
{{trigger_code_block}}
match_packages:
- convex
- convex-helpers
- convex-test
- "@convex-dev/aggregate"
- "@convex-dev/migrations"
- "@convex-dev/r2"
- "@convex-dev/rate-limiter"
- "@convex-dev/resend"
- "@convex-dev/workflow"
- "@convex-dev/workpool"
family_slug: convex
family_display_name: Convex
family_type: framework
mode: upgrade+optimize
plan_basename: convex-upgrade-and-optimization
playbook_title: Convex Upgrade And Optimization Playbook
operator_title: Convex Upgrade And Optimization Operator Mode
trigger_title: Convex Upgrade And Optimization Trigger Prompt
related_packages:
- convex
- convex-helpers
- convex-test
purpose: Use this playbook to fully explore, research, plan, implement, verify, and document a Convex upgrade or current-major backend optimization wave in this repository.
use_when:
- the repository already uses Convex
- the repo needs a Convex version upgrade, backend best-practices audit, or both
- the repo needs one canonical artifact covering schema, generated code, CLI posture, and deployment-script boundaries
primary_goal:
- reach one verified canonical Convex backend end state for the owner workspace
- align schema, generated code, CLI scripts, and backend package usage with current official guidance
- remove stale backend workarounds or duplicate ownership that the current Convex surface makes unnecessary
non_goals:
- unrelated application redesign outside the Convex boundary
- treating client-only `convex` consumers as the owner surface when a dedicated backend workspace exists
- changing deploy-key or environment posture without proof from repo policy and current Convex docs
source_hierarchy:
- official Convex docs and CLI guidance
- official generated-code, schema, query, and index docs
- upstream Convex source when docs and types are insufficient
- local repo code, generated artifacts, scripts, and docs
- package manager metadata, lockfiles, audits, and release notes
default_final_decisions:
- treat the backend workspace as the owner Convex surface when it owns `convex/` and Convex scripts
- generated Convex artifacts move with schema and function changes
- support both version-upgrade and same-major optimization outcomes inside one pack
intake_checklist:
- record current `convex` and related `@convex-dev/*` versions
- record package manager and lockfile shape
- identify the owner backend workspace
- inspect the `convex/` directory and generated artifacts
- inventory deploy, codegen, and non-interactive validation scripts before editing
required_research:
Upstream Convex:
- verify current CLI guidance and generated-code expectations
- verify current schema, query, and index best practices
- verify current deploy-key and agent-mode guidance if the repo uses those flows
Upstream source inspection:
- inspect source only when public docs do not answer CLI or generated-code behavior questions
questions_to_resolve:
- which workspace truly owns the backend Convex surface in this repo
- is this run a version bump, a current-major cleanup, or both
- which deploy and codegen scripts are contractually required by repo policy
- which client-facing `convex` consumers are in or out of scope
canonical_end_state:
- the owner backend workspace follows current verified Convex guidance
- schema, generated code, and verification scripts are in sync
- backend package usage and docs reflect one canonical Convex posture
- lint, typecheck, tests, build, and audit remain green
what_to_adopt:
- current Convex CLI and generated-code flows
- current schema and index-backed query guidance
- existing non-interactive deploy-key posture when the repo already relies on it
what_to_avoid:
- stale generated artifacts or drift between schema and generated code
- outdated Convex helper patterns kept in parallel after the upgrade
- client-only ownership assumptions in monorepos with a dedicated backend workspace
execution_plan:
"Phase 1: Discovery":
- inventory the owner backend workspace, `convex/` sources, generated files, and scripts
- inventory root validation or release scripts that constrain Convex changes
- inventory current package versions and current backend best-practice signals
"Phase 2: Decisions":
- lock the owner workspace and the final version or optimize-only scope
- lock deploy-key, codegen, and agent-mode boundaries
- lock explicit defers before broad edits
"Phase 3: Code Changes":
- align package versions, schema usage, generated artifacts, and scripts to the final verified shape
- remove stale helpers or duplicate ownership that no longer earn their keep
- update docs and policy to match the final state
"Phase 4: Verification":
- run repo-native validation
- run Convex-specific codegen and release-surface checks
- write the final upgrade and optimization report with residual risks
report_heading: Upgrade And Optimization Report Requirements
report_requirements:
- current owner workspace and Convex starting state
- final decisions
- current Convex features and backend best-practice signals relevant to the repo
- stale or deprecated patterns removed or intentionally retained
- codegen, release-surface, and verification evidence
- repo-specific findings and residual risks
skill_routing_playbook:
- "Always start in the upgrade lane: `$repo-modernize-upgrade-audit`, `$opensrc`, `$opensrc-inspect`, `$technical-writing`, `$hard-cut`, and the repo-local Convex skill set."
- "Use official Convex docs first for unstable claims."
- "Use `$bun-dev` only when Bun is the repo's real package-manager or runtime lane."
- "Use `$platform-architect` when the Convex wave crosses web, mobile, and backend boundaries."
- "Do not use `$imagegen` for Convex upgrade work."
skill_routing_operator:
- "Default lane: `$repo-modernize-upgrade-audit`, `$opensrc`, `$opensrc-inspect`, `$technical-writing`, `$hard-cut`, and the repo-local Convex skill set."
- "Proof lane: official Convex docs first, source only when public guidance is insufficient."
- "Conditional lanes: `$bun-dev` for Bun repos, `$platform-architect` for full-stack monorepo coordination."
- "Do not route this migration through `$imagegen`."
operator_defaults:
- Final Convex posture follows current verified official guidance.
- One owner backend workspace per pack.
- Generated API and data-model artifacts move with schema and function changes.
- No stale backend helper or deploy-key drift unless a real boundary requires it.
operator_fast_intake:
- record current `convex` and `@convex-dev/*` versions
- record package manager
- inspect the owner `convex/` directory and generated artifacts
- inventory codegen, deploy, and release scripts
- inventory root validation commands that constrain backend changes
operator_research:
- verify current Convex CLI, generated-code, and index guidance
- verify deploy-key and agent-mode guidance when the repo uses those flows
- inspect source only when docs or CLI help are insufficient
operator_execute:
- align Convex package versions, schema usage, generated artifacts, and scripts to the final verified posture
- remove stale backend helpers or duplicate ownership that no longer earn their keep
- update docs and policy to match the final state
operator_exit_criteria:
- the owner backend workspace follows the final verified Convex posture
- generated artifacts and verification scripts are in sync
- stale backend helper drift is gone or explicitly deferred
- verification is green
trigger_mission: Act as an architect-level modernization engineer performing a verification-first Convex upgrade and backend optimization wave in this repository.
trigger_goals:
- reach one canonical final Convex end state for the owner backend workspace
- support both version-upgrade and same-major optimization work
- remove stale helpers, generated-code drift, and unnecessary backend duplication where justified
- keep the diff reviewable and the final state simpler than the initial state
trigger_required_research:
- inspect manifests, lockfiles, Convex source, generated artifacts, scripts, and AGENTS/docs first
- verify current official Convex guidance before editing
- use official docs, upstream source, and repo-native commands
- build a touched-files map before broad edits
trigger_required_decisions:
- confirm which workspace owns the backend Convex surface
- decide whether this run is upgrade-only, optimize-only, or both
- decide which deploy-key, codegen, and agent-mode flows are in or out of scope
- decide which stale helper or wrapper code can be deleted
trigger_required_outcomes:
- standardize on the verified final Convex usage, schema, and script shape
- remove stale backend patterns and unnecessary related dependencies
- update repo policy and docs to match the final convention
trigger_required_deliverables:
- findings matrix
- decision log
- affected-files map
- migration checklist
- exact verification commands
- upgrade and optimization report
- residual risks or explicit defer reasons
trigger_verification_expectation:
- run lint, typecheck, tests, audit, and the repo's codegen or release-surface checks
- prove removed patterns are gone with grep or equivalent checks
match_packages:
- expo
- expo-router
- expo-updates
- expo-dev-client
- eas-cli
family_slug: expo-eas
family_display_name: Expo And EAS
family_type: framework
mode: upgrade+optimize
plan_basename: expo-eas-upgrade-and-optimization
playbook_title: Expo And EAS Upgrade And Optimization Playbook
operator_title: Expo And EAS Upgrade And Optimization Operator Mode
trigger_title: Expo And EAS Upgrade And Optimization Trigger Prompt
related_packages:
- expo
- expo-router
- expo-updates
- expo-dev-client
- react-native
- react-native-web
- react
- react-dom
purpose: Use this playbook to fully explore, research, plan, implement, verify, and document an Expo SDK plus EAS upgrade or current-major optimization wave in this repository.
use_when:
- the repository already uses Expo or Expo Router
- the repo needs an Expo SDK upgrade, Expo package alignment audit, or EAS workflow cleanup
- the repo needs one canonical artifact covering mobile app ownership, app config, build profiles, and validation posture
primary_goal:
- reach one verified canonical Expo SDK and EAS end state for the target app workspace
- keep Expo, Expo Router, React Native, and EAS configuration aligned to current official guidance
- adopt current Expo-native tooling and remove stale mobile build workarounds where justified
non_goals:
- unrelated mobile product redesign
- splitting the Expo SDK wave from EAS configuration when the repo treats them as one delivery surface
- introducing bare-workflow-only steps into a CNG-first workspace without proof
source_hierarchy:
- official Expo docs and SDK upgrade guides
- official EAS docs and build-profile guidance
- official React Native and Expo Router docs when they materially affect the upgrade
- local repo code, configs, workflows, and docs
- package manager metadata, lockfiles, audits, and release notes
default_final_decisions:
- treat Expo SDK alignment as a framework-family concern, not a single-package bump
- support both version-upgrade and same-major optimization outcomes inside one pack
- keep scope centered on the owner mobile workspace plus root validation and workflow boundaries
intake_checklist:
- record current `expo`, `expo-router`, `react-native`, and `expo-updates` versions
- record package manager and lockfile shape
- inspect `app.json` or `app.config.*`
- inspect `eas.json`
- identify whether the workspace is CNG-first or keeps native `ios/` and `android/` directories
- inventory Expo, EAS, and native workflow scripts before editing
required_research:
Upstream Expo:
- verify the current Expo SDK upgrade walkthrough
- verify current Expo monorepo guidance and package alignment rules
- verify `expo-doctor`, `expo install --fix`, and New Architecture guidance
Upstream EAS:
- verify current `eas.json` build-profile guidance
- verify EAS environment and workflow guidance that materially affects CI or release flows
Upstream source inspection:
- inspect source or CLI behavior only when public docs do not answer config or package-alignment questions
questions_to_resolve:
- is this run primarily an SDK jump, a same-major cleanup, or both
- which mobile workspace owns the Expo app surface in this repo
- what root validation or CI commands must remain coupled to the mobile app upgrade
- which native directories or EAS workflows are intentionally in or out of scope
canonical_end_state:
- the owner app workspace follows current Expo SDK and EAS guidance
- Expo family packages are aligned with the supported SDK surface
- app config, EAS config, and validation scripts match the final mobile posture
- docs and repo policy describe the final Expo and EAS convention
what_to_adopt:
- current Expo SDK upgrade flows
- "`expo-doctor` and Expo package-alignment checks"
- current Expo Router and EAS build-profile conventions where they fit the repo posture
what_to_avoid:
- drifting Expo family versions outside the official support matrix
- stale mobile workflow workarounds left in parallel after the upgrade
- CNG and bare-workflow instructions mixed together without a clear owner posture
execution_plan:
"Phase 1: Discovery":
- inventory the owner Expo workspace, app config, and EAS build profiles
- inventory root validation and workflow scripts that constrain the mobile app
- inventory current Expo family package versions and local overrides
"Phase 2: Decisions":
- lock the owner workspace and the final SDK target or optimize-only scope
- lock the EAS workflow boundary and explicit native-directory policy
- lock any package or config defers before broad edits
"Phase 3: Code Changes":
- align Expo family packages, app config, and workflow scripts to the final verified shape
- remove stale mobile build workarounds or exclusions that no longer earn their keep
- update docs and policy to match the final state
"Phase 4: Verification":
- run repo-native validation
- run Expo-specific doctor and workflow checks
- write the final upgrade and optimization report with residual risks
report_heading: Upgrade And Optimization Report Requirements
report_requirements:
- current owner workspace, SDK, and EAS starting state
- final decisions
- current Expo and EAS features relevant to the repo
- stale or deprecated patterns removed or intentionally retained
- workflow and validation evidence
- repo-specific findings and residual risks
skill_routing_playbook:
- "Always start in the upgrade lane: `$repo-modernize-upgrade-audit`, `$opensrc`, `$opensrc-inspect`, `$technical-writing`, `$hard-cut`, `$expo`, and `$expo:upgrading-expo`."
- "Use official Expo and EAS docs first for unstable claims."
- "Use `$bun-dev` only when Bun is the repo's real package-manager or runtime lane."
- "Use Turborepo or platform-architecture lanes only when the repo is a monorepo and those boundaries materially affect the mobile app."
- "Do not use `$imagegen` for Expo or EAS upgrade work."
skill_routing_operator:
- "Default lane: `$repo-modernize-upgrade-audit`, `$opensrc`, `$opensrc-inspect`, `$technical-writing`, `$hard-cut`, `$expo`, `$expo:upgrading-expo`."
- "Proof lane: official Expo and EAS docs first, source only when public guidance is insufficient."
- "Conditional lanes: `$bun-dev` for Bun repos, `$turborepo` for monorepo task-graph work, `$platform-architect` when the app upgrade crosses web/native/backend boundaries."
- "Do not route this migration through `$imagegen`."
operator_defaults:
- Final Expo SDK and EAS posture follows current verified official guidance.
- One owner mobile workspace per pack.
- No stale mobile workflow workarounds unless a real external boundary requires them.
- SDK alignment, app config, and EAS config move together.
operator_fast_intake:
- record current `expo`, `expo-router`, and `react-native` versions
- record package manager
- inspect `app.json` or `app.config.*`
- inspect `eas.json`
- identify whether native `ios/` or `android/` directories exist
- inventory Expo, doctor, and EAS workflow scripts
operator_research:
- verify the current Expo SDK upgrade walkthrough
- verify current monorepo and EAS build-profile guidance
- inspect source only when docs or CLI help are insufficient
operator_execute:
- align Expo family package versions, app config, and EAS config to the final verified posture
- remove stale exclusions, mobile workflow workarounds, and redundant package drift
- update docs and policy to match the final state
operator_exit_criteria:
- the owner mobile workspace follows the final verified Expo SDK posture
- EAS config and validation scripts match the final convention
- stale mobile workflow workarounds are gone or explicitly deferred
- verification is green
trigger_mission: Act as an architect-level modernization engineer performing a verification-first Expo SDK and EAS upgrade plus optimization wave in this repository.
trigger_goals:
- reach one canonical final Expo SDK and EAS end state for the owner workspace
- support both SDK-upgrade and same-major optimization work
- remove stale mobile workflow workarounds, config drift, and unnecessary package churn where justified
- keep the diff reviewable and the final state simpler than the initial state
trigger_required_research:
- inspect manifests, lockfiles, Expo app config, EAS config, AGENTS/docs, and mobile scripts first
- verify current official Expo and EAS guidance before editing
- use official docs, upstream source, and repo-native commands
- build a touched-files map before broad edits
trigger_required_decisions:
- confirm whether this run is SDK-upgrade-only, optimize-only, or both
- decide the canonical final Expo and EAS posture for the owner workspace
- decide which related packages and workflows are in or out of scope
- decide which stale exclusions or config can be deleted
trigger_required_outcomes:
- standardize on the verified final Expo SDK and EAS config shape
- remove stale workflow patterns and unnecessary related dependencies
- update repo policy and docs to match the final convention
trigger_required_deliverables:
- findings matrix
- decision log
- affected-files map
- migration checklist
- exact verification commands
- upgrade and optimization report
- residual risks or explicit defer reasons
trigger_verification_expectation:
- run lint, typecheck, tests, audit, and the mobile doctor or workflow checks the repo actually uses
- prove removed patterns are gone with grep or equivalent checks
match_packages:
- lucide-react
family_slug: lucide-react
plan_basename: lucide-react-v1-upgrade
playbook_title: Lucide React v1 Upgrade Playbook
operator_title: Lucide React v1 Upgrade Operator Mode
trigger_title: Lucide React v1 Upgrade Trigger Prompt
related_packages:
- lucide-react
qualification_plan:
doc_urls:
lucide home: https://lucide.dev/
lucide icons: https://lucide.dev/icons/
github releases: https://github.com/lucide-icons/lucide/releases
source_specs:
- lucide-icons/lucide
research_plan:
target_version: Lucide React v1
compatibility_rationale: Keep the repo on the latest compatible Lucide React v1 surface and adopt current named-import and type usage guidance.
release_range: current repo version -> Lucide React v1
official_docs:
lucide home: https://lucide.dev/
api_reference:
icons gallery: https://lucide.dev/icons/
package source: https://github.com/lucide-icons/lucide/tree/main/packages/lucide-react
migration_guides:
v1 docs: https://lucide.dev/
release_history:
github releases: https://github.com/lucide-icons/lucide/releases
examples_cookbooks:
icons gallery: https://lucide.dev/icons/
brand logo statement: https://lucide.dev/brand-logo-statement
source_specs:
- lucide-icons/lucide
repo_usage_queries:
- label: Lucide manifest declarations
cwd: .
command: rg -n '"lucide-react"|@radix-ui/react-icons|react-icons' .
- label: Lucide import usage
cwd: .
command: rg -n 'lucide-react|dist/esm/icons|DynamicIcon|LucideProvider|LucideIcon' .
purpose: Use this playbook to fully explore, research, plan, implement, verify, and document a `lucide-react` v1 upgrade in this repository.
use_when:
- the repository already uses `lucide-react` and needs a v1-era cleanup or migration
- the repo still imports icons from `lucide-react/dist/esm/icons/*`
- the repo has local typing shims for deep Lucide imports
- the repo has extra icon dependencies that may now be removable
primary_goal:
- standardize on named imports from `lucide-react`
- remove deep Lucide import paths and any Lucide deep-path typing shim
- remove unnecessary secondary icon dependencies for a tiny brand-icon footprint
- leave current docs, policies, and verification evidence
non_goals:
- broad design-system modernization beyond the icon surface
- introducing `DynamicIcon` unless runtime data actually requires it
- adopting `LucideProvider` unless it clearly deletes meaningful code
- folding unrelated shadcn or Radix migrations into the same wave
source_hierarchy:
- official Lucide docs
- official Next.js docs
- upstream Lucide source code
- local repo code and tests
- package manager metadata, audits, and lockfiles
default_final_decisions:
- "canonical import style: `import { IconName } from \"lucide-react\"`"
- rely on Next.js built-in import optimization when the repo version supports it
- prefer local SVG ownership over a separate icon package for a tiny brand-icon footprint
- use one hard-cut migration wave, not staged coexistence
- keep scope focused on the Lucide/icon surface
intake_checklist:
- confirm framework and version, especially Next.js version
- record current `lucide-react` version
- record package manager and lockfile shape
- search for deep Lucide imports
- search for local typing shims related to Lucide deep imports
- search for dynamic icon usage
- search for custom icon wrappers or indirection layers
- search for other icon dependencies such as brand/icon helper packages
- search repo docs, AGENTS, contributing guides, and lint rules for icon import policy
- build a touched-files map before editing
required_research:
Upstream Lucide:
- verify current React usage guidance
- verify migration guidance to v1
- verify current exported types such as `LucideProps`, `LucideIcon`, and `IconNode`
- verify current guidance for `DynamicIcon`, `LucideProvider`, accessibility defaults, and brand icon support or removal
Upstream Next.js:
- verify whether `lucide-react` is optimized by default in the repo's Next.js version
- verify whether explicit `optimizePackageImports` config is needed or redundant
Upstream source inspection:
- inspect Lucide source when public docs or typings do not answer export shape, per-icon typing behavior, dynamic helpers, or provider/context behavior
questions_to_resolve:
- is barrel import from `lucide-react` safe and preferred in this repo's framework version
- does the repo have any runtime icon-name boundary that actually justifies `DynamicIcon`
- is any local icon wrapper still earning its keep
- are brand icons currently covered by Lucide, another package, or local SVGs
- is there any repo policy that must be updated together with code changes
canonical_end_state:
- all Lucide imports come from `lucide-react`
- no file imports `lucide-react/dist/esm/icons/*`
- any Lucide deep-path typing shim is deleted
- icon component or data typing uses official Lucide types where needed
- tiny one-off brand icon dependencies are removed when local SVG ownership is enough
- docs and repo policy describe the final import shape
- lint, typecheck, tests, build, and audit remain green
what_to_adopt:
- named imports from `lucide-react`
- "`LucideIcon` for icon component fields and props"
- local SVGs for non-Lucid brand marks
- existing local styling patterns unless a simpler package-native pattern is clearly better
what_to_avoid:
- "`lucide-react/dist/esm/icons/*`"
- mixed deep-import and barrel-import conventions
- local typing shims kept only to support a stale import policy
- "`DynamicIcon` for static UI"
- "`LucideProvider` unless it deletes enough local styling glue to justify itself"
- keeping a second icon package only for a handful of brand marks
execution_plan:
"Phase 1: Discovery":
- inventory all Lucide imports
- inventory all non-Lucid icon dependencies
- inventory all docs and policy references to icon import conventions
- record brand-icon usage and ownership
- record any dynamic icon usage or wrappers
"Phase 2: Decisions":
- lock the canonical import style
- lock the brand-icon strategy
- lock the rollout style
- lock whether any adjacent icon work is deferred
"Phase 3: Code Changes":
- convert deep Lucide imports to named imports from `lucide-react`
- tighten icon typing to official Lucide types where useful
- delete the Lucide deep-path typing shim
- replace secondary brand-icon dependency usage with local SVG ownership when justified
- remove obsolete icon dependencies from manifests and lockfiles
"Phase 4: Policy And Docs":
- update AGENTS or repo guidance if it still describes the old import shape
- update architecture or frontend docs if they mention stale icon policy
- write or update the upgrade report with current guidance, final decisions, verification evidence, and residual risks
"Phase 5: Verification":
- lint
- typecheck
- tests
- build
- audit
- grep-based proof that old import paths and removed icon dependencies are gone
verification_commands:
- "# inventory"
- "rg -n 'lucide-react|dist/esm/icons|react-icons|@radix-ui/react-icons' ."
- ""
- "# verification"
- "${PM_RUN} lint"
- "${PM_RUN} type-check"
- "${PM_TEST}"
- "${PM_RUN} build"
- "${PM_AUDIT}"
- ""
- "# proof of hard cut"
- "rg -n 'lucide-react/dist/esm/icons/' ."
- "rg -n '@radix-ui/react-icons' ."
report_requirements:
- current starting state
- final decisions
- features and capabilities available in current Lucide React
- old patterns removed or discouraged
- deprecations and practical replacements
- repo-specific findings, verification evidence, and residual risks
skill_routing_playbook:
- "Always start in the upgrade lane: `$repo-modernize-upgrade-audit`, `$opensrc`, `$opensrc-inspect`, `$technical-writing`, and `$hard-cut`."
- "Use official-doc lanes first for unstable claims: current Lucide docs, Next.js docs, changelogs, and upstream source when needed."
- "Use `$bun-dev` only when Bun is the repo's real runtime or package-manager lane."
- "Use `$vitest` or `$vitest-dev` when tests, coverage, or Vitest config need to move."
- "Use `$playwright-interactive`, `$next-browser`, or `$vercel:agent-browser` only when user-visible browser verification matters."
- "Use Vercel and Build Web Apps plugin lanes only when the target repo actually needs them."
- "Do not use `$imagegen` for Lucide or vector-icon migration unless raster asset generation is explicitly part of the surface."
operator_defaults:
- "Final import style: `import { IconName } from \"lucide-react\"`."
- no deep imports
- no Lucide deep-path typing shim
- no extra icon package for a tiny brand-logo footprint unless clearly needed
- no `DynamicIcon` unless runtime data forces it
operator_fast_intake:
- record Next.js version
- record `lucide-react` version
- record package manager
- "grep for: `lucide-react/dist/esm/icons`, `lucide-react`, `@radix-ui/react-icons`, `react-icons`"
- find any local Lucide typing shim
- find any AGENTS/docs that describe icon import policy
operator_research:
- verify the Lucide React guide and migration guide
- verify Next.js package import optimization guidance
- inspect Lucide source only if docs and types are insufficient
operator_execute:
- convert all deep Lucide imports to named imports from `lucide-react`
- replace loose icon typing with `LucideIcon` where useful
- delete the deep-path shim
- localize brand icons if a second dependency is only covering a few marks
- remove obsolete icon dependencies from manifest and lockfile
- update docs/policy to match the final import shape
operator_exit_criteria:
- every Lucide import uses `from "lucide-react"`
- no deep import path remains
- any Lucide shim is deleted
- removed icon dependencies are actually gone
- docs/policy match the final state
- verification is green
skill_routing_operator:
- "Default lane: `$repo-modernize-upgrade-audit`, `$opensrc`, `$opensrc-inspect`, `$technical-writing`, `$hard-cut`."
- "Proof lane: current official docs, changelogs, and upstream source when needed."
- "Test lane: `$vitest` or `$vitest-dev` when tests or coverage config move."
- "Browser lane: `$playwright-interactive`, `$next-browser`, or `$vercel:agent-browser` only for visible UI verification."
- "Conditional lanes: `$bun-dev` for Bun repos, framework/plugin lanes only when actually relevant."
- "Do not route this migration through `$imagegen`."
trigger_mission: Act as an architect-level modernization engineer performing a verification-first Lucide React v1 migration in this repository.
trigger_goals:
- "reach one canonical Lucide end state: named imports from `lucide-react`"
- delete deep import paths, local shims, stale docs, and unnecessary icon deps
- keep the diff reviewable and the final state simpler than the initial state
trigger_required_research:
- inspect package manifests, lockfiles, Next config, AGENTS/docs, and all icon usage first
- verify current Lucide and Next.js guidance before editing
- use official docs, upstream source, and repo-native commands
- build a touched-files map before broad edits
trigger_required_decisions:
- confirm whether named imports from `lucide-react` are the canonical final shape in this repo
- decide whether any runtime icon-name use really justifies `DynamicIcon`
- decide how brand icons should be owned
- keep the migration Lucide-focused unless explicit evidence justifies more
trigger_required_outcomes:
- standardize on `import { IconName } from "lucide-react"`
- remove deep imports from `lucide-react/dist/esm/icons/*`
- remove any Lucide deep-path typing shim if no longer needed
- replace tiny one-off brand icon dependencies with local SVG ownership when justified
- update repo policy/docs to match the final import convention
trigger_required_deliverables:
- findings matrix
- decision log
- affected-files map
- migration checklist
- exact verification commands
- upgrade report
- residual risks or explicit defer reasons
trigger_verification_expectation:
- run lint, typecheck, tests, build, and audit
- prove removed import paths and dependencies are gone with grep
match_packages:
- next
- nextjs
family_slug: nextjs
family_display_name: Next.js
family_type: framework
mode: upgrade+optimize
plan_basename: nextjs-v16-upgrade-and-optimization
playbook_title: Next.js v16 Upgrade And Optimization Playbook
operator_title: Next.js v16 Upgrade And Optimization Operator Mode
trigger_title: Next.js v16 Upgrade And Optimization Trigger Prompt
related_packages:
- next
- react
- react-dom
- "@types/react"
- "@types/react-dom"
- "@next/codemod"
purpose: Use this playbook to fully explore, research, plan, implement, verify, and document a Next.js upgrade or current-major optimization wave in this repository.
use_when:
- the repository already uses `next`
- the repo needs a version upgrade, a current-major optimization audit, or both
- the repo needs one canonical artifact covering routing, rendering, config, deployment boundaries, and framework-native adoption work
primary_goal:
- reach one verified canonical Next.js end state for the target repo
- support both version-upgrade and current-major optimization work
- adopt current framework-native APIs, config, and repo posture where they materially simplify the app
- leave docs, verification evidence, and a reviewable execution path
non_goals:
- unrelated application redesign beyond the Next.js boundary
- introducing server-runtime-only features into a repo that intentionally stays static-export-only
- folding unrelated package waves into scope without direct framework evidence
source_hierarchy:
- official Next.js docs and version-specific upgrade guides
- official Vercel Next.js guidance when it clarifies platform behavior
- upstream Next.js source code when docs and types are insufficient
- local repo code, tests, configs, and docs
- package manager metadata, lockfiles, audits, and release notes
default_final_decisions:
- treat Next.js as a framework boundary, not a plain npm package
- default to one canonical framework posture per repo
- support both upgrade and optimize outcomes inside the same pack
- keep scope centered on the Next.js family and directly related runtime or tooling surfaces
intake_checklist:
- record current `next`, `react`, and `react-dom` versions
- record package manager and lockfile shape
- inspect `next.config.*`
- identify App Router vs Pages Router posture
- identify static-export vs server-runtime posture
- inventory `next/*` imports and route surfaces
- inventory docs and local policy that describe the framework boundary
- build a touched-files map before editing
required_research:
Upstream Next.js:
- verify the current version-specific upgrade guide
- verify current breaking changes, stable APIs, and codemods for the repo's major version
- verify current routing, caching, request API, and config guidance
Upstream Vercel and deployment posture:
- verify platform guidance that materially affects Next.js runtime, static export, or cache behavior
- verify whether the repo's deployment posture rules out certain framework features
Upstream source inspection:
- inspect Next.js source only when public docs, types, or codemods do not answer behavior or migration risk questions
questions_to_resolve:
- is this run primarily a version jump, a same-major optimization audit, or both
- what is the canonical final Next.js posture in this repo
- which runtime or config features are intentionally forbidden by repo posture
- which adjacent packages are truly part of this framework wave
- which docs or policy files must move with the code change
canonical_end_state:
- all live Next.js usage follows current verified framework guidance
- the repo's Next.js posture is explicit, consistent, and compatible with deployment constraints
- obsolete wrappers, stale APIs, and redundant framework workarounds are removed when no real boundary requires them
- docs and repo policy describe the final Next.js convention
- lint, typecheck, tests, build, and audit remain green
what_to_adopt:
- current version-appropriate Next.js APIs and config
- framework-native routing, metadata, image, navigation, cache, and typegen patterns where they fit the repo posture
- current codemods when they reduce migration risk and review cost
what_to_avoid:
- stale Next.js APIs, deprecated config names, and transitional compatibility code
- mixed framework conventions left in parallel
- server-runtime-only features in repos that intentionally remain static exports
execution_plan:
"Phase 1: Discovery":
- inventory Next.js config, routes, imports, and current framework posture
- inventory related packages and framework-adjacent tooling
- inventory docs and policy references that describe Next.js constraints or conventions
"Phase 2: Decisions":
- lock the canonical final Next.js posture
- lock the upgrade vs optimize scope
- lock the related-package boundary and explicit defers
"Phase 3: Code Changes":
- apply the final version-appropriate Next.js usage shape
- remove stale config, wrappers, and framework workarounds that no longer earn their keep
- update docs and repo policy to match the final state
"Phase 4: Verification":
- run repo-native validation
- prove removed patterns are gone
- write the final upgrade and optimization report with residual risks
verification_commands:
- "# inventory"
- "node -p \"require('./package.json').dependencies?.next || require('./package.json').devDependencies?.next || ''\""
- "rg --files -g 'next.config.*' -g 'middleware.*' -g 'proxy.*' -g 'app/**' -g 'src/app/**' ."
- "rg -n \"from ['\\\"]next/(font|image|link|navigation|server|cache)\" src app next.config.* package.json docs"
- "rg -n \"\\bcookies\\(|\\bheaders\\(|\\bdraftMode\\(\" src app next.config.* package.json docs"
- "rg -n \"\\brevalidateTag\\(|\\bupdateTag\\(\" src app next.config.* package.json docs"
- "rg -n \"\\bcacheLife\\(|\\bcacheTag\\(|\\bunstable_cache(Life|Tag)\\(\" src app next.config.* package.json docs"
- "rg -n \"\\buseSearchParams\\(|generateMetadata|generateStaticParams\" src app next.config.* package.json docs"
- "rg -n \"dynamicParams|proxy\\(|middleware\\(\" src app next.config.* package.json docs"
- ""
- "# verification"
- "${PM_RUN} lint"
- "${PM_RUN} type-check"
- "${PM_TEST}"
- "${PM_RUN} build"
- "${PM_AUDIT}"
report_requirements:
- current starting state
- final decisions
- current Next.js features and capabilities relevant to the repo
- stale or deprecated patterns removed or intentionally retained
- codemods considered or used
- repo-specific findings, verification evidence, and residual risks
skill_routing_playbook:
- "Always start in the framework upgrade lane: `$repo-modernize-upgrade-audit`, `$opensrc`, `$opensrc-inspect`, `$technical-writing`, `$hard-cut`, `$vercel`, and `$vercel:nextjs`."
- "Use official Next.js docs first for unstable claims, then Vercel guidance when platform behavior matters."
- "Use `$bun-dev` only when Bun is the repo's real runtime or package-manager lane."
- "Use test lanes such as `$vitest` or `$vitest-dev` when tests or coverage config move."
- "Use browser lanes only when the framework wave affects visible behavior."
- "Do not use `$imagegen` for Next.js framework migration work."
operator_defaults:
- Final Next.js posture follows current verified official guidance.
- One canonical framework posture per repo.
- No stale compatibility shims unless a real external boundary requires them.
- Static export constraints remain binding when the repo enforces them.
operator_fast_intake:
- record current `next`, `react`, and `react-dom` versions
- record package manager
- inspect `next.config.*`
- identify App Router vs Pages Router posture
- identify static-export vs server-runtime posture
- grep `next/*` imports and request-time API usage
operator_research:
- verify the current version-specific Next.js guide and codemods
- verify Vercel Next.js guidance when deployment or cache posture matters
- inspect source only when docs, types, or codemods are insufficient
operator_execute:
- migrate the repo to the canonical final Next.js posture
- remove stale config, deprecated APIs, and redundant framework workarounds
- update docs and policy to match the final state
operator_exit_criteria:
- live Next.js usage follows the final verified posture
- deprecated config or framework patterns are gone or explicitly deferred
- docs and policy match the final state
- verification is green
skill_routing_operator:
- "Default lane: `$repo-modernize-upgrade-audit`, `$opensrc`, `$opensrc-inspect`, `$technical-writing`, `$hard-cut`, `$vercel`, `$vercel:nextjs`."
- "Proof lane: official Next.js docs first, Vercel docs when platform behavior matters, upstream source only when necessary."
- "Test lane: `$vitest` or `$vitest-dev` when tests or coverage config move."
- "Conditional lanes: `$bun-dev` for Bun repos, browser verification only when the framework wave changes visible behavior."
- "Do not route this migration through `$imagegen`."
trigger_mission: Act as an architect-level modernization engineer performing a verification-first Next.js upgrade and optimization wave in this repository.
trigger_goals:
- reach one canonical final Next.js end state for this repo
- support both version-upgrade and same-major optimization work
- remove stale config, docs, and unnecessary framework workarounds where justified
- keep the diff reviewable and the final state simpler than the initial state
trigger_required_research:
- inspect manifests, lockfiles, Next config, route surfaces, AGENTS/docs, and all `next/*` usage first
- verify current official Next.js guidance before editing
- use official docs, upstream source, and repo-native commands
- build a touched-files map before broad edits
trigger_required_decisions:
- confirm whether this run is upgrade-only, optimize-only, or both
- decide the canonical final Next.js posture for this repo
- decide which related packages are in or out of scope
- decide which stale wrappers or config can be deleted
trigger_required_outcomes:
- standardize on the verified final Next.js usage and config shape
- remove stale framework patterns and unnecessary related dependencies
- update repo policy and docs to match the final convention
trigger_required_deliverables:
- findings matrix
- decision log
- affected-files map
- migration checklist
- exact verification commands
- upgrade and optimization report
- residual risks or explicit defer reasons
trigger_verification_expectation:
- run lint, typecheck, tests, build, and audit
- prove removed patterns are gone with grep or equivalent checks
match_packages:
- shadcn-ui
- shadcn
- radix-ui
- "@radix-ui/react-dialog"
- "@radix-ui/react-slot"
family_slug: shadcn
plan_basename: shadcn-radix-ui-unification
playbook_title: shadcn Radix UI Unification Playbook
operator_title: shadcn Radix UI Unification Operator Mode
trigger_title: shadcn Radix UI Unification Trigger Prompt
anchor_package: radix-ui
related_packages:
- radix-ui
- "@radix-ui/react-icons"
qualification_plan:
doc_urls:
shadcn cli docs: https://ui.shadcn.com/docs/cli
shadcn radix migration changelog: https://ui.shadcn.com/docs/changelog/2026-02-radix-ui
radix introduction: https://www.radix-ui.com/primitives/docs/overview/introduction
radix releases: https://www.radix-ui.com/primitives/docs/overview/releases
source_specs:
- shadcn-ui/ui
- radix-ui/primitives
research_plan:
target_version: shadcn Radix unified package lane
compatibility_rationale: Keep shadcn new-york repos on the current unified radix-ui package path, verify current CLI migration behavior, and adopt the latest compatible Radix guidance without mixing Base UI scope into the same wave.
release_range: current repo primitive package set -> current unified radix-ui package lane
official_docs:
shadcn cli docs: https://ui.shadcn.com/docs/cli
shadcn installation: https://ui.shadcn.com/docs/installation
radix introduction: https://www.radix-ui.com/primitives/docs/overview/introduction
api_reference:
shadcn dialog docs: https://ui.shadcn.com/docs/components/dialog
radix getting started: https://www.radix-ui.com/primitives/docs/overview/getting-started
radix accessibility: https://www.radix-ui.com/primitives/docs/overview/accessibility
migration_guides:
shadcn radix migration changelog: https://ui.shadcn.com/docs/changelog/2026-02-radix-ui
shadcn radix migration launch: https://ui.shadcn.com/docs/changelog/2025-06-radix-ui
shadcn migrate command docs: https://ui.shadcn.com/docs/cli
release_history:
shadcn radix migration changelog: https://ui.shadcn.com/docs/changelog/2026-02-radix-ui
radix releases overview: https://www.radix-ui.com/primitives/docs/overview/releases
examples_cookbooks:
shadcn dialog examples: https://ui.shadcn.com/docs/components/dialog
shadcn sidebar examples: https://ui.shadcn.com/docs/components/radix/sidebar
source_specs:
- shadcn-ui/ui
- radix-ui/primitives
repo_usage_queries:
- label: shadcn config and manifests
cwd: .
command: rg -n '"radix-ui"|@radix-ui/react-|@radix-ui/react-icons|components\\.json|shadcn' .
- label: shadcn primitive imports double quotes
cwd: .
command: "rg -n \"from \\\"@radix-ui/react-|from \\\"radix-ui\\\"\" ."
- label: shadcn primitive imports single quotes
cwd: .
command: "rg -n \"from '@radix-ui/react-|from 'radix-ui'\" ."
- label: shadcn owned component surface
cwd: .
command: rg -n 'components/ui|ui/' .
purpose: Use this playbook to fully explore, research, plan, implement, verify, and document a migration from many individual `@radix-ui/react-*` packages to the unified `radix-ui` package in a shadcn `new-york` Next.js codebase.
use_when:
- the repository uses shadcn `new-york`
- the repo owns local shadcn component source in-repo
- the repo still imports primitives from multiple `@radix-ui/react-*` packages
- the repo wants one canonical primitive import model
- the repo needs a reusable migration report for current and future repos
primary_goal:
- "`radix-ui` as the unified primitive dependency"
- one import convention for local shadcn-owned primitives
- no mixed primitive package ownership in component source
- current docs, policies, and verification evidence
non_goals:
- converting the repo to Base UI
- redesigning the visual system
- changing shadcn style family without explicit approval
- "treating `@radix-ui/react-icons` as automatically covered by the primitive migration"
- folding Lucide or unrelated dependency waves into the same change by default
source_hierarchy:
- official shadcn docs and CLI help
- official Radix docs
- upstream shadcn source and migration implementation
- local repo code and tests
- package manager metadata, audits, and lockfiles
default_final_decisions:
- "canonical primitive import style: `import { Dialog as DialogPrimitive } from \"radix-ui\"`"
- use `shadcn migrate radix` as the initial rewrite path
- remove obsolete `@radix-ui/react-*` packages only after grep proves they are unused
- use one hard-cut wave, not staged coexistence
- stay on shadcn `new-york` plus Radix; do not silently expand into Base UI
intake_checklist:
- confirm the repo actually uses shadcn
- confirm `components.json` exists and record `style`, `base`, `rsc`, aliases, and `iconLibrary`
- run `shadcn info --json` and record framework, version, base, resolved paths, and installed components
- search for `@radix-ui/react-*` usage
- search for existing `radix-ui` usage
- search for `@radix-ui/react-icons` usage
- identify all locally owned shadcn components and all direct primitive import sites
- search repo docs and AGENTS for primitive import guidance
- build a touched-files map before editing
required_research:
Upstream shadcn:
- "verify current CLI help: `shadcn --help`, `shadcn migrate --list`, `shadcn migrate radix --help`"
- verify current migration/changelog guidance for `radix-ui`
- verify whether the target style/base is eligible for unified `radix-ui`
Upstream Radix:
- verify current installation guidance for `radix-ui`
- verify tree-shaking or bundling guidance where documented
- verify compatibility expectations for importing multiple primitives from the unified package
Upstream source inspection:
- inspect the shadcn migrator implementation when docs are incomplete
- confirm what the migrator does and does not do for import rewrites, dependency addition, old package cleanup, `Slot`, and `@radix-ui/react-icons`
questions_to_resolve:
- is the repo on `new-york` plus Radix and therefore a good candidate for this migration
- does the repo own its shadcn component source, or is it generated from elsewhere
- are there any direct primitive imports outside the standard UI component directory
- is `@radix-ui/react-icons` still in use, and should it remain explicitly outside this wave
- is a Base UI migration being considered separately, and if so, should it stay deferred
canonical_end_state:
- local shadcn-owned primitives import from `radix-ui`
- local component source no longer imports individual `@radix-ui/react-*` packages for migrated primitives
- "`package.json` carries `radix-ui` and no obsolete individual primitive packages"
- the repo does not misrepresent `@radix-ui/react-icons` as covered by the migration unless it was explicitly handled too
- docs and repo policy describe the final primitive import shape
- lint, typecheck, tests, build, and audit remain green
what_to_adopt:
- "`shadcn migrate radix` as the first migration step"
- named imports from `radix-ui`
- manual post-migration grep and manifest cleanup
- focused verification on dialog, sheet, dropdown, select, popover, toast, navigation menu, toggle, and toggle group behavior
what_to_avoid:
- partial coexistence between `radix-ui` and individual primitive imports in local component source
- assuming the CLI removes old packages automatically
- assuming the CLI migrates `@radix-ui/react-icons`
- silently expanding the scope into Base UI migration
- widening the change into unrelated design-system refactors
execution_plan:
"Phase 1: Discovery":
- capture `shadcn info --json`
- inventory all primitive imports
- inventory all local shadcn-owned components
- inventory all docs/policy references to primitive import conventions
- record `@radix-ui/react-icons` usage and ownership separately
"Phase 2: Decisions":
- lock the canonical primitive import style
- lock whether the official CLI migration applies cleanly
- lock cleanup policy for old primitive packages
- lock whether `@radix-ui/react-icons` is explicitly deferred
- lock that Base UI is out of scope unless explicitly approved
"Phase 3: Code Changes":
- run `${PM_DLX} shadcn@latest migrate radix`
- review the diff file-by-file
- fix any local edge cases the migration did not cover cleanly
- add `radix-ui` if it is still missing
- remove obsolete individual `@radix-ui/react-*` packages after zero references are proven
"Phase 4: Policy And Docs":
- update AGENTS or repo guidance if it still describes the old import shape
- update architecture or frontend docs if they mention stale primitive policy
- write or update the migration report with current guidance, actual CLI behavior, final decisions, verification evidence, and residual risks
"Phase 5: Verification":
- lint
- typecheck
- tests
- build
- audit
- grep-based proof that old primitive imports and removed packages are gone
verification_commands:
- "# inventory"
- "rg -n '@radix-ui/react-|radix-ui|@radix-ui/react-icons' ."
- ""
- "# inspect project config"
- "${PM_DLX} shadcn@latest info --json"
- "${PM_DLX} shadcn@latest migrate --list"
- "${PM_DLX} shadcn@latest migrate radix --help"
- ""
- "# verification"
- "${PM_RUN} lint"
- "${PM_RUN} type-check"
- "${PM_TEST}"
- "${PM_RUN} build"
- "${PM_AUDIT}"
- ""
- "# proof of hard cut"
- "rg -n 'from \"@radix-ui/react-' ."
report_heading: Migration Report Requirements
report_requirements:
- current starting state
- final decisions
- actual CLI behavior observed in this repo
- migration-specific caveats and skipped surfaces
- final verification evidence
- repo-specific findings and residual risks
skill_routing_playbook:
- "Always start in the upgrade and cleanup lane: `$repo-modernize-upgrade-audit`, `$opensrc`, `$opensrc-inspect`, `$technical-writing`, and `$hard-cut`."
- "Primary shadcn execution lane: `$vercel:shadcn` or a repo-local shadcn skill, plus the `shadcn` CLI."
- "Use official-doc lanes first for unstable claims: current shadcn docs, Radix docs, changelogs, and upstream source when needed."
- "Use `$vitest` or `$vitest-dev` when UI tests, coverage, or Vitest config need to change."
- "Use `$playwright-interactive`, `$next-browser`, or `$vercel:agent-browser` when migrated primitives need browser-visible verification."
- "Use `$build-web-apps:frontend-skill` only if the migration also includes an explicit visual redesign or composition pass."
- "Use `$bun-dev` only when Bun is the repo's real runtime or package-manager lane."
- "Do not use `$imagegen` for shadcn or Radix vector/UI-system migration unless raster asset generation is explicitly part of the surface."
operator_defaults:
- "Final primitive import style: `import { Dialog as DialogPrimitive } from \"radix-ui\"`."
- "use `${PM_DLX} shadcn@latest migrate radix` first"
- remove old `@radix-ui/react-*` packages only after grep proves zero usage
- keep `@radix-ui/react-icons` as a separate explicit decision
- keep Base UI out of scope unless explicitly requested
operator_fast_intake:
- confirm shadcn is present
- read `components.json`
- run `shadcn info --json`
- "grep for: `@radix-ui/react-`, `radix-ui`, `@radix-ui/react-icons`"
- map all direct primitive import sites
- find any AGENTS/docs that describe primitive import policy
operator_research:
- verify shadcn CLI help and migration docs
- verify Radix unified package guidance
- inspect shadcn migrator source if the docs are not specific enough
operator_execute:
- run `${PM_DLX} shadcn@latest migrate radix`
- review the diff file-by-file
- fix any local edge cases, especially around `Slot` and shared overlays
- add `radix-ui` if still missing
- remove obsolete individual primitive packages once zero references are proven
- update docs/policy to match the final primitive import shape
operator_exit_criteria:
- local shadcn-owned primitives use `radix-ui`
- obsolete individual primitive packages are gone
- docs/policy match the final state
- verification is green
- "`@radix-ui/react-icons` status is explicit, not accidental"
skill_routing_operator:
- "Default lane: `$repo-modernize-upgrade-audit`, `$opensrc`, `$opensrc-inspect`, `$technical-writing`, `$hard-cut`."
- "Primary execution lane: `$vercel:shadcn` or a repo-local shadcn skill, plus the `shadcn` CLI."
- "Proof lane: current shadcn/Radix docs and upstream source when CLI behavior needs confirmation."
- "Test and browser lanes: `$vitest` or `$vitest-dev` for test changes; `$playwright-interactive`, `$next-browser`, or `$vercel:agent-browser` for visible regression checks."
- "Conditional lanes: `$bun-dev` for Bun repos, framework/plugin lanes only when actually relevant."
- "Do not route this migration through `$imagegen`."
trigger_mission: Act as an architect-level modernization engineer performing a verification-first shadcn Radix unification migration in this repository.
trigger_goals:
- "reach one canonical primitive end state: local shadcn-owned components import from `radix-ui`"
- use the official shadcn migration where it helps, but do not over-credit it
- delete stale import conventions, obsolete primitive packages, and stale docs
- keep the diff reviewable and the final state simpler than the initial state
trigger_required_research:
- inspect `components.json`, manifests, lockfiles, AGENTS/docs, and all direct primitive imports first
- run `shadcn info --json` and record framework, style, base, resolved paths, and installed components
- verify current shadcn CLI/changelog guidance and Radix installation guidance before editing
- build a touched-files map before broad edits
trigger_required_decisions:
- confirm the repo is a real `new-york` plus Radix migration candidate
- decide whether `shadcn migrate radix` covers the owned component surface
- decide whether `@radix-ui/react-icons` is explicitly in or out of scope
- keep Base UI migration out of scope unless explicitly requested
trigger_required_outcomes:
- standardize local shadcn-owned primitive imports on `radix-ui`
- use `shadcn migrate radix` as the starting rewrite step where applicable
- remove obsolete `@radix-ui/react-*` packages only after grep proves they are unused
- update repo policy/docs to match the final primitive import convention
- treat `@radix-ui/react-icons` as a separate explicit decision because the official migration skips it
trigger_required_deliverables:
- findings matrix
- decision log
- affected-files map
- migration checklist
- exact verification commands
- migration report
- residual risks or explicit defer reasons
trigger_verification_expectation:
- run lint, typecheck, tests, build, and audit
- prove old primitive import paths are gone with grep
- verify shared overlay/focus components still behave correctly after rewrite
match_packages:
- turbo
- turborepo
family_slug: turborepo
family_display_name: Turborepo
family_type: tooling
mode: upgrade+optimize
plan_basename: turborepo-monorepo-upgrade-and-optimization
playbook_title: Turborepo Monorepo Upgrade And Optimization Playbook
operator_title: Turborepo Monorepo Upgrade And Optimization Operator Mode
trigger_title: Turborepo Monorepo Upgrade And Optimization Trigger Prompt
related_packages:
- turbo
purpose: Use this playbook to fully explore, research, plan, implement, verify, and document a Turborepo upgrade or monorepo task-graph optimization wave in this repository.
use_when:
- the repository already uses Turborepo
- the repo needs a Turborepo version upgrade, package-config audit, or task-graph cleanup
- the repo needs one canonical artifact covering root task orchestration, package configs, and validation posture
primary_goal:
- reach one verified canonical Turborepo task-graph and package-config end state for the monorepo
- align root delegation, package tasks, and package configurations with current official guidance
- remove stale root-task logic or duplicated orchestration that Turborepo should own instead
non_goals:
- unrelated app or package redesign outside the monorepo orchestration boundary
- moving package task logic into bespoke root shell scripts
- treating workspace package configurations as optional docs when they actively change task behavior
source_hierarchy:
- official Turborepo docs and reference pages
- official package-configuration and affected-run guidance
- local repo task graph, scripts, and package configs
- package manager metadata, lockfiles, and release notes
default_final_decisions:
- treat Turborepo as a monorepo-root concern with related workspace package configs
- prefer package tasks plus root delegation via `turbo run`
- support both version-upgrade and same-major optimization outcomes inside one pack
intake_checklist:
- record current `turbo` version
- record package manager and lockfile shape
- inspect root `turbo.json`
- inspect any workspace `turbo.json` package configurations
- inventory root scripts that delegate to or bypass Turborepo
- build a touched-files map before editing
required_research:
Upstream Turborepo:
- verify current run-reference guidance
- verify current package-configuration inheritance rules
- verify current affected-run and graph-inspection guidance
Upstream source inspection:
- inspect source only when docs do not answer task-graph or package-config behavior questions
questions_to_resolve:
- is this run primarily a version bump, a task-graph cleanup, or both
- which root scripts are canonical delegation surfaces and which are stale
- which workspace package configs materially affect the final task graph
- which CI or local validation commands must remain coupled to the Turborepo surface
canonical_end_state:
- the monorepo uses current verified Turborepo guidance
- root scripts delegate cleanly and package tasks own the real task logic
- package configurations and docs match the final task graph
- lint, typecheck, tests, build, and audit remain green
what_to_adopt:
- current `turbo run` delegation and graph-inspection workflows
- package configuration inheritance and affected-run validation
- existing repo-native package-task patterns when they already fit current guidance
what_to_avoid:
- stale root task logic that bypasses Turborepo
- package configs left unaudited when they override root behavior
- mixed shorthand and canonical `turbo run` conventions in code and CI
execution_plan:
"Phase 1: Discovery":
- inventory root and workspace `turbo.json` files, root scripts, and package task ownership
- inventory CI or local validation commands that depend on the task graph
- inventory current version and monorepo feature usage
"Phase 2: Decisions":
- lock the final version or optimize-only scope
- lock the root-vs-package task ownership model
- lock package-config cleanup and explicit defers
"Phase 3: Code Changes":
- align root delegation, package configs, and task-graph tooling to the final verified shape
- remove stale orchestration that Turborepo should no longer share with custom root logic
- update docs and policy to match the final state
"Phase 4: Verification":
- run repo-native validation
- run Turborepo graph and affected-run checks
- write the final upgrade and optimization report with residual risks
report_heading: Upgrade And Optimization Report Requirements
report_requirements:
- current root and package-config starting state
- final decisions
- current Turborepo features and task-graph signals relevant to the repo
- stale or deprecated patterns removed or intentionally retained
- graph, affected-run, and validation evidence
- repo-specific findings and residual risks
skill_routing_playbook:
- "Always start in the upgrade lane: `$repo-modernize-upgrade-audit`, `$opensrc`, `$opensrc-inspect`, `$technical-writing`, `$hard-cut`, `$turborepo`, and `$vercel:turborepo` when useful."
- "Use official Turborepo docs first for unstable claims."
- "Use `$bun-dev` only when Bun is the repo's real package-manager or runtime lane."
- "Use `$platform-architect` when task-graph changes materially affect web/native/backend coordination."
- "Do not use `$imagegen` for Turborepo upgrade work."
skill_routing_operator:
- "Default lane: `$repo-modernize-upgrade-audit`, `$opensrc`, `$opensrc-inspect`, `$technical-writing`, `$hard-cut`, `$turborepo`, and `$vercel:turborepo` when useful."
- "Proof lane: official Turborepo docs first, source only when public guidance is insufficient."
- "Conditional lanes: `$bun-dev` for Bun repos, `$platform-architect` for cross-stack monorepo coordination."
- "Do not route this migration through `$imagegen`."
operator_defaults:
- Final Turborepo posture follows current verified official guidance.
- Root scripts delegate; package tasks own real task logic.
- Package configurations are treated as live task-graph surfaces, not optional docs.
- No stale root orchestration remains unless a real external boundary requires it.
operator_fast_intake:
- record current `turbo` version
- record package manager
- inspect root `turbo.json`
- inspect any workspace package-config `turbo.json` files
- inventory root scripts that delegate to or bypass Turborepo
operator_research:
- verify the current run reference and package-configuration docs
- verify current `--affected` and graph-inspection guidance
- inspect source only when docs are insufficient
operator_execute:
- align root delegation, package configs, and task-graph tooling to the final verified posture
- remove stale orchestration that Turborepo should no longer share with custom root logic
- update docs and policy to match the final state
operator_exit_criteria:
- the monorepo follows the final verified Turborepo posture
- package tasks and package configs match the final task graph
- stale root orchestration is gone or explicitly deferred
- verification is green
trigger_mission: Act as an architect-level modernization engineer performing a verification-first Turborepo upgrade and monorepo task-graph optimization wave in this repository.
trigger_goals:
- reach one canonical final Turborepo end state for the monorepo
- support both version-upgrade and same-major optimization work
- remove stale root orchestration, package-config drift, and unnecessary task-graph duplication where justified
- keep the diff reviewable and the final state simpler than the initial state
trigger_required_research:
- inspect manifests, lockfiles, root and workspace `turbo.json`, scripts, and AGENTS/docs first
- verify current official Turborepo guidance before editing
- use official docs, upstream source, and repo-native commands
- build a touched-files map before broad edits
trigger_required_decisions:
- confirm whether this run is upgrade-only, optimize-only, or both
- decide the canonical final root-vs-package task ownership model
- decide which package configs and CI boundaries are in or out of scope
- decide which stale orchestration or shorthand conventions can be deleted
trigger_required_outcomes:
- standardize on the verified final Turborepo task-graph and delegation shape
- remove stale root orchestration and unnecessary related dependencies
- update repo policy and docs to match the final convention
trigger_required_deliverables:
- findings matrix
- decision log
- affected-files map
- migration checklist
- exact verification commands
- upgrade and optimization report
- residual risks or explicit defer reasons
trigger_verification_expectation:
- run lint, typecheck, tests, audit, and graph or affected-run checks
- prove removed patterns are gone with grep or equivalent checks
Manifest Schema
The canonical rendered source is upgrade-pack.yaml.
Required Keys
schema_versionfamily_display_namefamily_typemodefamily_slugplan_basenameplaybook_titleoperator_titletrigger_titleanchor_packagerelated_packagesrepo_contexttarget_surfacequalification_planresearch_plancurrent_versionvalidated_upstream_versionvalidated_doc_daterepo_probesupstream_validationpurposeuse_whenprimary_goalnon_goalsprimary_personasecondary_audienceoperating_goalssource_hierarchydefault_final_decisionsintake_checklistrequired_researchquestions_to_resolvecanonical_end_statewhat_to_adoptwhat_to_avoidframework_constraintssupported_featuresunsupported_featurescodemod_recommendationsexecution_planverification_commandsreport_headingreport_requirementsdeliverablesskill_routing_playbookoperator_defaultsoperator_fast_intakeoperator_researchoperator_executeoperator_exit_criteriaskill_routing_operatortrigger_missiontrigger_goalstrigger_required_researchtrigger_required_decisionstrigger_required_outcomestrigger_required_deliverablestrigger_verification_expectation
Notes
repo_contextis generated from live repo inspection.target_surfaceis the family-specific owner surface chosen during
enrichment. It should explicitly identify whether the pack is root-owned, workspace-owned, or root-plus-workspaces, plus the verification strategy used for that shape.
qualification_plandrives the separate qualification stage. It should
declare the snapshot filename, current doc URLs, pinned source specs, and family-native read-only CLI checks.
research_plandrives the separate research stage. It should declare the
snapshot filename, raw bundle filename, web-findings filename, source-map policy, identity-confidence threshold, required evidence categories, required web-confirmation categories, target-version policy, release-range reasoning, source priorities, upstream URL buckets, pinned source specs, and repo-usage mapping commands.
family_typeshould distinguish broad families such aspackagevs
framework.
modeshould express the mission shape such asupgrade,optimize, or
upgrade+optimize.
current_version,validated_upstream_version, andvalidated_doc_date
should be recorded after enrichment.
repo_probesandupstream_validationare dictionaries whose values are
ordered string lists.
required_researchandexecution_planare dictionaries whose values are
ordered string lists.
verification_commandsis an ordered list of shell lines rendered into one
fenced block.
plan_basenamecontrols file names:<plan_basename>-playbook.md<plan_basename>-trigger-prompt.md<plan_basename>-operator-mode.mdresearch_plan.snapshot_filenamecontrols the machine-readable research file
name, usually research-snapshot.json.
research_plan.bundle_filenamecontrols the raw machine-readable research
bundle file name, usually research-bundle.json.
research_plan.web_findings_filenamecontrols the machine-readableweb.run
confirmation file name, usually web-research-findings.json.
research_plan.source_map_policydescribes how the bundled source map should
be used, usually bundled-seed-then-verify.
research_plan.identity_confidence_thresholdcontrols the minimum confidence
required for the generic package-identity resolver to count the pack as fully researched.
research_plan.required_web_confirmation_categoriesdeclares which
categories must have explicit web.run confirmations before the research stage can be complete.
qualification_plan.snapshot_filenamecontrols the machine-readable
qualification file name, usually qualification-snapshot.json.
Minimal Example
schema_version: 3
family_display_name: Lucide React
family_type: package
mode: upgrade
family_slug: lucide-react
plan_basename: lucide-react-v1-upgrade
playbook_title: Lucide React v1 Upgrade Playbook
operator_title: Lucide React v1 Upgrade Operator Mode
trigger_title: Lucide React v1 Upgrade Trigger Prompt
anchor_package: lucide-react
related_packages:
- lucide-react
repo_context:
repo_root: /path/to/repo
package_manager: pnpm
detected_by: packageManager
target_surface:
surface_type: workspace
workspace_path: apps/web
workspace_name: '@repo/web'
workspace_package_json: apps/web/package.json
workspace_slug: apps-web
owner_reason: apps/web declares the framework package and owns its config.
related_workspaces:
- apps/web
verification_strategy: layered-root-and-workspace
qualification_plan:
strategy: separate-read-only-qualification
snapshot_filename: qualification-snapshot.json
doc_urls:
upgrade guide: https://nextjs.org/docs/app/guides/upgrading/version-16
source_specs:
- next@16.2.4
cli_checks:
- label: Next.js codemod help
cwd: apps/web
command: pnpm dlx @next/codemod@canary --help
research_plan:
strategy: separate-read-only-research
snapshot_filename: research-snapshot.json
bundle_filename: research-bundle.json
web_findings_filename: web-research-findings.json
required_categories:
- official_docs
- api_reference
- migration_guides
- release_history
- examples_cookbooks
- source_evidence
- repo_usage_mapping
source_priority:
- official docs and API references first
- official migration guides and upgrade walkthroughs second
- official blog, release notes, and changelog sources third
- upstream source inspection fourth
- examples and cookbooks fifth
- repo-local usage mapping always required
identity_confidence_threshold: 0.75
source_map_policy: bundled-seed-then-verify
required_web_confirmation_categories:
- official_docs
- api_reference
target_version_policy: latest-compatible-stable
target_version: Next.js 16
compatibility_rationale: >-
Stay on the latest compatible stable Next.js 16 surface that fits the
repo's runtime and deployment constraints.
release_range: 16.2.4 -> Next.js 16
official_docs:
docs home: https://nextjs.org/docs
api_reference:
typedRoutes: https://nextjs.org/docs/app/api-reference/config/next-config-js/typedRoutes
migration_guides:
upgrade guide: https://nextjs.org/docs/app/guides/upgrading/version-16
release_history:
github releases: https://github.com/vercel/next.js/releases
examples_cookbooks:
static exports: https://nextjs.org/docs/app/guides/static-exports
source_specs:
- next@16.2.4
repo_usage_queries:
- label: Next config and route surfaces
cwd: .
command: rg --files apps/web | rg '(next\\.config\\.|(^|/)proxy\\.|(^|/)app/)'
current_version: 0.577.0
validated_upstream_version: v1
validated_doc_date: 2026-03-31
repo_probes:
Repo posture:
- record family-specific probe results here
upstream_validation:
Official guidance:
- record the live official guidance snapshot here
purpose: >-
Use this playbook to fully explore, research, plan, implement, verify, and
document a `lucide-react` upgrade in this repository.
use_when:
- the repo already uses `lucide-react`
primary_goal:
- standardize on named imports from `lucide-react`
non_goals:
- unrelated design-system rewrites
framework_constraints:
- record any family-specific constraints here
supported_features:
- record supported features here
unsupported_features:
- record unsupported or intentionally out-of-scope features here
codemod_recommendations:
- record codemods or automated migration helpers hereProvenance Scoring
research_upgrade_pack.py now emits per-category provenance in category_provenance.
Factors
officiality- how authoritative the source looks
freshness- how recently the bundled source-map entry was verified
directness- whether the category has explicit
web.runconfirmation package_specificity- whether the source is package-specific instead of generic ecosystem prose
Score
The current weighted score is:
- officiality:
35% - freshness:
20% - directness:
25% - package specificity:
20%
This score is a trust signal, not a final gate by itself. Readiness still depends on:
- required category coverage
- identity confidence
- compatible target resolution
- required
web.runconfirmations
Qualification Schema
qualification-snapshot.json is the machine-readable evidence file produced by scripts/qualify_upgrade_pack.py.
Required Keys
schema_versiongenerated_atfamily_sluganchor_packagerepo_rootsnapshot_filenamequalification_statussummaryresearch_snapshotdoc_checkssource_checkscli_checksrepo_local_skill_overlayscaveats
Status Values
readyready-with-caveatsinsufficient-evidence
Summary Shape
summary should contain integer counters for:
doc_checksdoc_failuressource_checkssource_failurescli_checkscli_failuresrepo_local_overlaysresearch_status
Notes
- Qualification is downstream of the research stage. A pack cannot be
ready
unless research-snapshot.json reports research_status = complete.
research_snapshotrecords the linked research snapshot path plus the
observed research status at qualification time.
doc_checksrecords live official-doc metadata for the URLs declared in
qualification_plan.doc_urls.
source_checksrecords pinnedopensrc pathevidence for the specs declared
in qualification_plan.source_specs.
cli_checksrecords family-native read-only command results for the commands
declared in qualification_plan.cli_checks.
repo_local_skill_overlaysrecords optional repo-local skill matches detected
under .agents/skills/.
- Keep this file machine-readable. Human summaries belong in the rendered
playbook/operator docs.
Qualification Strategy
The qualification stage is intentionally separate from bootstrap, enrichment, and rendering.
Why It Is Separate
- bootstrap and enrich stay focused on deterministic repo and family structure
- qualification can be rerun independently when docs, CLI behavior, or local
overlays change
- render stays a pure document-generation step with an optional evidence input
Qualification Inputs
upgrade-pack.yaml- the target repo root from
repo_context.repo_root qualification_plan.doc_urlsqualification_plan.source_specsqualification_plan.cli_checks
Qualification Outputs
qualification-snapshot.json- rendered summary sections in the playbook and operator-mode files
Command Rules
- qualification commands must be read-only
- prefer
--help, graph inspection, package listing, config display, and doctor
or diagnostics surfaces
- do not run install, deploy, publish, or code-changing commands in the
qualification stage
Overlay Rules
- repo-local skill overlays are optional accelerators, not required contracts
- the base family lane must stay correct without overlays
- overlays should only append routing or evidence hints; they must not replace
the universal family logic
Research Bundle Schema
research-bundle.json is the raw evidence artifact produced by scripts/research_upgrade_pack.py.
Required Keys
schema_versiongenerated_atfamily_sluganchor_packagerepo_rootsnapshot_filenamebundle_filenameweb_findings_filenameidentitysource_map_seedtarget_resolutionregistrygithubctx7collectorsrepo_runtimediscovered_sourcessource_evidencerepo_usage_mappingcategory_entriescategory_statuscategory_provenanceweb_research_queueweb_research_findingscaveats
Notes
- Keep this file machine-readable. It is the raw evidence ledger, not a human
narrative.
identityshould include the canonical package identity, resolved docs and
repository surfaces, confidence, evidence, conflicts, and unresolved surfaces.
target_resolutionshould include the selected target version, compatibility
status, candidate versions reviewed, peer and engine checks, and any evidence-backed related packages.
registryshould summarize the npm metadata call used to seed generic
discovery.
githubshould summarize resolved repository metadata and recent release
tags when available.
ctx7should capture library resolution plus any category-level docs queries
used for API-reference, migration, or example discovery.
source_map_seedshould capture the bundled source-map entry, freshness, and
drift findings used to seed generic package research.
collectorsshould summarize optional adapters or local tools detected at
runtime.
category_entriesshould mirror the category material that rolled up into
research-snapshot.json.
web_research_queueshould be the machine-readable queue Codex uses with
web.run for official docs and API references.
Research Lanes
Default lanes:
$repo-modernize-upgrade-audit$opensrc$opensrc-inspect$technical-writing$hard-cut
Required evidence posture:
- official docs and API references
- official migration guides and upgrade walkthroughs
- official changelogs, release notes, or release posts
- pinned upstream source when docs are insufficient
- repo-local usage mapping before implementation
Conditional lanes:
$bun-dev- only when Bun is part of the target repo's package-manager or runtime
posture
$github- when release metadata, issues, PRs, or repo state materially improve the
pack
- framework/plugin lanes
- only when the target repo detects that framework or platform
- for Next.js packs, prefer
$verceland$vercel:nextjsalongside official
nextjs.org docs
- for Expo/EAS packs, prefer
$expoand$expo:upgrading-expoalongside
official docs.expo.dev guidance
- for Convex packs, prefer the repo-local Convex skill plus official
docs.convex.dev guidance
- for Turborepo packs, prefer
$turborepoand$vercel:turborepo
alongside official turborepo.com docs
- browser verification lanes
- only when the package family changes visible UI behavior
Do not use raster/image-generation lanes for dependency upgrade packs unless the dependency family explicitly includes bitmap asset generation.
Research Schema
research-snapshot.json is the machine-readable evidence file produced by scripts/research_upgrade_pack.py.
The same stage also writes research-bundle.json, a raw evidence bundle with identity resolution, registry metadata, release history traces, Context7 hits, source evidence, repo-usage outputs, bundled source-map drift checks, and the machine-readable web.run queue.
Required Keys
schema_versiongenerated_atfamily_sluganchor_packagerepo_rootsnapshot_filenamebundle_filenameweb_findings_filenameresearch_statuscurrent_versiontarget_versiontarget_version_policycompatibility_rationalerelease_rangerequired_categoriescategory_statuscategory_provenancesummaryidentitysource_map_seedtarget_resolutionrecommended_related_packagesofficial_docsapi_referencemigration_guidesrelease_historyexamples_cookbookssource_evidencerepo_usage_mappingweb_research_queueweb_research_findingscaveats
Status Values
completepartialinsufficient-evidence
Required Categories
Every research plan must model these categories:
official_docsapi_referencemigration_guidesrelease_historyexamples_cookbookssource_evidencerepo_usage_mapping
Notes
- Keep this file machine-readable. Human summaries belong in the rendered
playbook and operator docs.
identity.statusshould behigh-confidence,medium-confidence, or
low-confidence.
target_resolution.selected_statusshould distinguishcompatible,
compatible-with-caveats, and incompatible.
category_statusshould useok,partial,failed, ormissing.release_rangeshould explain the current-to-target range that was actually
reviewed.
web_research_queueshould contain the required and optionalweb.run
pages that still need official confirmation.
web_research_findingsshould summarize any confirmed official pages already
written to web-research-findings.json.
source_evidenceshould include pinnedopensrc pathresolution plus any
high-signal changelog, migration, or example files found in the fetched source tree.
repo_usage_mappingshould capture read-only grep or inventory commands that
prove how the target repo currently uses the package family.
recommended_related_packagesshould contain evidence-backed peer or
companion packages that likely belong in the same upgrade wave.
Research Strategy
The research stage exists to prove that a pack actually reviewed the upstream surfaces needed for a safe, modern upgrade.
Goals
- prove that official docs and API references were reviewed
- prove that migration guides and release notes for the relevant range were
reviewed
- prove that examples or cookbook-style adoption guidance were reviewed
- prove that pinned upstream source was inspected when needed
- prove that repo-local usage was mapped before implementation begins
Source Priority
1. Official docs and API references 2. Official migration guides and upgrade walkthroughs 3. Official release notes, changelogs, and release posts 4. Upstream source inspection 5. Official examples and cookbook-style guides 6. Repo-local usage mapping
Enforcement
research_planinupgrade-pack.yamldeclares the required categories and
exact URLs, source specs, and repo-usage commands.
scripts/research_upgrade_pack.pyproducesresearch-snapshot.json.scripts/qualify_upgrade_pack.pymust read that snapshot before it can mark a
pack ready.
- If required categories are missing or failed, qualification must degrade to
ready-with-caveats or insufficient-evidence.
Family Guidance
- Next.js packs should include official docs, API refs, version upgrade guides,
release posts or releases, and repo-specific route/config usage mapping.
- Expo/EAS packs should include SDK guides, EAS docs, changelog sources,
package reference pages, and mobile-workspace config mapping.
- Convex packs should include CLI docs, generated API or client references,
release sources, and repo-specific schema or codegen mapping.
- Turborepo packs should include root config guidance, query or ls references,
release sources, and monorepo task-graph mapping.
- Generic packs should still define the full contract, but may remain
insufficient-evidence until a human or later family override supplies the missing official sources.
Web Research Contract
upgrade-pack-generator cannot call web.run from Python. The browser confirmation step is therefore an explicit Codex workflow stage.
Inputs
research-bundle.json- use
web_research_queue upgrade-pack.yaml- use
research_plan.required_web_confirmation_categories
Required Behavior
1. Read web_research_queue from research-bundle.json. 2. For every queue item where required_for_complete=true, use web.run to confirm the official page. 3. Prefer the seeded official page first. Only broaden the search when the seeded page is broken or clearly non-authoritative. 4. Capture concise facts that materially affect the upgrade plan:
- latest compatible API refs
- migration constraints
- newly recommended capabilities
- deprecations or removals
5. Write those confirmations to web-research-findings.json. 6. Re-run scripts/research_upgrade_pack.py so research-snapshot.json reflects the confirmed pages before qualification.
web-research-findings.json Shape
{
"entries": [
{
"category": "official_docs",
"url": "https://example.dev/docs",
"confirmed": true,
"confirmed_at": "2026-04-20T00:00:00Z",
"facts": [
"Short machine-readable fact 1.",
"Short machine-readable fact 2."
]
}
]
}Completion Rule
If a category listed in required_web_confirmation_categories does not have a confirmed entry in web-research-findings.json, research_status must not be complete.
Workflow
upgrade-pack-generator has two explicit modes.
Mode 1: Family Authoring
Use this when a dependency family deserves reusable knowledge across many repos.
Steps:
1. Pick the canonical family slug and anchor package. 2. Create or update a YAML override in references/family-overrides/. 3. Keep the override family-specific:
- package-native end state
- related packages and aliases
- special research lanes
- verification proofs
- naming conventions
4. Do not duplicate generic pack structure already provided by the base generator.
Mode 2: Repo Instantiation
Use this when you want a repo-local pack for a concrete repository.
Steps:
1. Detect repo context with scripts/detect_repo_context.py. 2. Bootstrap a starter manifest with scripts/bootstrap_manifest.py. 3. Enrich the manifest with scripts/enrich_manifest.py. 4. During enrichment, lock the owner surface explicitly:
- repo root
- one owning workspace
- repo root plus related workspaces
5. Refine the manifest further with live repo research and upstream package research. 6. Validate the manifest. 7. Run scripts/research_upgrade_pack.py to capture upstream docs, API refs, release notes, cookbooks, source evidence, repo-usage mapping, package identity, and target-version reasoning in research-snapshot.json plus the raw research-bundle.json. 8. Use Codex web.run against the required web_research_queue items from research-bundle.json and write the confirmations to web-research-findings.json. 9. Re-run scripts/research_upgrade_pack.py so research-snapshot.json includes the official-page confirmations and blocks complete when they are still missing. 10. Run scripts/qualify_upgrade_pack.py to capture read-only docs, source, CLI, and repo-local overlay evidence in qualification-snapshot.json. 11. Render the pack into .agents/plans/upgrade/<topic>/.
The rendered pack should follow this final contract:
- the playbook is the human source of truth
- the playbook is the only file updated during a real implementation run
- operator-mode is a delta card with links back to playbook sections
- trigger-prompt is a thin launcher that tells a fresh Codex session to load
the playbook first
upgrade-pack.yaml,research-snapshot.json, and
qualification-snapshot.json remain the canonical machine-readable sources
research-bundle.jsonis the raw evidence ledger behind the research
snapshot
web-research-findings.jsonis the machine-readableweb.runevidence file
for the required official docs and API-reference surfaces
Guardrails
- Generation is docs/research only.
- Do not implement package upgrades while building the pack.
- The generated
upgrade-pack.yamlis the canonical source. research-snapshot.jsonis the canonical machine-readable research evidence
file for the rendered pack.
research-bundle.jsonis the canonical raw evidence bundle for the rendered
pack.
qualification-snapshot.jsonis the canonical machine-readable qualification
evidence file for the rendered pack.
operator-mode.mdandtrigger-prompt.mdare rendered derivatives, not
hand-maintained documents.
- Use one package-manager command family per target repo run.
- In monorepos, prefer workspace-owned family packs over root-centric guesses.
#!/usr/bin/env python3
"""Bootstrap an upgrade-pack manifest from repo context and optional family overrides."""
from __future__ import annotations
import argparse
from pathlib import Path
from typing import Any
from common import (
available_override_paths,
detect_repo_context,
dump_yaml,
load_yaml,
normalize_slug,
recursive_merge,
repo_path,
titleize_package,
unique_list,
)
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--repo-root", required=True, help="Path to the target repo root.")
parser.add_argument("--anchor-package", required=True, help="Primary package driving the pack.")
parser.add_argument("--out", required=True, help="Path to write upgrade-pack.yaml.")
parser.add_argument("--family-slug", help="Optional explicit family slug override.")
return parser
def match_override(anchor_package: str, script_path: Path) -> dict[str, Any] | None:
"""Find a matching family override for an anchor package."""
for path in available_override_paths(script_path):
data = load_yaml(path) or {}
candidates = set(data.get("match_packages") or [])
if anchor_package in candidates:
return data
return None
def generic_manifest(anchor_package: str, repo_context: dict[str, Any], family_slug: str) -> dict[str, Any]:
"""Build a generic manifest when no family override exists."""
display = titleize_package(anchor_package)
plan_basename = f"{family_slug}-upgrade"
repo_usage_queries = [
{
"label": f"{display} manifest declarations",
"cwd": ".",
"command": f"rg -n '\"{anchor_package}\"' . --glob 'package.json' --glob 'pnpm-workspace.yaml' --glob 'bunfig.toml'",
},
{
"label": f"{display} repo usage",
"cwd": ".",
"command": f"rg -n '{anchor_package}' .",
},
]
return {
"schema_version": 3,
"family_slug": family_slug,
"family_display_name": display,
"family_type": "package",
"mode": "upgrade",
"plan_basename": plan_basename,
"playbook_title": f"{display} Upgrade Playbook",
"operator_title": f"{display} Upgrade Operator Mode",
"trigger_title": f"{display} Upgrade Trigger Prompt",
"anchor_package": anchor_package,
"related_packages": [anchor_package],
"repo_context": repo_context,
"target_surface": {
"surface_type": "repo-root",
"workspace_path": ".",
"workspace_name": "(root)",
"workspace_package_json": "package.json",
"workspace_slug": "root",
"owner_reason": "Default root-scoped package family until enrichment proves a narrower owner workspace.",
"related_workspaces": ["."],
"verification_strategy": "root-only",
},
"qualification_plan": {
"strategy": "separate-read-only-qualification",
"snapshot_filename": "qualification-snapshot.json",
"doc_urls": {},
"source_specs": [],
"cli_checks": [],
},
"research_plan": {
"strategy": "separate-read-only-research",
"snapshot_filename": "research-snapshot.json",
"bundle_filename": "research-bundle.json",
"web_findings_filename": "web-research-findings.json",
"required_categories": [
"official_docs",
"api_reference",
"migration_guides",
"release_history",
"examples_cookbooks",
"source_evidence",
"repo_usage_mapping",
],
"source_priority": [
"official docs and API references first",
"official migration guides and upgrade walkthroughs second",
"official blog, release notes, and changelog sources third",
"upstream source inspection fourth",
"examples and cookbooks fifth",
"repo-local usage mapping always required",
],
"identity_confidence_threshold": 0.75,
"source_map_policy": "bundled-seed-then-verify",
"required_web_confirmation_categories": [
"official_docs",
"api_reference",
],
"target_version_policy": "latest-compatible-stable",
"target_version": "latest supportable stable release to be confirmed during enrichment and research",
"compatibility_rationale": (
"Use the latest supportable stable release whose documented constraints fit the repo's "
"framework, runtime, and policy boundaries."
),
"release_range": "current repo version -> latest supportable stable release under verified repo constraints",
"official_docs": {},
"api_reference": {},
"migration_guides": {},
"release_history": {},
"examples_cookbooks": {},
"source_specs": [],
"repo_usage_queries": repo_usage_queries,
},
"current_version": "unknown",
"validated_upstream_version": "unverified",
"validated_doc_date": "unverified",
"repo_probes": {
"Repo posture": [
"Run the family-specific enrichment step to record framework or package probes.",
],
},
"upstream_validation": {
"Official guidance": [
"Record the current official docs, version, and last-updated date during enrichment.",
],
},
"framework_constraints": [
"Record family-specific constraints during enrichment before broad edits begin.",
],
"supported_features": [
"Record family-specific supported features during enrichment.",
],
"unsupported_features": [
"Record family-specific unsupported or intentionally out-of-scope features during enrichment.",
],
"codemod_recommendations": [
"Record family-specific codemods or automated migration helpers during enrichment.",
],
"purpose": (
f"Use this playbook to fully explore, research, plan, implement, verify, and "
f"document a `{anchor_package}` upgrade in this repository."
),
"use_when": [
f"the repository already uses `{anchor_package}`",
"the package likely has upgrade-specific cleanup or modernization work",
"you need one repo-local artifact for research, decisions, execution, and closeout",
],
"primary_goal": [
f"upgrade `{anchor_package}` to the latest supportable version",
"adopt package-native APIs where they simplify local code",
"leave current docs, verification evidence, and a reviewable execution path",
],
"non_goals": [
"unrelated framework rewrites",
"folding adjacent dependency waves into scope without evidence",
"adding compatibility layers that are not justified by a real boundary",
],
"primary_persona": "Codex acting as an architect-level modernization engineer.",
"secondary_audience": "Human maintainers reviewing the migration, risks, and completion evidence.",
"operating_goals": [
"research before editing",
"prefer official docs and upstream source over assumption",
"keep one canonical implementation path",
"delete stale wrappers, shims, and dead dependencies when justified",
"keep a concise ledger of findings, decisions, completed work, and residual risks",
],
"source_hierarchy": [
f"official `{anchor_package}` docs and migration guidance",
"official framework docs for the target repo",
f"upstream `{anchor_package}` source code",
"local repo code, tests, and docs",
"package manager metadata, lockfiles, audits, and release notes",
],
"default_final_decisions": [
"prefer current package-native APIs over stale local abstractions",
"use one hard-cut wave unless repo-specific evidence requires otherwise",
f"keep scope centered on `{anchor_package}` and directly related packages",
],
"intake_checklist": [
"confirm framework and version, especially the package's host framework",
f"record the current `{anchor_package}` version",
"record package manager and lockfile shape",
f"search all `{anchor_package}` usage",
"search repo docs, AGENTS, and contributing guides for local policy",
"build a touched-files map before editing",
],
"required_research": {
f"Upstream {display}": [
"verify latest stable guidance",
"verify migration notes, deprecations, and release constraints",
"verify current exported types, APIs, and package-native capabilities",
],
"Upstream framework": [
"verify host-framework integration guidance that affects this package",
"verify whether any framework-native optimization or config matters",
],
"Upstream source inspection": [
"inspect source when docs, types, or changelogs do not answer behavior or migration risk questions",
],
},
"questions_to_resolve": [
f"what is the canonical final usage shape for `{anchor_package}` in this repo",
"which related packages or peers are truly part of the same upgrade wave",
"which local wrappers or abstractions no longer earn their keep after the upgrade",
"which docs or policy files must move with the code change",
],
"canonical_end_state": [
f"all live `{anchor_package}` usage follows current verified guidance",
"obsolete wrappers, shims, or compatibility paths are removed when no real boundary requires them",
"docs and repo policy describe the final package usage shape",
"lint, typecheck, tests, build, and audit remain green",
],
"what_to_adopt": [
"current package-native APIs and types",
"current framework-native integration points",
"existing local styling and architectural patterns unless the package now offers a simpler canonical path",
],
"what_to_avoid": [
"stale package APIs or deprecated imports",
"mixed old and new conventions left in parallel",
"local shims kept only to preserve a stale internal policy",
],
"execution_plan": {
"Phase 1: Discovery": [
f"inventory all `{anchor_package}` usage",
"inventory related packages and wrappers",
"inventory docs and policy references that mention the package",
],
"Phase 2: Decisions": [
"lock the canonical final package usage shape",
"lock scope for related packages and defers",
"lock rollout style and boundary exceptions",
],
"Phase 3: Code Changes": [
"apply the current package-native usage shape",
"remove obsolete wrappers, shims, and redundant dependencies",
"update docs and repo policy to match the final state",
],
"Phase 4: Verification": [
"run repo-native validation",
"prove removed patterns and dependencies are gone",
"write the final upgrade report and residual risks",
],
},
"verification_commands": [
"# inventory",
f"rg -n '{anchor_package}' .",
"",
"# verification",
"${PM_RUN} lint",
"${PM_RUN} typecheck",
"${PM_TEST}",
"${PM_RUN} build",
"${PM_AUDIT}",
],
"report_heading": "Upgrade Report Requirements",
"report_requirements": [
"current starting state",
"final decisions",
"features and capabilities available in the current target version",
"old patterns removed or discouraged",
"deprecations and practical replacements",
"repo-specific findings and residual risks",
],
"deliverables": [
"findings matrix",
"decision log",
"affected-files map",
"migration checklist",
"exact verification commands",
"upgrade report",
"residual risks or explicit defer reasons",
],
"skill_routing_playbook": [
"Always start in the upgrade lane: `$repo-modernize-upgrade-audit`, `$opensrc`, `$opensrc-inspect`, `$technical-writing`, and `$hard-cut`.",
"Use official-doc lanes first for unstable claims: current upstream docs, changelogs, and source when needed.",
"Use `$bun-dev` only when Bun is the repo's real runtime or package-manager lane.",
"Use framework/plugin lanes only when the target repo actually detects them.",
"Do not route this pack through `$imagegen` unless raster asset generation is explicitly part of the package-family surface.",
],
"operator_defaults": [
f"Final `{anchor_package}` usage follows current verified package-native guidance.",
"One canonical implementation path.",
"No stale compatibility shims unless a real external boundary requires them.",
],
"operator_fast_intake": [
"record framework and package version",
"record package manager",
f"grep for `{anchor_package}` usage and related packages",
"find any AGENTS/docs that describe local package policy",
],
"operator_research": [
f"verify current `{anchor_package}` docs and migration guidance",
"verify framework integration guidance",
"inspect upstream source only if docs and types are insufficient",
],
"operator_execute": [
f"migrate all live `{anchor_package}` usage to the canonical final shape",
"remove obsolete wrappers, shims, and redundant dependencies",
"update docs/policy to match the final state",
],
"operator_exit_criteria": [
f"all live `{anchor_package}` usage follows the final verified shape",
"obsolete compatibility code and dependencies are gone",
"docs/policy match the final state",
"verification is green",
],
"skill_routing_operator": [
"Default lane: `$repo-modernize-upgrade-audit`, `$opensrc`, `$opensrc-inspect`, `$technical-writing`, `$hard-cut`.",
"Use `$bun-dev` only when Bun is actually part of repo posture.",
"Use framework/plugin lanes only when explicitly relevant to the target repo.",
"Do not route this migration through `$imagegen`.",
],
"trigger_mission": f"Act as an architect-level modernization engineer performing a verification-first `{anchor_package}` upgrade in this repository.",
"trigger_goals": [
f"reach one canonical final end state for `{anchor_package}` usage",
"delete stale wrappers, shims, docs, and unnecessary related deps when justified",
"keep the diff reviewable and the final state simpler than the initial state",
],
"trigger_required_research": [
"inspect manifests, lockfiles, framework config, AGENTS/docs, and all package usage first",
"verify current package and framework guidance before editing",
"use official docs, upstream source, and repo-native commands",
"build a touched-files map before broad edits",
],
"trigger_required_decisions": [
"confirm the canonical final usage shape in this repo",
"decide which related packages are in or out of scope",
"decide which local wrappers or abstractions can be deleted",
],
"trigger_required_outcomes": [
"standardize on the verified final package usage shape",
"remove stale package usage patterns and unnecessary related dependencies",
"update repo policy/docs to match the final convention",
],
"trigger_required_deliverables": [
"findings matrix",
"decision log",
"affected-files map",
"migration checklist",
"exact verification commands",
"upgrade report",
"residual risks or explicit defer reasons",
],
"trigger_verification_expectation": [
"run lint, typecheck, tests, build, and audit",
"prove removed patterns and dependencies are gone with grep or equivalent checks",
],
}
def finalize_manifest(manifest: dict[str, Any]) -> dict[str, Any]:
"""Fill derived fields after override merge."""
basename = manifest["plan_basename"]
manifest["playbook_filename"] = f"{basename}-playbook.md"
manifest["trigger_filename"] = f"{basename}-trigger-prompt.md"
manifest["operator_filename"] = f"{basename}-operator-mode.md"
manifest["related_packages"] = unique_list(manifest["related_packages"])
manifest.setdefault("research_plan", {})
return manifest
def main() -> None:
args = build_parser().parse_args()
root = repo_path(args.repo_root)
repo_context = detect_repo_context(root)
override = match_override(args.anchor_package, Path(__file__))
family_slug = (
args.family_slug
or (override or {}).get("family_slug")
or normalize_slug(args.anchor_package)
)
manifest = generic_manifest(args.anchor_package, repo_context, family_slug)
if override:
manifest = recursive_merge(manifest, override)
manifest["repo_context"] = repo_context
for key in ("required_research", "execution_plan"):
if key in override:
manifest[key] = override[key]
manifest = finalize_manifest(manifest)
out_path = Path(args.out).expanduser().resolve()
out_path.parent.mkdir(parents=True, exist_ok=True)
dump_yaml(out_path, manifest)
print(out_path)
if __name__ == "__main__":
main()
#!/usr/bin/env python3
"""Detect repo package-manager and framework context for upgrade-pack generation."""
from __future__ import annotations
import argparse
import json
from common import detect_repo_context, repo_path
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--repo-root", required=True, help="Path to the target repo root.")
parser.add_argument("--json", action="store_true", help="Emit JSON instead of text.")
return parser
def main() -> None:
args = build_parser().parse_args()
context = detect_repo_context(repo_path(args.repo_root))
if args.json:
print(json.dumps(context, indent=2, sort_keys=False))
return
print(f"repo_root: {context['repo_root']}")
print(f"package_manager: {context['package_manager']}")
print(f"detected_by: {context['detected_by']}")
print(f"root_lockfiles: {', '.join(context['root_lockfiles']) or '(none)'}")
frameworks = ", ".join(context["frameworks_detected"]) or "(none)"
print(f"frameworks_detected: {frameworks}")
if __name__ == "__main__":
main()
#!/usr/bin/env python3
"""Semver-ish constraint helpers for upgrade-pack-generator."""
from __future__ import annotations
import re
from dataclasses import dataclass
from typing import Iterable
SEMVER_RE = re.compile(
r"^\s*v?(?P<major>\d+)(?:\.(?P<minor>\d+|x|\*))?(?:\.(?P<patch>\d+|x|\*))?(?:-(?P<prerelease>[0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?\s*$"
)
TOKEN_RE = re.compile(r"(>=|<=|>|<|=|\^|~)?\s*v?(\d+|x|\*)(?:\.(\d+|x|\*))?(?:\.(\d+|x|\*))?(?:-([0-9A-Za-z.-]+))?")
@dataclass(frozen=True, order=True)
class Semver:
"""Comparable semver tuple."""
major: int
minor: int
patch: int
prerelease: str = ""
@property
def is_prerelease(self) -> bool:
return bool(self.prerelease)
def parse_semver(raw: str | None) -> Semver | None:
"""Parse a semver-ish string into a comparable tuple."""
if not raw:
return None
match = SEMVER_RE.match(raw.strip())
if not match:
return None
major = int(match.group("major"))
minor_token = match.group("minor")
patch_token = match.group("patch")
if minor_token in {None, "x", "*"}:
minor = 0
else:
minor = int(minor_token)
if patch_token in {None, "x", "*"}:
patch = 0
else:
patch = int(patch_token)
return Semver(major=major, minor=minor, patch=patch, prerelease=match.group("prerelease") or "")
def _token_version(major: str, minor: str | None, patch: str | None, prerelease: str | None) -> tuple[Semver, bool, bool]:
wildcard_minor = minor in {None, "x", "*"}
wildcard_patch = patch in {None, "x", "*"}
return (
Semver(
major=int(major) if major not in {"x", "*"} else 0,
minor=0 if wildcard_minor else int(minor or 0),
patch=0 if wildcard_patch else int(patch or 0),
prerelease=prerelease or "",
),
wildcard_minor,
wildcard_patch,
)
def _bump_major(version: Semver) -> Semver:
return Semver(version.major + 1, 0, 0)
def _bump_minor(version: Semver) -> Semver:
return Semver(version.major, version.minor + 1, 0)
def _bump_patch(version: Semver) -> Semver:
return Semver(version.major, version.minor, version.patch + 1)
def _expand_token(operator: str | None, major: str, minor: str | None, patch: str | None, prerelease: str | None) -> list[tuple[str, Semver]]:
version, wildcard_minor, wildcard_patch = _token_version(major, minor, patch, prerelease)
op = operator or "="
if major in {"x", "*"}:
return []
if op == "^":
upper = _bump_major(version) if version.major > 0 else _bump_minor(version)
return [(">=", version), ("<", upper)]
if op == "~":
return [(">=", version), ("<", _bump_minor(version))]
if op == "=" and wildcard_minor:
return [(">=", version), ("<", _bump_major(version))]
if op == "=" and wildcard_patch:
return [(">=", version), ("<", _bump_minor(version))]
return [(op, version)]
def _iter_branch_constraints(branch: str) -> Iterable[list[tuple[str, Semver]]]:
tokens = TOKEN_RE.findall(branch)
if not tokens:
return []
expanded: list[tuple[str, Semver]] = []
for operator, major, minor, patch, prerelease in tokens:
expanded.extend(_expand_token(operator or None, major, minor or None, patch or None, prerelease or None))
return [expanded]
def compare(actual: Semver, operator: str, expected: Semver) -> bool:
"""Evaluate one comparator."""
if operator == "=":
return actual == expected
if operator == ">":
return actual > expected
if operator == ">=":
return actual >= expected
if operator == "<":
return actual < expected
if operator == "<=":
return actual <= expected
return False
def satisfies(actual_version: str | None, range_spec: str | None) -> bool | None:
"""Return whether a version satisfies a semver-ish range."""
if not range_spec or range_spec.strip() in {"*", "latest"}:
return True
actual = parse_semver(actual_version)
if actual is None:
return None
for branch in range_spec.split("||"):
branch = branch.strip()
if not branch:
continue
groups = list(_iter_branch_constraints(branch))
if not groups:
continue
for constraints in groups:
if all(compare(actual, operator, expected) for operator, expected in constraints):
return True
return False
def select_highest_stable(versions: list[str]) -> str | None:
"""Return the highest stable version from a list."""
parsed = [parse_semver(version) for version in versions]
stable = [
(version, semver)
for version, semver in zip(versions, parsed, strict=False)
if semver is not None and not semver.is_prerelease
]
if not stable:
return None
stable.sort(key=lambda item: item[1], reverse=True)
return stable[0][0]
#!/usr/bin/env python3
"""Sync and validate the bundled package source map."""
from __future__ import annotations
import argparse
import json
from pathlib import Path
from typing import Any
from common import bundled_source_map_path
REQUIRED_KEYS = (
"packageName",
"officialDocs",
"officialApiReference",
"officialGithubRepo",
"sourceConfidence",
"verifiedAt",
)
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--source",
help="Optional external package_source_map.json to copy into the bundled skill location.",
)
parser.add_argument(
"--skill-script",
default=__file__,
help="Any script path inside the upgrade-pack-generator skill; used to resolve the bundled destination.",
)
parser.add_argument(
"--check",
action="store_true",
help="Validate only; do not overwrite the bundled source map.",
)
return parser
def validate_payload(payload: Any) -> list[str]:
"""Return validation errors for a source-map payload."""
errors: list[str] = []
if not isinstance(payload, list) or not payload:
return ["source map must be a non-empty JSON list"]
for index, entry in enumerate(payload):
if not isinstance(entry, dict):
errors.append(f"entry {index} must be an object")
continue
for key in REQUIRED_KEYS:
value = entry.get(key)
if key in {"officialDocs", "officialApiReference"} and value is None:
errors.append(f"entry {index}.{key} must be a non-empty string")
continue
if not isinstance(value, str) or not value.strip():
errors.append(f"entry {index}.{key} must be a non-empty string")
return errors
def main() -> None:
args = build_parser().parse_args()
bundled_path = bundled_source_map_path(args.skill_script)
source_path = Path(args.source).expanduser().resolve() if args.source else bundled_path
payload = json.loads(source_path.read_text(encoding="utf-8"))
errors = validate_payload(payload)
if errors:
print("Source map validation failed:")
for error in errors:
print(f"- {error}")
raise SystemExit(1)
if not args.check and source_path != bundled_path:
bundled_path.parent.mkdir(parents=True, exist_ok=True)
bundled_path.write_text(
json.dumps(payload, indent=2, sort_keys=False) + "\n",
encoding="utf-8",
)
print(bundled_path)
if __name__ == "__main__":
main()
Related skills
FAQ
Does it implement the upgrade?
No. The generated pack is docs/research only, and you must not implement package changes while generating the pack.
Is it monorepo-aware?
Yes. It locks an explicit owner surface such as the repo root, one owning workspace, or repo root plus related workspaces.