Context
The current dedup modules (`engine/modules/{zinit_znap,asdf_mise,nvm_mise}_dedup.go`) handle the specific case devboost itself created: a tool devboost installed (znap, mise) now overlaps with a legacy tool (zinit, asdf, nvm) the user already had. Their entire mechanism is "detect the legacy tool's config line, comment it out in place, stay reversible and drift-aware." They do not look at what the legacy tool was configured to do — they just silence it.
The idea (from conversation, not yet scoped)
"if we ever change our choice of provider for let's say [starship], wouldn't we want to keep the user's customizations in say zinit? So should our now second-level 'dedup' actually be a first class citizen. So that we could migrate configs from similar apps and provide them back to the new choice. And it doesn't even have to be us who originally installed it. We just might have a better choice for the user."
This describes a genuinely different capability: when devboost swaps a user from tool A to tool B in the same category (any category — shell plugin manager, prompt, version manager, etc.), it should be able to:
- Detect A's existing user customizations (e.g. `zinit load user/plugin` lines, a prompt's custom segments/theme).
- Translate/port what's portable into B's equivalent config.
- Do this even when devboost didn't originally install A — A may predate devboost entirely.
This is a migration/config-porting concern, not a dedup concern. It would need real per-tool-pair parsers (not the current generic "match a line pattern, comment it out" mechanism), and a way to represent "categories" of interchangeable tools so devboost knows zinit and znap (or two prompt tools) are substitutes for one another in the first place.
Why not fold into the current dedup modules
The existing mechanism is deliberately minimal: pattern-match, comment out, snapshot, stay reversible. Bidirectional config translation is a materially bigger feature (parsing arbitrary user customizations, mapping semantics across tools that don't necessarily have 1:1 equivalents, handling partial/lossy translation) and shouldn't be scope-crept into today's simple mechanism.
Open questions for scoping later
- What counts as a "category" of interchangeable tool, and how is that declared (module metadata? explicit registry?).
- How much of a user's customization is realistically portable vs. tool-specific with no equivalent.
- Whether this should be opt-in/interactive-preview only (given devboost's zero-prompt principle, a lossy auto-migration of user customizations is risky) — possibly this always needs a
plan-style preview before ever touching anything.
- Whether this generalizes beyond devboost's own module swaps (i.e. porting configs between tools devboost never touched at all), per "it doesn't even have to be us who originally installed it."
No implementation yet — this is a design idea to scope when picked up.
Context
The current dedup modules (`engine/modules/{zinit_znap,asdf_mise,nvm_mise}_dedup.go`) handle the specific case devboost itself created: a tool devboost installed (znap, mise) now overlaps with a legacy tool (zinit, asdf, nvm) the user already had. Their entire mechanism is "detect the legacy tool's config line, comment it out in place, stay reversible and drift-aware." They do not look at what the legacy tool was configured to do — they just silence it.
The idea (from conversation, not yet scoped)
This describes a genuinely different capability: when devboost swaps a user from tool A to tool B in the same category (any category — shell plugin manager, prompt, version manager, etc.), it should be able to:
This is a migration/config-porting concern, not a dedup concern. It would need real per-tool-pair parsers (not the current generic "match a line pattern, comment it out" mechanism), and a way to represent "categories" of interchangeable tools so devboost knows zinit and znap (or two prompt tools) are substitutes for one another in the first place.
Why not fold into the current dedup modules
The existing mechanism is deliberately minimal: pattern-match, comment out, snapshot, stay reversible. Bidirectional config translation is a materially bigger feature (parsing arbitrary user customizations, mapping semantics across tools that don't necessarily have 1:1 equivalents, handling partial/lossy translation) and shouldn't be scope-crept into today's simple mechanism.
Open questions for scoping later
plan-style preview before ever touching anything.No implementation yet — this is a design idea to scope when picked up.