diff --git a/docs/superpowers/specs/2026-05-25-unified-dist-distribution-design.md b/docs/superpowers/specs/2026-05-25-unified-dist-distribution-design.md new file mode 100644 index 0000000..b49d51f --- /dev/null +++ b/docs/superpowers/specs/2026-05-25-unified-dist-distribution-design.md @@ -0,0 +1,122 @@ +# Unified Dist Distribution Design + +## Goal + +Make first-time installation and later updates use the exact same extension directory structure so coworkers never need to learn different paths or loading rules. + +## Confirmed Direction + +- The only user-facing unpacked extension directory should be `dist/`. +- First install and later update must produce the same directory name and shape. +- Coworkers should always load the same directory in `chrome://extensions`. + +## Problem + +The current delivery flow has created multiple mental models: + +- sometimes coworkers are told to load `dist-release/` +- sometimes the ZIP extracts to a differently named top-level folder +- sometimes Git-based installation and ZIP-based installation do not look identical + +This is not user-friendly and increases support cost. + +## Scope + +This change standardizes the user-facing extension directory across: + +- local release builds +- ZIP packaging +- Git-based teammate installation +- later update downloads +- installation and update documentation + +This change does not alter: + +- extension runtime behavior +- update-check logic itself +- popup auth flow +- COS manifest format + +## Distribution Rule + +There must be exactly one user-facing extension directory: + +- `dist/` + +This rule must hold in all paths: + +1. Git install + - teammate runs the release build + - resulting unpacked extension directory is `dist/` +2. ZIP install + - teammate unzips the package + - resulting top-level extension directory is `dist/` +3. ZIP update + - teammate downloads the newer ZIP + - unzip result is also `dist/` + - teammate replaces the previous `dist/` + +## Packaging Rule + +The release ZIP should unpack into a single top-level folder named `dist/`. + +Expected unpack result: + +- `dist/manifest.json` +- `dist/background/` +- `dist/content/` +- `dist/popup/` +- `dist/assets/` + +The ZIP must not unpack as: + +- a flat file list +- `dist-release/` +- `star-chart-search-enhancer-internal/` +- any other user-facing top-level folder name + +## Build Rule + +Release builds should write the unpacked extension directly to `dist/`. + +There should not be a second extension build directory that teammates might mistake as the correct one. + +If internal scripts need a concept of “release build,” that should be represented by: + +- environment/config +- release manifest values +- packaging flow + +but not by exposing a second unpacked directory name to users. + +## Documentation Rule + +All teammate-facing docs must say the same thing: + +- first install: load `dist/` +- later update: replace `dist/` and reload + +No user-facing doc should mention `dist-release/`. + +## CI / Release Rule + +Drone and local release scripts must publish only one ZIP layout: + +- unzip result is `dist/` + +The release flow must not generate a user ZIP whose folder layout differs from the Git-based install path. + +## Acceptance Criteria + +- `npm run build:release` writes the unpacked extension to `dist/` +- release ZIP unpacks into a top-level `dist/` folder +- first install and later update ZIPs unpack to the same structure +- coworker docs consistently reference `dist/` +- repository no longer contains a second tracked unpacked extension directory that conflicts with `dist/` + +## Out of Scope + +- changing extension features +- changing the update notification UX +- switching away from unpacked-extension installation +- Chrome Web Store or enterprise force-install deployment