From 149cb2185975a13d0283c8107c05188327fad06f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roch=C3=A9=20Compaan?= Date: Tue, 16 Jun 2026 07:12:22 +0200 Subject: [PATCH 1/6] docs(npm): design package rename --- .../2026-06-16-npm-package-rename-design.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 docs/specs/2026-06-16-npm-package-rename-design.md diff --git a/docs/specs/2026-06-16-npm-package-rename-design.md b/docs/specs/2026-06-16-npm-package-rename-design.md new file mode 100644 index 0000000..46eb328 --- /dev/null +++ b/docs/specs/2026-06-16-npm-package-rename-design.md @@ -0,0 +1,65 @@ +# npm package rename design + +## Context + +Patchmill is currently published as `@rochecompaan/patchmill`. The CLI command +is already `patchmill`, and the Nix package uses the unscoped package name. The +npm package should move to the cleaner canonical package name `patchmill`. + +## Decision + +Publish future releases from this repository as the unscoped npm package +`patchmill`. + +The old scoped package, `@rochecompaan/patchmill`, will not be maintained as a +compatibility shim. After the first successful `patchmill` publish, it will be +deprecated on npm with a clear warning that tells users how to install the new +package. + +Recommended deprecation command after release: + +```sh +npm deprecate "@rochecompaan/patchmill@*" "Package renamed to patchmill. Install with: npm install -g patchmill or use: npx patchmill" +``` + +## Repository changes + +- Change `package.json` package name from `@rochecompaan/patchmill` to + `patchmill`. +- Refresh npm lock metadata so `package-lock.json` and `npm-shrinkwrap.json` + identify the root package as `patchmill`. +- Change Release Please package metadata from `@rochecompaan/patchmill` to + `patchmill`. +- Update README installation and `npx` examples to use `patchmill`. +- Add a short migration note in the README explaining that + `@rochecompaan/patchmill` is deprecated and users should install `patchmill` + instead. + +## Non-goals + +- Do not create or maintain a wrapper package for `@rochecompaan/patchmill`. +- Do not change the CLI binary name; it remains `patchmill`. +- Do not change Nix packaging beyond what is required by npm metadata, because + Nix already uses `patchmill` as its package name. + +## Release flow + +1. Merge the repository changes. +2. Let Release Please prepare and publish the next npm release as `patchmill`. +3. Confirm `npm install -g patchmill` and `npx patchmill` work. +4. Deprecate `@rochecompaan/patchmill` with the warning shown above. + +## Verification + +Use direct verification rather than new automated tests because this is +npm/release metadata and documentation, not reusable runtime behavior. + +Verification commands: + +- `npm install --package-lock-only --ignore-scripts` +- `npm run lint:md` +- `npm run build` +- `npm pack --dry-run` + +The dry-run pack should show package name `patchmill` and include the expected +files. From c7c02ba8f2a45cc5f8f8e72e7206ca8655472354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roch=C3=A9=20Compaan?= Date: Tue, 16 Jun 2026 07:17:38 +0200 Subject: [PATCH 2/6] docs(npm): plan package rename --- docs/plans/2026-06-16-npm-package-rename.md | 357 ++++++++++++++++++++ 1 file changed, 357 insertions(+) create mode 100644 docs/plans/2026-06-16-npm-package-rename.md diff --git a/docs/plans/2026-06-16-npm-package-rename.md b/docs/plans/2026-06-16-npm-package-rename.md new file mode 100644 index 0000000..da4b669 --- /dev/null +++ b/docs/plans/2026-06-16-npm-package-rename.md @@ -0,0 +1,357 @@ +# npm Package Rename Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use +> superpowers:subagent-driven-development (recommended) or +> superpowers:executing-plans to implement this plan task-by-task. Steps use +> checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Rename the canonical npm package from `@rochecompaan/patchmill` to +`patchmill` and document deprecation of the old scoped package. + +**Architecture:** This is a package metadata and documentation migration. The +repository continues to build and publish the same CLI binary, `patchmill`, +while npm metadata and user-facing installation instructions switch to the +unscoped package name. + +**Tech Stack:** npm package metadata, npm lockfiles, Release Please, Markdown +documentation, TypeScript build verification. + +--- + +## File structure + +- Modify: `package.json` + - Responsibility: declares the canonical npm package name and existing CLI + binary mapping. +- Modify: `package-lock.json` + - Responsibility: records root package metadata for local installs. +- Modify: `npm-shrinkwrap.json` + - Responsibility: records publish-time locked dependencies and root package + metadata. +- Modify: `release-please-config.json` + - Responsibility: tells Release Please which package name to use for releases. +- Modify: `README.md` + - Responsibility: documents canonical install and `npx` usage plus migration + guidance from the deprecated scoped package. +- No new runtime source files. +- No new automated tests because this changes package metadata and + documentation, not reusable runtime behavior. Use direct verification commands + in Task 3. + +## Implementation tasks + +### Task 1: Rename npm package metadata and lockfile roots + +**Files:** + +- Modify: `package.json` +- Modify: `package-lock.json` +- Modify: `npm-shrinkwrap.json` + +- [ ] **Step 1: Confirm the unscoped npm name is still available** + + Run: + + ```bash + npm view patchmill name version --json + ``` + + Expected: command exits non-zero with npm `E404` / `Not Found`. Treat that as + success because it means no public `patchmill` package currently exists. + + If this command returns package metadata instead of `E404`, stop and report + the collision before editing files. + +- [ ] **Step 2: Change the root package name in `package.json`** + + Run: + + ```bash + npm pkg set name=patchmill + ``` + + Expected: `package.json` changes from: + + ```json + "name": "@rochecompaan/patchmill" + ``` + + to: + + ```json + "name": "patchmill" + ``` + +- [ ] **Step 3: Refresh `package-lock.json` despite the shrinkwrap file** + + npm updates `npm-shrinkwrap.json` instead of `package-lock.json` when a + shrinkwrap file is present. Temporarily move the shrinkwrap aside so npm + refreshes `package-lock.json` from the updated `package.json`. + + Run: + + ```bash + mv npm-shrinkwrap.json npm-shrinkwrap.json.bak + npm install --package-lock-only --ignore-scripts + mv npm-shrinkwrap.json.bak npm-shrinkwrap.json + ``` + + Expected: `package-lock.json` root metadata now uses `patchmill`. + +- [ ] **Step 4: Refresh `npm-shrinkwrap.json`** + + Run: + + ```bash + npm install --package-lock-only --ignore-scripts + ``` + + Expected: `npm-shrinkwrap.json` root metadata now uses `patchmill`. + +- [ ] **Step 5: Verify both lockfiles name the root package consistently** + + Run: + + ```bash + node <<'NODE' + const fs = require('node:fs'); + + for (const file of ['package.json', 'package-lock.json', 'npm-shrinkwrap.json']) { + const data = JSON.parse(fs.readFileSync(file, 'utf8')); + const rootName = data.packages?.['']?.name ?? data.name; + + console.log(`${file}: name=${data.name}; rootName=${rootName}`); + + if (data.name !== 'patchmill') { + throw new Error(`${file} top-level name is ${data.name}`); + } + + if (file !== 'package.json' && rootName !== 'patchmill') { + throw new Error(`${file} root package name is ${rootName}`); + } + } + NODE + ``` + + Expected output: + + ```text + package.json: name=patchmill; rootName=patchmill + package-lock.json: name=patchmill; rootName=patchmill + npm-shrinkwrap.json: name=patchmill; rootName=patchmill + ``` + +- [ ] **Step 6: Review the metadata diff** + + Run: + + ```bash + git diff -- package.json package-lock.json npm-shrinkwrap.json + ``` + + Expected: only root package name metadata changes from + `@rochecompaan/patchmill` to `patchmill`; dependencies and CLI `bin` mapping + remain unchanged. + +- [ ] **Step 7: Commit the metadata rename** + + Run: + + ```bash + git add package.json package-lock.json npm-shrinkwrap.json + git commit -m "chore(npm): rename package to patchmill" + ``` + + Expected: commit succeeds. + +### Task 2: Update Release Please and README migration guidance + +**Files:** + +- Modify: `release-please-config.json` +- Modify: `README.md` + +- [ ] **Step 1: Update Release Please package name** + + In `release-please-config.json`, change: + + ```json + "package-name": "@rochecompaan/patchmill" + ``` + + to: + + ```json + "package-name": "patchmill" + ``` + + Expected: Release Please will prepare future releases for the unscoped npm + package. + +- [ ] **Step 2: Update the global install quickstart** + + In `README.md`, replace the current global install block: + + ````markdown + Install the Patchmill CLI globally, then start with the onboarding flow: + + ```sh + npm install -g @rochecompaan/patchmill + + patchmill init + patchmill doctor + patchmill triage --dry-run + ``` + ```` + + with: + + ````markdown + Install the Patchmill CLI globally, then start with the onboarding flow: + + ```sh + npm install -g patchmill + + patchmill init + patchmill doctor + patchmill triage --dry-run + ``` + ```` + +- [ ] **Step 3: Update the `npx` quickstart** + + In `README.md`, replace the current `npx` paragraph and block: + + ````markdown + If you prefer not to install Patchmill globally, use the scoped package name + with `npx`: + + ```sh + npx @rochecompaan/patchmill init + npx @rochecompaan/patchmill doctor + npx @rochecompaan/patchmill triage --dry-run + ``` + ```` + + with: + + ````markdown + If you prefer not to install Patchmill globally, use `npx`: + + ```sh + npx patchmill init + npx patchmill doctor + npx patchmill triage --dry-run + ``` + ```` + +- [ ] **Step 4: Add migration guidance for the deprecated scoped package** + + Immediately after the `npx` quickstart block in `README.md`, add: + + ````markdown + ### Migrating from `@rochecompaan/patchmill` + + The scoped npm package `@rochecompaan/patchmill` is deprecated. Install the + unscoped package instead: + + ```sh + npm uninstall -g @rochecompaan/patchmill + npm install -g patchmill + ``` + + For one-off usage, replace `npx @rochecompaan/patchmill ...` with + `npx patchmill ...`. + ```` + +- [ ] **Step 5: Review all remaining scoped package references** + + Run: + + ```bash + rg -n "@rochecompaan/patchmill" README.md package.json package-lock.json npm-shrinkwrap.json release-please-config.json docs + ``` + + Expected: the only remaining matches are intentional migration/deprecation + references in `README.md` and the already-approved spec at + `docs/specs/2026-06-16-npm-package-rename-design.md`. + +- [ ] **Step 6: Commit the release and documentation updates** + + Run: + + ```bash + git add release-please-config.json README.md + git commit -m "docs(npm): document patchmill package install" + ``` + + Expected: commit succeeds. + +### Task 3: Verify package metadata, docs, build, and pack output + +**Files:** + +- Read/verify: `package.json` +- Read/verify: `package-lock.json` +- Read/verify: `npm-shrinkwrap.json` +- Read/verify: `README.md` +- Read/verify: `release-please-config.json` +- Read/verify: generated dry-run pack output only + +- [ ] **Step 1: Run Markdown lint for documentation changes** + + Run: + + ```bash + npm run lint:md + ``` + + Expected: command exits 0. + +- [ ] **Step 2: Run the TypeScript build** + + Run: + + ```bash + npm run build + ``` + + Expected: command exits 0 and regenerates `dist/` from the current source. + +- [ ] **Step 3: Run npm pack dry-run** + + Run: + + ```bash + npm pack --dry-run + ``` + + Expected: output contains `patchmill@0.12.0`, includes + `dist/bin/patchmill.js`, and does not report `@rochecompaan/patchmill` as the + package being packed. + +- [ ] **Step 4: Review final git diff and status** + + Run: + + ```bash + git status --short + git diff --stat HEAD~2..HEAD + ``` + + Expected: working tree is clean except for any generated `dist/` changes from + `npm run build`. If `dist/` changed, inspect it with `git diff -- dist` and + commit only if the build output legitimately changed due to the metadata + rename. + +- [ ] **Step 5: Record post-release npm deprecation command for the maintainer** + + In the final implementation summary, include this command for after the first + successful `patchmill` release: + + ```bash + npm deprecate "@rochecompaan/patchmill@*" "Package renamed to patchmill. Install with: npm install -g patchmill or use: npx patchmill" + ``` + + Expected: the command is not run during implementation because it should + happen only after the new `patchmill` package has been published successfully. From 801dac43c4be309fdf6d9aa2333ca6b87e9a3d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roch=C3=A9=20Compaan?= Date: Tue, 16 Jun 2026 07:36:58 +0200 Subject: [PATCH 3/6] chore(npm): rename package to patchmill --- npm-shrinkwrap.json | 4 ++-- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index a386042..13a3f09 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,11 +1,11 @@ { - "name": "@rochecompaan/patchmill", + "name": "patchmill", "version": "0.12.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@rochecompaan/patchmill", + "name": "patchmill", "version": "0.12.0", "license": "Apache-2.0", "dependencies": { diff --git a/package-lock.json b/package-lock.json index e24b418..efbb741 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "@rochecompaan/patchmill", + "name": "patchmill", "version": "0.12.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@rochecompaan/patchmill", + "name": "patchmill", "version": "0.12.0", "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 09b6d1e..6941a50 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "@rochecompaan/patchmill", + "name": "patchmill", "version": "0.12.0", "private": false, "publishConfig": { From 226801f23f2c82e1e5440811ac6f9f95d0bfa157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roch=C3=A9=20Compaan?= Date: Tue, 16 Jun 2026 07:37:57 +0200 Subject: [PATCH 4/6] docs(npm): document patchmill package install --- README.md | 24 ++++++++++++++++++------ release-please-config.json | 2 +- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 7b6fd05..1474618 100644 --- a/README.md +++ b/README.md @@ -66,22 +66,34 @@ the first `github-gh` version; Forgejo visual-evidence upload uses the Install the Patchmill CLI globally, then start with the onboarding flow: ```sh -npm install -g @rochecompaan/patchmill +npm install -g patchmill patchmill init patchmill doctor patchmill triage --dry-run ``` -If you prefer not to install Patchmill globally, use the scoped package name -with `npx`: +If you prefer not to install Patchmill globally, use `npx`: ```sh -npx @rochecompaan/patchmill init -npx @rochecompaan/patchmill doctor -npx @rochecompaan/patchmill triage --dry-run +npx patchmill init +npx patchmill doctor +npx patchmill triage --dry-run ``` +### Migrating from `@rochecompaan/patchmill` + +The scoped npm package `@rochecompaan/patchmill` is deprecated. Install the +unscoped package instead: + +```sh +npm uninstall -g @rochecompaan/patchmill +npm install -g patchmill +``` + +For one-off usage, replace `npx @rochecompaan/patchmill ...` with +`npx patchmill ...`. + ### Try Patchmill on a disposable demo repository Before pointing Patchmill at a production repository, create a disposable Team diff --git a/release-please-config.json b/release-please-config.json index 4f63853..544d7c4 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -2,7 +2,7 @@ "packages": { ".": { "release-type": "node", - "package-name": "@rochecompaan/patchmill", + "package-name": "patchmill", "include-component-in-tag": false, "extra-files": [ { From 8f5f7d51ca2d81c40dffa9f36bb247032719495e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roch=C3=A9=20Compaan?= Date: Tue, 16 Jun 2026 07:38:51 +0200 Subject: [PATCH 5/6] test(npm): expect patchmill release package --- bin/release-config.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/release-config.test.ts b/bin/release-config.test.ts index 4f6118b..bb0d751 100644 --- a/bin/release-config.test.ts +++ b/bin/release-config.test.ts @@ -35,7 +35,7 @@ test("release-please config manages the root node package and Nix version", () = assert.deepEqual(config.packages?.["."], { "release-type": "node", - "package-name": "@rochecompaan/patchmill", + "package-name": "patchmill", "include-component-in-tag": false, "extra-files": [{ type: "generic", path: "nix/package.nix" }], }); From 15e69215de8b53d4518453d93b0e62dd8f1ada08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roch=C3=A9=20Compaan?= Date: Tue, 16 Jun 2026 08:19:38 +0200 Subject: [PATCH 6/6] fix(nix): use renamed npm package path --- nix/package.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nix/package.nix b/nix/package.nix index 5d2927d..2e76a66 100644 --- a/nix/package.nix +++ b/nix/package.nix @@ -25,7 +25,7 @@ buildNpmPackageNode24 rec { || baseName == "result"); }; - npmDepsHash = "sha256-3MlGzlwzuntPCK7cFjRnZsdiz79H3oL6PTwHpkKI6wM="; + npmDepsHash = "sha256-lnLDh+1JrACIf7QDxejIQj9Rb9jCSLNa5HYr3EfUKz8="; npmDepsFetcherVersion = 2; dontNpmBuild = true; @@ -44,7 +44,7 @@ buildNpmPackageNode24 rec { ''; postInstall = '' - package_dir="$out/lib/node_modules/@rochecompaan/${pname}" + package_dir="$out/lib/node_modules/${pname}" mkdir -p "$out/share/${pname}" cp -R "$package_dir/bin" "$out/share/${pname}/bin"