@dennisrepa/elevate 1.2.0 → 1.3.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/LICENSE +21 -21
- package/README.md +225 -214
- package/dist/cli.js +2803 -1277
- package/dist/cli.js.map +1 -1
- package/docs/de.md +409 -305
- package/docs/en.md +414 -309
- package/package.json +84 -73
- package/docs/plans/transactional-updates.md +0 -142
package/package.json
CHANGED
|
@@ -1,73 +1,84 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@dennisrepa/elevate",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "🪶 Elevate — Interactive Polyglot Terminal Dashboard & Agentic MCP Server for safe dependency updates across monorepos.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "./dist/cli.js",
|
|
7
|
-
"bin": {
|
|
8
|
-
"elevate": "dist/cli.js"
|
|
9
|
-
},
|
|
10
|
-
"files": [
|
|
11
|
-
"dist",
|
|
12
|
-
"README.md",
|
|
13
|
-
"docs"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"build
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
},
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
"
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"@
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
|
|
73
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@dennisrepa/elevate",
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "🪶 Elevate — Interactive Polyglot Terminal Dashboard & Agentic MCP Server for safe dependency updates across monorepos.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/cli.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"elevate": "dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md",
|
|
13
|
+
"docs/en.md",
|
|
14
|
+
"docs/de.md"
|
|
15
|
+
],
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public",
|
|
18
|
+
"registry": "https://registry.npmjs.org/"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"cli",
|
|
22
|
+
"tui",
|
|
23
|
+
"dependencies",
|
|
24
|
+
"updater",
|
|
25
|
+
"monorepo",
|
|
26
|
+
"npm",
|
|
27
|
+
"maven",
|
|
28
|
+
"mcp",
|
|
29
|
+
"agentic"
|
|
30
|
+
],
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/DennisRepa/Elevate.git"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://github.com/DennisRepa/Elevate#readme",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/DennisRepa/Elevate/issues"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsup",
|
|
42
|
+
"build:bundle": "node scripts/build-bundle.mjs",
|
|
43
|
+
"build:binary": "node scripts/build-binary.mjs",
|
|
44
|
+
"dev": "tsx src/index.tsx",
|
|
45
|
+
"start": "node dist/cli.js",
|
|
46
|
+
"prepublishOnly": "npm run build",
|
|
47
|
+
"typecheck": "tsc --noEmit -p . && tsc -p tsconfig.test.json",
|
|
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"
|
|
52
|
+
},
|
|
53
|
+
"author": {
|
|
54
|
+
"name": "Dennis Répa",
|
|
55
|
+
"email": "dennis.maier.1989@gmail.com",
|
|
56
|
+
"url": "https://de.linkedin.com/in/dennismaier1989"
|
|
57
|
+
},
|
|
58
|
+
"funding": {
|
|
59
|
+
"type": "ko-fi",
|
|
60
|
+
"url": "https://ko-fi.com/dennisrepa"
|
|
61
|
+
},
|
|
62
|
+
"engines": {
|
|
63
|
+
"node": ">=20.0.0"
|
|
64
|
+
},
|
|
65
|
+
"dependencies": {
|
|
66
|
+
"@modelcontextprotocol/sdk": "^1.30.1",
|
|
67
|
+
"@npmcli/map-workspaces": "^6.0.0",
|
|
68
|
+
"ink": "^6.3.0",
|
|
69
|
+
"picocolors": "^1.1.1",
|
|
70
|
+
"react": "^19.0.0",
|
|
71
|
+
"saxes": "^6.0.0",
|
|
72
|
+
"semver": "^7.6.3",
|
|
73
|
+
"tsx": "^4.19.3"
|
|
74
|
+
},
|
|
75
|
+
"devDependencies": {
|
|
76
|
+
"@types/node": "^26.6.2",
|
|
77
|
+
"@types/react": "^19.3.0",
|
|
78
|
+
"@types/semver": "^7.8.0",
|
|
79
|
+
"ink-testing-library": "^4.0.0",
|
|
80
|
+
"tsup": "^8.5.1",
|
|
81
|
+
"typescript": "^7.0.2",
|
|
82
|
+
"vitest": "^5.0.3"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
# 🪶 Elevate — Plan: Transaktionale Updates & lokaler MCP-Betrieb
|
|
2
|
-
|
|
3
|
-
> **Status:** geplant · **Stand:** 2026-09-25
|
|
4
|
-
> **Betriebsmodell:** Elevate läuft lokal beim Entwickler. Sein Harness (Continue, Cline, Claude Code, Cursor …) startet `elevate mcp` als stdio-Server im Projektordner. Keine Container, kein Gateway (siehe Parity ADR 0006, gilt für die ganze Tool-Familie).
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## 1. Ziele
|
|
9
|
-
|
|
10
|
-
1. **Transaktionale Updates:** Schlägt die Verifikation fehl, bleibt das Repository unverändert.
|
|
11
|
-
2. **Ein zentraler Update-Ablauf** statt drei Kopien in CLI, TUI und MCP.
|
|
12
|
-
3. **Saubere Workspace-Bestimmung** im MCP-Betrieb (MCP Roots).
|
|
13
|
-
4. **`init` für alle gängigen Harnesses**, inklusive Continue und Cline.
|
|
14
|
-
|
|
15
|
-
## 2. Ausgangslage
|
|
16
|
-
|
|
17
|
-
| Thema | Heute |
|
|
18
|
-
|---|---|
|
|
19
|
-
| Update-Ablauf | Manifest schreiben → `npm install` / `mvn dependency:resolve` → Verifikation, alles direkt im Repo ([npm-updater.ts](../../src/adapters/npm/npm-updater.ts), [maven-updater.ts](../../src/adapters/maven/maven-updater.ts), [npm-verifier.ts](../../src/adapters/npm/npm-verifier.ts), [maven-verifier.ts](../../src/adapters/maven/maven-verifier.ts)) |
|
|
20
|
-
| Fehlgeschlagene Verifikation | Repo bleibt im geänderten Zustand, man muss selbst zurückrollen |
|
|
21
|
-
| Duplikation | Ablauf „anwenden → verifizieren“ dreifach: [command-update.ts:173](../../src/cli/command-update.ts#L173), [use-updater.ts:34](../../src/hooks/use-updater.ts#L34), [mcp-server.ts:410](../../src/mcp/mcp-server.ts#L410) |
|
|
22
|
-
| Workspace | `findMonorepoRoot(process.cwd())` ([config.ts:67](../../src/config.ts#L67)), MCP Roots werden nicht genutzt |
|
|
23
|
-
| `init` | erkennt Cursor, Claude Desktop, Claude Code, Antigravity, VS Code, Windsurf ([command-init.ts](../../src/cli/command-init.ts)). **Continue und Cline fehlen.** |
|
|
24
|
-
|
|
25
|
-
## 3. Zentraler Update-Workflow
|
|
26
|
-
|
|
27
|
-
Neuer Application Service `src/application/update-workflow.ts`, den CLI, TUI und MCP gemeinsam nutzen:
|
|
28
|
-
|
|
29
|
-
```ts
|
|
30
|
-
export class UpdateWorkflow {
|
|
31
|
-
constructor(private strategy: EcosystemStrategy, private sandbox: WorkspaceSandboxPort) {}
|
|
32
|
-
|
|
33
|
-
async run(input: {
|
|
34
|
-
module: ProjectModule;
|
|
35
|
-
rootDir: string;
|
|
36
|
-
updates: UpdateCandidate[];
|
|
37
|
-
verify: boolean;
|
|
38
|
-
onProgress: (msg: string) => void;
|
|
39
|
-
}): Promise<UpdateWorkflowResult>; // updateSummary, verifyResult, committed, changedFiles, followUps
|
|
40
|
-
}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
Dieser Schritt ändert **kein** Verhalten. Er beseitigt nur die Duplikation und schafft die Stelle, an der die Transaktion eingebaut wird.
|
|
44
|
-
|
|
45
|
-
## 4. Transaktion über einen austauschbaren Arbeitsort
|
|
46
|
-
|
|
47
|
-
### 4.1 Port
|
|
48
|
-
|
|
49
|
-
```ts
|
|
50
|
-
// src/domain/ports.ts
|
|
51
|
-
export interface WorkspaceSandbox {
|
|
52
|
-
readonly workDir: string;
|
|
53
|
-
resolve(module: ProjectModule): ProjectModule; // Modulpfade über relPath auf workDir abbilden
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export interface WorkspaceSandboxPort {
|
|
57
|
-
open(rootDir: string): Promise<WorkspaceSandbox>;
|
|
58
|
-
commit(sandbox: WorkspaceSandbox, files: string[]): Promise<void>;
|
|
59
|
-
discard(sandbox: WorkspaceSandbox): Promise<void>;
|
|
60
|
-
}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
### 4.2 Adapter
|
|
64
|
-
|
|
65
|
-
| Adapter | Verhalten | Einsatz |
|
|
66
|
-
|---|---|---|
|
|
67
|
-
| `SnapshotSandboxAdapter` | Arbeitet **direkt im Repo**, sichert vorher Manifeste + Lockfiles. Bei `discard` werden diese zurückgespielt und die Installation erneut ausgeführt, um `node_modules` wiederherzustellen. | **Standard.** Schnell, nutzt vorhandenes `node_modules` |
|
|
68
|
-
| `CopySandboxAdapter` | Kopiert das Repo (git-getrackte + nicht ignorierte Dateien, ohne `node_modules`/`target`/`dist`) in ein Temp-Verzeichnis, arbeitet dort und schreibt bei Erfolg nur Manifeste + Lockfiles zurück. Danach wird im echten Repo installiert. | `--isolated`: maximale Sicherheit, z. B. für riskante Major-Updates. Das Repo wird während der Prüfung **nie** berührt. |
|
|
69
|
-
| `InPlaceSandboxAdapter` | Heutiges Verhalten ohne Rollback | `--no-rollback`, für Sonderfälle |
|
|
70
|
-
|
|
71
|
-
### 4.3 Ablauf
|
|
72
|
-
|
|
73
|
-
```
|
|
74
|
-
1. open Snapshot anlegen bzw. Kopie erstellen
|
|
75
|
-
2. apply Manifest ändern, installieren
|
|
76
|
-
3. verify Build + Tests
|
|
77
|
-
4a. grün commit: Snapshot verwerfen bzw. Manifeste + Lockfiles zurückschreiben
|
|
78
|
-
4b. rot discard: Dateien zurückspielen + Installation wiederherstellen → Repo wie vorher
|
|
79
|
-
5. Ergebnis inkl. changedFiles und ggf. followUps
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### 4.4 Updater melden geänderte Dateien
|
|
83
|
-
|
|
84
|
-
`DependencyUpdaterPort.applyUpdates()` liefert zusätzlich die geänderten Dateien (relativ zum Root). Das braucht die Transaktion:
|
|
85
|
-
|
|
86
|
-
| Ökosystem | Dateien |
|
|
87
|
-
|---|---|
|
|
88
|
-
| npm | betroffene `package.json` + `package-lock.json` |
|
|
89
|
-
| Maven | betroffene `pom.xml` |
|
|
90
|
-
| künftig pnpm / Yarn / Gradle | `pnpm-lock.yaml` / `yarn.lock` / `gradle.lockfile`, `libs.versions.toml` |
|
|
91
|
-
|
|
92
|
-
### 4.5 Schutz vor parallelen Änderungen
|
|
93
|
-
|
|
94
|
-
Beim `open` wird ein Hash der betroffenen Dateien gespeichert. Hat der Entwickler (oder ein anderer Agent) sie während des Laufs geändert, bricht `commit`/`discard` ab, statt fremde Änderungen zu überschreiben, und meldet den Konflikt.
|
|
95
|
-
|
|
96
|
-
## 5. MCP-Betrieb
|
|
97
|
-
|
|
98
|
-
### 5.1 Workspace-Bestimmung
|
|
99
|
-
|
|
100
|
-
In dieser Reihenfolge:
|
|
101
|
-
|
|
102
|
-
1. **MCP Roots** des Clients (bei mehreren Roots: Parameter `workspace` wählt aus, Default der erste; auf `roots/list_changed` reagieren)
|
|
103
|
-
2. `--root <pfad>` bzw. `ELEVATE_ROOT`
|
|
104
|
-
3. `findMonorepoRoot(process.cwd())` (heutiges Verhalten)
|
|
105
|
-
|
|
106
|
-
Pfade außerhalb der Roots werden abgelehnt. Diese Logik wandert später ins gemeinsame Toolkit-Paket der Tool-Familie.
|
|
107
|
-
|
|
108
|
-
### 5.2 Antworten
|
|
109
|
-
|
|
110
|
-
- `elevate_apply_updates` meldet `rolledBack: true` samt Grund, wenn die Verifikation fehlschlug.
|
|
111
|
-
- Parameter `isolated: boolean` (entspricht `--isolated`).
|
|
112
|
-
- Keine verschachtelten Parameter mehr für einfache Fälle: zusätzlich `identifiers: string[]` (Update auf latest) neben dem bestehenden `updates`-Array. Das ist für lokale Modelle deutlich robuster.
|
|
113
|
-
|
|
114
|
-
## 6. `init` für alle Harnesses
|
|
115
|
-
|
|
116
|
-
Neu: **Continue** (`.continue/mcpServers/elevate.yaml` bzw. globale `config.yaml`) und **Cline** (`cline_mcp_settings.json`). Vorhandene Detektoren bleiben. Ziel ist eine Liste, die in der ganzen Tool-Familie identisch ist:
|
|
117
|
-
|
|
118
|
-
`continue · cline · claude-code · claude-desktop · cursor · windsurf · vscode · antigravity`
|
|
119
|
-
|
|
120
|
-
## 7. Tests
|
|
121
|
-
|
|
122
|
-
- **Unit:** `UpdateWorkflow` mit Fake-Ports: grün → commit, rot → discard, Konflikt → Abbruch.
|
|
123
|
-
- **Adapter:** Snapshot (Rückspielen, EOL-Erhalt, Wiederherstellung von `node_modules`), Copy (Kopierregeln, `resolve()` für verschachtelte Module, Rückschreiben).
|
|
124
|
-
- **Integration:** Beispiel-Repo mit absichtlich brechendem Update. Danach ist das Repo per `git status` sauber und die Tests laufen wieder grün.
|
|
125
|
-
- **MCP:** Roots-Handling mit Test-Client (ein Root, mehrere Roots, Wechsel).
|
|
126
|
-
- **Regression:** TUI, CLI und MCP liefern bei grünen Updates dieselben Ergebnisse wie vorher.
|
|
127
|
-
|
|
128
|
-
## 8. Umsetzungsschritte
|
|
129
|
-
|
|
130
|
-
| Schritt | Inhalt | Fertig, wenn |
|
|
131
|
-
|---|---|---|
|
|
132
|
-
| 1 | `UpdateWorkflow`, CLI/TUI/MCP umstellen | Duplikation entfernt, Verhalten unverändert |
|
|
133
|
-
| 2 | Port + `InPlaceSandboxAdapter`, Updater liefern `changedFiles` | Heutiges Verhalten läuft über den Port |
|
|
134
|
-
| 3 | `SnapshotSandboxAdapter` als Standard, Konfliktschutz | Rote Verifikation hinterlässt ein unverändertes Repo |
|
|
135
|
-
| 4 | `CopySandboxAdapter` + `--isolated` | Repo wird während isolierter Prüfung nicht berührt |
|
|
136
|
-
| 5 | MCP Roots, `--root`, `rolledBack`, `identifiers` | Roots-Tests grün |
|
|
137
|
-
| 6 | `init` für Continue und Cline, Doku (de/en) | Beide Harnesses per `elevate init` eingerichtet |
|
|
138
|
-
|
|
139
|
-
## 9. Offene Fragen
|
|
140
|
-
|
|
141
|
-
1. Soll bei einem Rollback die Wiederherstellung von `node_modules` per `npm ci` (exakt, langsamer) oder `npm install` (schneller) erfolgen? *Vorschlag:* `npm ci`, wenn ein Lockfile existiert.
|
|
142
|
-
2. Workspace-Bestimmung und `init` zuerst in Elevate bauen und danach ins Toolkit-Paket verschieben, oder direkt im Toolkit starten? *Vorschlag:* direkt im Toolkit, damit Register und Parity sofort profitieren.
|