memtrace 0.1.25 → 0.1.27

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/README.md CHANGED
@@ -233,6 +233,19 @@ Skills and plugins are shared between Claude Code and Claude Desktop — both ac
233
233
  }
234
234
  ```
235
235
 
236
+ ### Uninstall
237
+
238
+ ```bash
239
+ memtrace uninstall # removes skills, MCP server, plugin, and settings
240
+ npm uninstall -g memtrace # removes the binary
241
+ ```
242
+
243
+ Already ran `npm uninstall` first? The cleanup script is persisted at `~/.memtrace/uninstall.js`:
244
+
245
+ ```bash
246
+ node ~/.memtrace/uninstall.js
247
+ ```
248
+
236
249
  ## Languages
237
250
 
238
251
  Rust · Go · TypeScript · JavaScript · Python · Java · C · C++ · C# · Swift · Kotlin · Ruby · PHP · Dart · Scala · Perl — and more via Tree-sitter.
package/bin/memtrace.js CHANGED
@@ -4,6 +4,45 @@
4
4
  const { spawnSync } = require("child_process");
5
5
  const { getBinaryPath } = require("../install.js");
6
6
 
7
+ // ── Handle `memtrace uninstall` before delegating to the Rust binary ────────
8
+ // npm v7+ does NOT fire preuninstall hooks for global packages (npm/cli#3042).
9
+ // This command provides reliable cleanup users can run before `npm uninstall -g`.
10
+
11
+ const args = process.argv.slice(2);
12
+
13
+ if (args[0] === "uninstall" || args[0] === "cleanup") {
14
+ const path = require("path");
15
+ const os = require("os");
16
+
17
+ // Try the bundled script first, then the persisted copy in ~/.memtrace/
18
+ const candidates = [
19
+ path.join(__dirname, "..", "uninstall.js"),
20
+ path.join(os.homedir(), ".memtrace", "uninstall.js"),
21
+ ];
22
+
23
+ let ran = false;
24
+ for (const p of candidates) {
25
+ try {
26
+ require(p);
27
+ ran = true;
28
+ break;
29
+ } catch (e) {
30
+ // try next candidate
31
+ }
32
+ }
33
+
34
+ if (!ran) {
35
+ console.error("memtrace: could not find uninstall script");
36
+ process.exit(1);
37
+ }
38
+
39
+ console.log("");
40
+ console.log("Now run: npm uninstall -g memtrace");
41
+ process.exit(0);
42
+ }
43
+
44
+ // ── Delegate everything else to the Rust binary ─────────────────────────────
45
+
7
46
  let binaryPath;
8
47
  try {
9
48
  binaryPath = getBinaryPath();
@@ -12,7 +51,7 @@ try {
12
51
  process.exit(1);
13
52
  }
14
53
 
15
- const result = spawnSync(binaryPath, process.argv.slice(2), {
54
+ const result = spawnSync(binaryPath, args, {
16
55
  stdio: "inherit",
17
56
  env: process.env,
18
57
  });
package/install.js CHANGED
@@ -231,6 +231,19 @@ if (require.main === module) {
231
231
  console.warn(`memtrace: MCP server registration failed: ${e.message}`);
232
232
  }
233
233
  }
234
+
235
+ // 5. Persist uninstall script to ~/.memtrace/ so it survives `npm uninstall -g`
236
+ // (npm v7+ does NOT fire preuninstall hooks for global packages — npm/cli#3042)
237
+ try {
238
+ const memtraceDir = path.join(os.homedir(), ".memtrace");
239
+ fs.mkdirSync(memtraceDir, { recursive: true });
240
+ const src = path.join(__dirname, "uninstall.js");
241
+ const dest = path.join(memtraceDir, "uninstall.js");
242
+ fs.copyFileSync(src, dest);
243
+ console.log(`memtrace: persisted uninstall script to ${dest}`);
244
+ } catch (e) {
245
+ console.warn(`memtrace: failed to persist uninstall script: ${e.message}`);
246
+ }
234
247
  }
235
248
 
236
249
  module.exports = { getBinaryPath };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memtrace",
3
- "version": "0.1.25",
3
+ "version": "0.1.27",
4
4
  "description": "Code intelligence graph — MCP server + AI agent skills + visualization UI",
5
5
  "keywords": [
6
6
  "mcp",
package/uninstall.js CHANGED
@@ -138,9 +138,9 @@ function tryClaudeCliUninstall() {
138
138
  }
139
139
  }
140
140
 
141
- // ── Main preuninstall ───────────────────────────────────────────────────────
141
+ // ── Main uninstall logic ───────────────────────────────────────────────────
142
142
 
143
- if (require.main === module) {
143
+ function run() {
144
144
  console.log("memtrace: cleaning up...");
145
145
 
146
146
  // 1. Remove skills
@@ -171,5 +171,24 @@ if (require.main === module) {
171
171
  console.warn(`memtrace: MCP server removal failed: ${e.message}`);
172
172
  }
173
173
 
174
+ // 5. Clean up ~/.memtrace/ (the persisted uninstall script itself)
175
+ try {
176
+ const memtraceDir = path.join(os.homedir(), ".memtrace");
177
+ if (fs.existsSync(memtraceDir)) {
178
+ fs.rmSync(memtraceDir, { recursive: true, force: true });
179
+ console.log("memtrace: removed ~/.memtrace/");
180
+ }
181
+ } catch (e) {
182
+ console.warn(`memtrace: failed to remove ~/.memtrace/: ${e.message}`);
183
+ }
184
+
174
185
  console.log("memtrace: uninstall complete");
175
186
  }
187
+
188
+ // Run when called directly (npm preuninstall hook) or when require()'d
189
+ if (require.main === module) {
190
+ run();
191
+ } else {
192
+ // Called via `memtrace uninstall` — run immediately
193
+ run();
194
+ }