@dennisrepa/elevate 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/de.md CHANGED
@@ -19,8 +19,9 @@
19
19
 
20
20
  ## ✨ Features & Highlights
21
21
 
22
- 1. **🌐 Polyglot Monorepo Support (npm & Maven):**
22
+ 1. **🌐 Polyglot Monorepo Support (npm, pnpm & Maven):**
23
23
  * **Node / npm:** Löst Workspaces genau wie npm auf (inklusive Glob-Mustern wie `packages/**`), berechnet SemVer-Diffs, aktualisiert `package.json`, führt `npm install` aus und prüft das Lockfile.
24
+ * **Node / pnpm** (9 – 12): Dasselbe für pnpm-Repositories — Workspaces aus `pnpm-workspace.yaml`, das `workspace:`-Protokoll, `catalog:`-Einträge, `pnpm install` und eine Lockfile-Prüfung. Repositories mit Yarn oder Bun werden abgelehnt.
24
25
  * **Java / Maven:** Findet jede `pom.xml` (auch die Root-POM), lässt Maven die Effective POM berechnen, sucht neuere Versionen über die Repositories des Builds (Mirrors, Nexus/Artifactory, Zugangsdaten aus der `settings.xml`) und prüft die betroffenen Module mit `mvn test-compile`.
25
26
  * **Live-Wechsel:** Ein Tastendruck auf **`[E]`** schaltet im laufenden Betrieb zwischen Frontend- und Backend-Modulen um.
26
27
 
@@ -68,6 +69,7 @@ Die URL der Registry allein entscheidet bewusst **nicht** über die Herkunft: In
68
69
  ### Workspace-Module angleichen
69
70
 
70
71
  * **npm:** Schließt der Versionsbereich einer Abhängigkeit die lokale Version eines Workspace-Pakets nicht ein, verlinkt npm das Workspace **nicht**, sondern installiert ein gleichnamiges Paket aus der Registry. Elevate bietet an, den Bereich anzugleichen (z. B. `^1.0.0` ➔ `^2.0.0`). Nach `npm install` prüft es die `package-lock.json`: Jede angeglichene Abhängigkeit muss `"link": true` sein, sonst wird das Update zurückgenommen. Bereiche, die npm immer verlinkt (`*`, `file:`, `workspace:`), bleiben unberührt.
72
+ * **pnpm:** pnpm verlinkt ein Workspace-Paket nur, wenn die Abhängigkeit mit dem `workspace:`-Protokoll geschrieben ist; ein einfacher Bereich wie `^1.0.0` wird aus der Registry aufgelöst — auch wenn die lokale Version ihn erfüllt. Elevate gleicht deshalb `workspace:^1.2.0` ➔ `workspace:^2.0.0` an (Protokoll und Präfix bleiben; `workspace:*`, `workspace:^`, `workspace:~` und `workspace:../lib` brauchen nichts) und führt einen einfachen Bereich auf ein Modul als *nicht verlinkt* (`not-linked`) auf, ohne den Namen je in einer Registry nachzuschlagen oder den Bereich umzuschreiben. Nach `pnpm install` liest es den Abschnitt `importers` der `pnpm-lock.yaml` (`lockfileVersion` 9.x): Jede angeglichene Abhängigkeit muss eine `version` mit `link:` haben, sonst wird das Update zurückgenommen.
71
73
  * **Maven:** Hängt ein Modul mit abweichender Version von einem Modul *desselben Reactors* ab (z. B. `1.0.0`, während das Modul auf `1.1.0-SNAPSHOT` steht), bietet Elevate das Angleichen an. Verweise über `${project.version}` brauchen kein Angleichen.
72
74
  * Der Release Channel gilt beim Angleichen nicht: Ziel ist die lokale Version — auch `-SNAPSHOT` —, weil die Module eines Repositorys zusammen gebaut und getestet werden.
73
75
 
@@ -103,9 +105,31 @@ Elevate verhält sich gleich, egal wo im Repository es gestartet wird. Der Root
103
105
 
104
106
  Die Suche verlässt nie den Checkout der Versionsverwaltung: Sie endet im nächsten Verzeichnis, das einen `.git`-Eintrag enthält. Eine verirrte `package.json` oder `pom.xml` oberhalb des Repositorys wird daher nie für dessen Root gehalten. Manifeste, die sich nicht lesen lassen, werden übersprungen.
105
107
 
106
- ### Paketmanager-Schutz (npm)
108
+ ### Paketmanager-Schutz (Yarn und Bun)
107
109
 
108
- Elevates Node.js-Unterstützung steuert npm. In einem Repository, das pnpm, Yarn oder Bun verwaltet, weigert sich Elevate, die npm-Module zu scannen oder zu ändern, denn `npm install` würde ein zweites Lockfile und ein `node_modules`-Layout anlegen, das das Projekt nicht verwendet. Der Paketmanager wird am Repository-Root in dieser Reihenfolge erkannt: Feld `packageManager` der `package.json` (`npm@`, `pnpm@`, `yarn@`, `bun@`), dann `package-lock.json` / `npm-shrinkwrap.json`, `pnpm-lock.yaml` / `pnpm-workspace.yaml`, `yarn.lock` / `.yarnrc.yml`, `bun.lock` / `bun.lockb`; ohne eines davon gilt das Repository als npm. Startet Elevate in einem Workspace-Paket, läuft die Suche in den übergeordneten Verzeichnissen weiter bis zum Checkout (nächstes Verzeichnis mit `.git`-Eintrag); ohne Checkout wird nur das Verzeichnis selbst geprüft. Die Ablehnung nennt den Paketmanager und die Datei, die entschieden hat. Maven-Module im selben Repository, lesende Versionsabfragen (`elevate versions`) und ein eigenes `postUpdateScript` bleiben unberührt.
110
+ Elevate unterstützt für Node.js npm und pnpm. In einem Repository, das Yarn oder Bun verwaltet, verweigert es Scan und Änderungen, weil jedes der beiden Werkzeuge ein zweites Lockfile und ein `node_modules`-Layout anlegen würde, das das Projekt nicht nutzt. Der Paketmanager wird vom Repository-Root aus erkannt, in dieser Reihenfolge: Feld `packageManager` der `package.json` (`npm@`, `pnpm@`, `yarn@`, `bun@`), dann `package-lock.json` / `npm-shrinkwrap.json`, `pnpm-lock.yaml` / `pnpm-workspace.yaml`, `yarn.lock` / `.yarnrc.yml`, `bun.lock` / `bun.lockb`; ohne Treffer gilt das Repository als npm. Startet Elevate innerhalb eines Workspace-Pakets, wird in den übergeordneten Verzeichnissen bis zum Checkout (nächstes Verzeichnis mit `.git`) weitergesucht. Die Ablehnung nennt den Paketmanager und die entscheidende Datei. Maven-Module im selben Repository, lesende Versionsabfragen (`elevate versions`) und ein eigenes `postUpdateScript` sind nicht betroffen.
111
+
112
+ ### pnpm-Workspaces und Catalogs
113
+
114
+ * **Workspace-Datei.** In einem pnpm-Repository bestimmt die Liste `packages` der `pnpm-workspace.yaml` (nicht das Feld `workspaces` der `package.json`) die Module; Muster mit `*`, `**` und `!` funktionieren wie bei npm, der Root ist immer ein Modul, `node_modules` enthält nie Module. Eine `pnpm-workspace.yaml` markiert auch den Repository-Root, selbst ohne `packages`. Eine Datei, die kein gültiges YAML ist, gilt als nicht vorhanden.
115
+ * **Catalogs.** Eine Abhängigkeit mit `catalog:` / `catalog:default` / `catalog:<name>` wird mit dem Bereich aus dem Catalog angeboten; der neue Bereich wird in genau diesen Eintrag der `pnpm-workspace.yaml` geschrieben (Kommentare, Anführungszeichen, Schreibweise und Zeilenenden bleiben; die `package.json` des Moduls wird nicht umgeschrieben). Eine nicht auflösbare Referenz erscheint als `catalog-unresolved`. Die JSON-Ausgabe nennt den Ort: `"declaredIn": {"file": "pnpm-workspace.yaml", "kind": "catalog", "catalog": "default"}`.
116
+ * **Overrides** (`pnpm.overrides`, `overrides` in der `pnpm-workspace.yaml`, `resolutions`) und `peerDependencies` werden nie geändert.
117
+
118
+ ### Befehle, die Elevate für pnpm ausführt
119
+
120
+ Alle im Repository-Root mit dem `pnpm` aus dem `PATH` (Version über `packageManager`/Corepack). Zuerst läuft `pnpm --version`; scheitert es, bricht die Operation mit einer Erklärung ab, bevor etwas verändert wird.
121
+
122
+ | Zweck | Befehl | Timeout |
123
+ | :--- | :--- | :--- |
124
+ | pnpm benutzbar? | `pnpm --version` | 15 s |
125
+ | Installation nach dem Schreiben der Bereiche | `pnpm install --no-frozen-lockfile` | 10 min |
126
+ | Wiederherstellung nach Rollback | `pnpm install --frozen-lockfile` | 10 min |
127
+ | Standard-Verifikation (Lockfile-Konsistenz, ersetzt `npm ls`) | `pnpm install --frozen-lockfile --lockfile-only` | 10 min |
128
+ | Schwachstellen-Zusammenfassung | `pnpm audit --json` | 60 s |
129
+ | Versionen eines Pakets | `pnpm view <name> <field> --json` | 15 s |
130
+ | Registry-Konfiguration | `pnpm config list --json` | 15 s |
131
+
132
+ `--no-frozen-lockfile` wird ausdrücklich übergeben, weil `pnpm install` bei gesetztem `CI` implizit eingefroren ist und am gerade geänderten Manifest scheitern würde. `pnpm ls` taugt nicht zur Verifikation: Es endet auch bei fehlenden Abhängigkeiten mit 0. Die Schwachstellen-Zusammenfassung stammt aus `pnpm audit --json`; ein Audit ohne Ergebnis ist eine Warnung, nie ein Grund für ein Rollback. pnpm-Einstellungen wie `minimumReleaseAge` oder die Freigabe von Build-Skripten liest Elevate nicht; lehnt pnpm deshalb ab, wird mit pnpms eigener Meldung zurückgenommen.
109
133
 
110
134
  ### Abhängigkeitsbereiche (npm)
111
135
 
@@ -153,6 +177,11 @@ src/
153
177
  │ │ ├── npm-registry.ts # npm-view-Abfragen & Dist-Tags
154
178
  │ │ ├── npm-scanner.ts # Herkunft, Angleichen, SemVer-Diffs
155
179
  │ │ ├── npm-lockfile.ts # Prüfung der Workspace-Verlinkung im Lockfile
180
+ │ │ ├── npm-commands.ts # Befehle je Paketmanager (npm / pnpm)
181
+ │ │ ├── npm-protocols.ts # Bereichs-Protokolle workspace: / catalog:
182
+ │ │ ├── pnpm-workspace.ts # pnpm-workspace.yaml: Pakete, Catalogs, Änderung an Ort und Stelle
183
+ │ │ ├── pnpm-lockfile.ts # Verlinkungsprüfung in der pnpm-lock.yaml
184
+ │ │ ├── pnpm-audit.ts # Zusammenfassung von pnpm audit --json
156
185
  │ │ ├── npm-updater.ts # Aktualisiert package.json & npm install
157
186
  │ │ ├── npm-verifier.ts # npm ls / eigene Verifikation
158
187
  │ │ └── npm-strategy.ts # NpmEcosystemStrategy
package/docs/en.md CHANGED
@@ -19,8 +19,8 @@
19
19
 
20
20
  ## ✨ Features & Highlights
21
21
 
22
- 1. **🌐 Polyglot Monorepo Support (npm & Maven):**
23
- * **Node / npm:** Resolves workspaces exactly like npm (glob patterns such as `packages/**` included), calculates SemVer diffs, updates `package.json` (`dependencies`, `devDependencies`, `optionalDependencies`), runs `npm install` and checks the lockfile. Repositories managed by pnpm, Yarn or Bun are refused.
22
+ 1. **🌐 Polyglot Monorepo Support (npm, pnpm & Maven):**
23
+ * **Node / npm:** Resolves workspaces exactly like npm (glob patterns such as `packages/**` included), calculates SemVer diffs, updates `package.json` (`dependencies`, `devDependencies`, `optionalDependencies`), runs `npm install` and checks the lockfile. **Node / pnpm** (9 – 12) works the same way for pnpm repositories: workspaces from `pnpm-workspace.yaml`, the `workspace:` protocol, `catalog:` entries, `pnpm install` and a lockfile check. Repositories managed by Yarn or Bun are refused.
24
24
  * **Java / Maven:** Finds every `pom.xml` (including the root POM), lets Maven compute the effective POM, looks up newer versions through the build's own repositories (mirrors, Nexus/Artifactory, credentials from `settings.xml`) and verifies the affected modules with `mvn test-compile`.
25
25
  * **Runtime Switch:** Press **`[E]`** anytime to switch between frontend and backend modules.
26
26
 
@@ -68,6 +68,7 @@ The registry URL alone is deliberately **not** used to decide the origin: in mos
68
68
  ### Aligning workspace modules
69
69
 
70
70
  * **npm:** If a dependency's range does not include the local version of a workspace package, npm does **not** link the workspace — it installs a package with the same name from the registry. Elevate offers to align the range (e.g. `^1.0.0` ➔ `^2.0.0`). After `npm install` it checks `package-lock.json`: every aligned dependency must be `"link": true`, otherwise the update is rolled back. Ranges that npm always links (`*`, `file:`, `workspace:`) are left alone.
71
+ * **pnpm:** pnpm links a workspace package only when the dependency is written with the `workspace:` protocol; a plain range such as `^1.0.0` is resolved from the registry, even if the local version satisfies it. Elevate therefore aligns `workspace:^1.2.0` ➔ `workspace:^2.0.0` (the protocol and the prefix are kept; `workspace:*`, `workspace:^`, `workspace:~` and `workspace:../lib` need nothing) and lists a plain range on a module as *not linked* without ever looking the name up in a registry or rewriting it. After `pnpm install` it reads the `importers` section of `pnpm-lock.yaml` (`lockfileVersion` 9.x): every aligned dependency must have a `version` starting with `link:`, otherwise the update is rolled back.
71
72
  * **Maven:** If a module depends on a module of the *same reactor* with a different version (e.g. `1.0.0` while the module is at `1.1.0-SNAPSHOT`), Elevate offers to align it. `${project.version}` references need no alignment.
72
73
  * The release channel does not apply to alignment: the local version — including `-SNAPSHOT` — is the target, because modules of one repository are built and tested together.
73
74
 
@@ -103,9 +104,31 @@ Elevate works the same wherever in the repository it is started. The root is fou
103
104
 
104
105
  The search never leaves the version-control checkout: it stops at the nearest directory that contains a `.git` entry, so a stray `package.json` or `pom.xml` somewhere above the repository is never mistaken for its root. Manifests that cannot be parsed are skipped.
105
106
 
106
- ### Package manager guard (npm)
107
+ ### Package manager guard (Yarn and Bun)
107
108
 
108
- Elevate's Node.js support drives npm. In a repository managed by pnpm, Yarn or Bun it refuses to scan or change the npm modules, because `npm install` would create a second lockfile and a `node_modules` layout the project does not use. The package manager is recognised from the repository root, in this order: the `packageManager` field of `package.json` (`npm@`, `pnpm@`, `yarn@`, `bun@`), then `package-lock.json` / `npm-shrinkwrap.json`, `pnpm-lock.yaml` / `pnpm-workspace.yaml`, `yarn.lock` / `.yarnrc.yml`, `bun.lock` / `bun.lockb`; without any of them the repository is treated as npm. If Elevate is started inside a workspace package, the search continues in the parent directories up to the checkout (the nearest directory with a `.git` entry); without a checkout only the directory itself is examined. The refusal names the manager and the file that decided. Maven modules in the same repository, read-only version queries (`elevate versions`) and a custom `postUpdateScript` are not affected.
109
+ Elevate's Node.js support drives npm and pnpm. In a repository managed by Yarn or Bun it refuses to scan or change the modules, because either tool would create a second lockfile and a `node_modules` layout the project does not use. The package manager is recognised from the repository root, in this order: the `packageManager` field of `package.json` (`npm@`, `pnpm@`, `yarn@`, `bun@`), then `package-lock.json` / `npm-shrinkwrap.json`, `pnpm-lock.yaml` / `pnpm-workspace.yaml`, `yarn.lock` / `.yarnrc.yml`, `bun.lock` / `bun.lockb`; without any of them the repository is treated as npm. If Elevate is started inside a workspace package, the search continues in the parent directories up to the checkout (the nearest directory with a `.git` entry); without a checkout only the directory itself is examined. The refusal names the manager and the file that decided. Maven modules in the same repository, read-only version queries (`elevate versions`) and a custom `postUpdateScript` are not affected.
110
+
111
+ ### pnpm workspaces and catalogs
112
+
113
+ * **Workspace file.** In a pnpm repository the `packages` list of `pnpm-workspace.yaml` (not the `workspaces` field of `package.json`) defines the modules; `*`, `**` and `!` patterns work as for npm, the root is always a module and `node_modules` never contains modules. A `pnpm-workspace.yaml` also marks the repository root, even without a `packages` list. A file that is not valid YAML counts as absent.
114
+ * **Catalogs.** A `catalog:` / `catalog:default` / `catalog:<name>` dependency is offered with the range from the catalog and the new range is written to that entry of `pnpm-workspace.yaml` (comments, quotes, notation and line endings stay; the module's `package.json` is not rewritten). A reference that cannot be resolved is listed as `catalog-unresolved`. The JSON output says where the version is declared: `"declaredIn": {"file": "pnpm-workspace.yaml", "kind": "catalog", "catalog": "default"}`.
115
+ * **Overrides** (`pnpm.overrides`, `overrides` in `pnpm-workspace.yaml`, `resolutions`) and `peerDependencies` are never changed.
116
+
117
+ ### Commands Elevate runs for pnpm
118
+
119
+ All in the repository root; Elevate uses the `pnpm` on the `PATH` (the `packageManager` field and Corepack decide the version). `pnpm --version` runs first and, if it fails, the operation stops with an explanation before anything is touched.
120
+
121
+ | Purpose | Command | Timeout |
122
+ | :--- | :--- | :--- |
123
+ | Is pnpm usable? | `pnpm --version` | 15 s |
124
+ | Install after writing the ranges | `pnpm install --no-frozen-lockfile` | 10 min |
125
+ | Restore after a rollback | `pnpm install --frozen-lockfile` | 10 min |
126
+ | Default verification (lockfile consistency, replaces `npm ls`) | `pnpm install --frozen-lockfile --lockfile-only` | 10 min |
127
+ | Vulnerability summary | `pnpm audit --json` | 60 s |
128
+ | Versions of a package | `pnpm view <name> <field> --json` | 15 s |
129
+ | Registry configuration | `pnpm config list --json` | 15 s |
130
+
131
+ `--no-frozen-lockfile` is passed explicitly because with `CI` set `pnpm install` is implicitly frozen and would fail on the manifest Elevate just changed. `pnpm ls` is not used for verification: it exits with 0 for missing dependencies. The vulnerability summary comes from `pnpm audit --json` (`pnpm install` prints none); an audit without a result is a warning, never a reason to roll back. Elevate does not read pnpm settings such as `minimumReleaseAge` or build-script approval; if pnpm refuses because of them, the update is rolled back with pnpm's own message.
109
132
 
110
133
  ### Dependency sections (npm)
111
134
 
@@ -153,7 +176,12 @@ src/
153
176
  │ │ ├── npm-registry.ts # npm view queries & dist-tags
154
177
  │ │ ├── npm-scanner.ts # Origins, alignment, SemVer diffs
155
178
  │ │ ├── npm-lockfile.ts # Workspace link check in package-lock.json
156
- │ │ ├── npm-package-manager.ts # Package manager detection & guard
179
+ │ │ ├── npm-package-manager.ts # Package manager detection, guard & pnpm check
180
+ │ │ ├── npm-commands.ts # Commands per package manager (npm / pnpm)
181
+ │ │ ├── npm-protocols.ts # workspace: / catalog: range protocols
182
+ │ │ ├── pnpm-workspace.ts # pnpm-workspace.yaml: packages, catalogs, in-place edit
183
+ │ │ ├── pnpm-lockfile.ts # Workspace link check in pnpm-lock.yaml
184
+ │ │ ├── pnpm-audit.ts # pnpm audit --json summary
157
185
  │ │ ├── npm-updater.ts # Updates package.json & runs npm install
158
186
  │ │ ├── npm-verifier.ts # npm ls / custom verification
159
187
  │ │ └── npm-strategy.ts # NpmEcosystemStrategy
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dennisrepa/elevate",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "🪶 Elevate — Interactive Polyglot Terminal Dashboard & Agentic MCP Server for safe dependency updates across monorepos.",
5
5
  "type": "module",
6
6
  "main": "./dist/cli.js",
@@ -14,8 +14,7 @@
14
14
  "docs/de.md"
15
15
  ],
16
16
  "publishConfig": {
17
- "access": "public",
18
- "registry": "https://registry.npmjs.org/"
17
+ "access": "public"
19
18
  },
20
19
  "keywords": [
21
20
  "cli",
@@ -24,6 +23,7 @@
24
23
  "updater",
25
24
  "monorepo",
26
25
  "npm",
26
+ "pnpm",
27
27
  "maven",
28
28
  "mcp",
29
29
  "agentic"
@@ -46,9 +46,7 @@
46
46
  "prepublishOnly": "npm run build",
47
47
  "typecheck": "tsc --noEmit -p . && tsc -p tsconfig.test.json",
48
48
  "test": "vitest run",
49
- "test:integration": "vitest run --config vitest.integration.config.ts",
50
- "preversion": "node scripts/changelog.mjs check",
51
- "version": "node scripts/changelog.mjs release && git add CHANGELOG.md"
49
+ "test:integration": "vitest run --config vitest.integration.config.ts"
52
50
  },
53
51
  "author": {
54
52
  "name": "Dennis Répa",
@@ -65,20 +63,26 @@
65
63
  "dependencies": {
66
64
  "@modelcontextprotocol/sdk": "^1.30.1",
67
65
  "@npmcli/map-workspaces": "^6.0.0",
68
- "ink": "^6.3.0",
66
+ "ink": "^8.0.0",
69
67
  "picocolors": "^1.1.1",
70
68
  "react": "^19.0.0",
71
69
  "saxes": "^6.0.0",
72
70
  "semver": "^7.6.3",
73
- "tsx": "^4.19.3"
71
+ "tsx": "^4.19.3",
72
+ "yaml": "^2.9.1"
74
73
  },
75
74
  "devDependencies": {
76
75
  "@types/node": "^26.6.2",
77
76
  "@types/react": "^19.3.0",
78
77
  "@types/semver": "^7.8.0",
79
78
  "ink-testing-library": "^4.0.0",
80
- "tsup": "^8.5.1",
79
+ "tsup": "^9.0.0",
81
80
  "typescript": "^7.0.2",
82
81
  "vitest": "^5.0.3"
82
+ },
83
+ "overrides": {
84
+ "glob": "^14.0.2",
85
+ "minimatch": "^11.0.1",
86
+ "esbuild": "^0.28.2"
83
87
  }
84
88
  }