Skip to content

packkit upgrade — keep a scaffolded project current - #23

Merged
DanMat merged 1 commit into
mainfrom
feat/packkit-upgrade
Jul 26, 2026
Merged

packkit upgrade — keep a scaffolded project current#23
DanMat merged 1 commit into
mainfrom
feat/packkit-upgrade

Conversation

@DanMat

@DanMat DanMat commented Jul 26, 2026

Copy link
Copy Markdown
Owner

The headline both reviews independently landed on, and the reason 2.9 shipped the packkit.json provenance file. A scaffolded project now has a durable relationship with Packkit: it can be pulled up to the current templates instead of drifting.

npx create-packkit upgrade          # dry run — what changed since you scaffolded
npx create-packkit upgrade --apply  # add new files, bump deps, keep your edits
npx create-packkit upgrade --force  # also overwrite files that differ

How it works

Reads packkit.json (preset + settings) and the name from package.json, regenerates the current recommended output in memory through the embedded API, and diffs it against disk. Reconstruction is faithful — verified byte-for-byte across every preset type (ts-lib, node-service, react-app, oss, fullstack).

It classifies each difference:

  • new files Packkit now generates,
  • added / bumped dependencies (tracked per section),
  • new / changed scripts,
  • files that differ — a template change or the user's own edit. Without a stored baseline it can't tell which, so these are surfaced for review and never auto-overwritten.

--apply brings in the safe changes and merges package.json so bumps and new deps/scripts land while the user's own deps, scripts, and field ordering survive. packkit.json is refreshed. Differing files are left untouched unless --force.

Layering

The decision logic — planUpgrade, buildUpgradeWrite, isUpgradeEmpty — is a pure, exported part of the embedded API and is unit-tested. The CLI just reads disk and formats the report. Consistent with the architecture: the engine is shared, the CLI is an adapter.

Verified end to end

Scaffolded a project, then simulated drift — deleted .editorconfig, removed vitest, downgraded tsup to ^7, added a custom script, edited the README:

Packkit 2.0.0 → 3.0.0
New files (1): .editorconfig
New dependencies (1): vitest@^4.0.0 (devDependencies)
Dependency updates (1): tsup: ^7.0.0 → ^8.0.0
Files that differ — review before overwriting (1): README.md

--apply: file restored, dep re-added, tsup bumped, the custom script preserved, the edited README left alone; packkit.json refreshed to 3.0.0. --force then overwrites the README.

94 tests pass (5 new). No core change, so the web bundle is untouched.

Follow-up (roadmap): per-file baseline hashes in packkit.json would let it distinguish "user edited" from "template changed" precisely, instead of surfacing all differing files for review.

🤖 Generated with Claude Code

The headline follow-up both reviews independently landed on, and the reason
2.9 added the packkit.json provenance file. A project scaffolded by Packkit
now has a durable relationship with the tool: it can be pulled up to the
current templates instead of drifting.

  npx create-packkit upgrade          # dry run — what changed since scaffold
  npx create-packkit upgrade --apply  # add new files, bump deps, keep edits
  npx create-packkit upgrade --force  # also overwrite files that differ

How it works: reads packkit.json (preset + settings) and the name from
package.json, regenerates the current recommended output in memory through
the embedded API, and diffs it against disk. Reconstruction is faithful —
verified byte-for-byte across every preset type. It classifies:
- new files Packkit now generates,
- added and bumped dependencies (per section),
- new and changed scripts,
- files that differ (a template change or the user's own edit — can't tell
  without a stored baseline, so surfaced for review, never auto-overwritten).

--apply brings in the safe changes and merges package.json so bumps and new
deps/scripts land while the user's own deps, scripts, and field order survive.
packkit.json is refreshed to the new version. Files that differ are listed and
left untouched unless --force.

The decision logic (planUpgrade / buildUpgradeWrite / isUpgradeEmpty) is a
pure, exported part of the embedded API and is unit-tested; the CLI reads
disk and formats the report. 94 tests pass (5 new), verified end to end:
deleted file re-added, removed dep restored, tsup ^7→^8 bumped, a user script
preserved, an edited README left alone (then overwritten under --force).

Follow-up noted in the roadmap: per-file baseline hashes in packkit.json would
let it tell "user edited" from "template changed" precisely.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@DanMat
DanMat merged commit ce06c43 into main Jul 26, 2026
5 checks passed
@DanMat
DanMat deleted the feat/packkit-upgrade branch July 26, 2026 20:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant