Upgrade Pack Generator
Generate upgrade-pack folders for dependency families in two stages:
- Author or refine a reusable family override.
- 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
Read references/workflow.md.
Decide the mode:
- family authoring
- repo instantiation
Detect repo context first:
python3 scripts/detect_repo_context.py --repo-root /path/to/repo --jsonBootstrap a manifest from the anchor package:
python3 scripts/bootstrap_manifest.py \ --repo-root /path/to/repo \ --anchor-package lucide-react \ --out /tmp/upgrade-pack.yamlEnrich the manifest with live repo probes and official upstream guidance:
python3 scripts/enrich_manifest.py --manifest /tmp/upgrade-pack.yamlRefine the enriched manifest further with live research when needed:
$repo-modernizer$opensrc$technical-writing$hard-cut
Validate the manifest:
python3 scripts/validate_upgrade_pack.py /tmp/upgrade-pack.yamlRun read-only research:
python3 scripts/research_upgrade_pack.py --manifest /tmp/upgrade-pack.yamlRun the mandatory
web.runconfirmation pass for required official docs and API-reference pages fromresearch-bundle.jsonand record the results inweb-research-findings.json.Re-run read-only research so the snapshot reflects the confirmed official pages:
python3 scripts/research_upgrade_pack.py --manifest /tmp/upgrade-pack.yamlRun read-only qualification:
python3 scripts/qualify_upgrade_pack.py --manifest /tmp/upgrade-pack.yamlRender 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:
package.json#packageManager- root lockfiles
- 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
- creates a starter
scripts/enrich_manifest.py- enriches
upgrade-pack.yamlwith family-specific repo probes, current package versions, and live official-doc snapshots
- enriches
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.runqueue intoresearch-snapshot.jsonplusresearch-bundle.json
- 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
scripts/sync_source_map.py- validates or refreshes the bundled package source-map under
references/source-maps/
- validates or refreshes the bundled package source-map under
scripts/qualify_upgrade_pack.py- runs family-native read-only qualification and writes
qualification-snapshot.json
- runs family-native read-only qualification and writes
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.yaml
Render 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/commander
Refresh 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-react