memtrace 0.6.30 → 0.6.46

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.
@@ -236,15 +236,32 @@ function applySettingsHooks(settings, hooksDir) {
236
236
  * into the *first* matching block. Pre-existing duplicates in
237
237
  * other blocks were never cleaned up, just left to compound.
238
238
  *
239
+ * 3. (issue #26) Both prior axes are install-path-sensitive: the
240
+ * marker match needs the underscore keys to survive, and the
241
+ * exact-command match only catches a hook at the SAME absolute
242
+ * path we're about to write. When the install location moves
243
+ * between versions (a version-pinned store dir, a different
244
+ * global prefix, a `/private/tmp` upgrade-test root) the prior
245
+ * entry sits at a different path with no markers, matches
246
+ * nothing, and survives every re-inject — accumulating, and
247
+ * dangling once that old path is pruned (its `command` then
248
+ * shells out to a script that no longer exists, erroring on
249
+ * every UserPromptSubmit / PostToolUse).
250
+ *
239
251
  * The new contract: regardless of how settings.json got into its
240
252
  * current shape, this function leaves it with exactly one of our
241
253
  * hooks installed under exactly one block. Running it 100 times
242
254
  * produces the same result as running it once — and self-heals
243
- * existing duplication on the way through.
255
+ * existing duplication (including stale, differently-pathed, and
256
+ * dangling copies) on the way through.
244
257
  *
245
258
  * Match strategy: a hook is "ours" if it has the managed markers
246
- * intact OR its command path matches one we generate. The
247
- * command-path match is what catches stripped-marker pollution.
259
+ * intact OR its command path matches one we generate OR its command
260
+ * ends in one of our hook script basenames. The basename match is
261
+ * the path-independent axis that catches stripped-marker pollution
262
+ * AND stale/dangling entries left at a previous install path (#26) —
263
+ * it mirrors the uninstaller's `isMemtraceHook` suffix test so inject
264
+ * and uninstall recognise exactly the same set of entries.
248
265
  *
249
266
  * @param {Array} existing
250
267
  * @param {object} ourEntry shape `{ matcher?, hooks: [...] }`
@@ -252,10 +269,15 @@ function applySettingsHooks(settings, hooksDir) {
252
269
  * @returns {Array}
253
270
  */
254
271
  function mergeHookList(existing, ourEntry, ourHook) {
272
+ const ourBasename =
273
+ typeof ourHook.command === "string" ? path.basename(ourHook.command) : null;
255
274
  const isOurs = (h) =>
256
275
  !!h && (
257
276
  (h._managed_by === HOOK_MANAGED_TAG && h._hook_kind === ourHook._hook_kind) ||
258
- (typeof h.command === "string" && h.command === ourHook.command)
277
+ (typeof h.command === "string" && h.command === ourHook.command) ||
278
+ (ourBasename !== null &&
279
+ typeof h.command === "string" &&
280
+ path.basename(h.command) === ourBasename)
259
281
  );
260
282
 
261
283
  // Phase 1: walk every block, strip every "ours" hook, drop blocks
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memtrace",
3
- "version": "0.6.30",
3
+ "version": "0.6.46",
4
4
  "description": "Code intelligence graph — MCP server + AI agent skills + visualization UI",
5
5
  "keywords": [
6
6
  "mcp",
@@ -39,12 +39,12 @@
39
39
  "fs-extra": "^11.0.0"
40
40
  },
41
41
  "optionalDependencies": {
42
- "@memtrace/darwin-arm64": "0.6.30",
43
- "@memtrace/linux-x64": "0.6.30",
44
- "@memtrace/linux-arm64": "0.6.30",
45
- "@memtrace/win32-x64": "0.6.30",
46
- "@memtrace/linux-x64-noavx2": "0.6.30",
47
- "@memtrace/win32-x64-noavx2": "0.6.30"
42
+ "@memtrace/darwin-arm64": "0.6.46",
43
+ "@memtrace/linux-x64": "0.6.46",
44
+ "@memtrace/linux-arm64": "0.6.46",
45
+ "@memtrace/win32-x64": "0.6.46",
46
+ "@memtrace/linux-x64-noavx2": "0.6.46",
47
+ "@memtrace/win32-x64-noavx2": "0.6.46"
48
48
  },
49
49
  "engines": {
50
50
  "node": ">=18"