memorix 0.9.7 → 0.9.9
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/CHANGELOG.md +13 -0
- package/dist/cli/index.js +41 -17
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +16 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.9.9] — 2026-02-25
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- **Cursor hooks config format invalid** — Generated config was missing required `version` field and used objects instead of arrays for hook scripts. Cursor requires `{ version: 1, hooks: { eventName: [{ command: "..." }] } }` format. Added `sessionStart`, `beforeShellExecution`, `afterMCPExecution`, `preCompact` events.
|
|
9
|
+
- **Cursor agent detection failed** — Cursor does NOT send `hook_event_name` like Claude Code. Detection now uses Cursor-specific fields (`workspace_roots`, `is_background_agent`, `composer_mode`). Event type inferred from payload structure (e.g., `old_content`/`new_content` → `afterFileEdit`).
|
|
10
|
+
- **Cursor `session_id` field not read** — Normalizer expected `conversation_id` but Cursor sends `session_id`. Now reads both with fallback.
|
|
11
|
+
|
|
12
|
+
## [0.9.8] — 2026-02-25
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- **Claude Code hooks installed to wrong file** — Hooks were written to `.github/hooks/memorix.json` but Claude Code reads from `.claude/settings.local.json` (project-level) or `~/.claude/settings.json` (global). Now correctly writes to `.claude/settings.local.json` for project-level installation.
|
|
16
|
+
- **Hooks merge overwrites existing settings** — Shallow spread `{...existing, ...generated}` would overwrite the entire `hooks` key, destroying user's other hook configurations. Now deep-merges the `hooks` object so existing hooks from other tools are preserved.
|
|
17
|
+
|
|
5
18
|
## [0.9.7] — 2026-02-25
|
|
6
19
|
|
|
7
20
|
### Fixed
|
package/dist/cli/index.js
CHANGED
|
@@ -3791,17 +3791,17 @@ function generateWindsurfConfig() {
|
|
|
3791
3791
|
}
|
|
3792
3792
|
function generateCursorConfig() {
|
|
3793
3793
|
const cmd = `${resolveHookCommand()} hook`;
|
|
3794
|
+
const hookScript = { command: cmd };
|
|
3794
3795
|
return {
|
|
3796
|
+
version: 1,
|
|
3795
3797
|
hooks: {
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
stop:
|
|
3803
|
-
command: cmd
|
|
3804
|
-
}
|
|
3798
|
+
sessionStart: [hookScript],
|
|
3799
|
+
beforeSubmitPrompt: [hookScript],
|
|
3800
|
+
afterFileEdit: [hookScript],
|
|
3801
|
+
beforeShellExecution: [hookScript],
|
|
3802
|
+
afterMCPExecution: [hookScript],
|
|
3803
|
+
preCompact: [hookScript],
|
|
3804
|
+
stop: [hookScript]
|
|
3805
3805
|
}
|
|
3806
3806
|
};
|
|
3807
3807
|
}
|
|
@@ -3823,6 +3823,7 @@ ${resolveHookCommand()} hook
|
|
|
3823
3823
|
function getProjectConfigPath(agent, projectRoot) {
|
|
3824
3824
|
switch (agent) {
|
|
3825
3825
|
case "claude":
|
|
3826
|
+
return path6.join(projectRoot, ".claude", "settings.local.json");
|
|
3826
3827
|
case "copilot":
|
|
3827
3828
|
return path6.join(projectRoot, ".github", "hooks", "memorix.json");
|
|
3828
3829
|
case "windsurf":
|
|
@@ -3930,10 +3931,12 @@ async function installHooks(agent, projectRoot, global = false) {
|
|
|
3930
3931
|
existing = JSON.parse(content);
|
|
3931
3932
|
} catch {
|
|
3932
3933
|
}
|
|
3933
|
-
const
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3934
|
+
const gen = generated;
|
|
3935
|
+
const merged = { ...existing };
|
|
3936
|
+
if (gen.hooks && typeof gen.hooks === "object") {
|
|
3937
|
+
const existingHooks = existing.hooks && typeof existing.hooks === "object" ? existing.hooks : {};
|
|
3938
|
+
merged.hooks = { ...existingHooks, ...gen.hooks };
|
|
3939
|
+
}
|
|
3937
3940
|
await fs4.writeFile(configPath, JSON.stringify(merged, null, 2), "utf-8");
|
|
3938
3941
|
}
|
|
3939
3942
|
const events = [];
|
|
@@ -6893,7 +6896,7 @@ var init_sync = __esm({
|
|
|
6893
6896
|
// src/hooks/normalizer.ts
|
|
6894
6897
|
function detectAgent(payload) {
|
|
6895
6898
|
if ("agent_action_name" in payload) return "windsurf";
|
|
6896
|
-
if ("
|
|
6899
|
+
if ("workspace_roots" in payload || "is_background_agent" in payload || "composer_mode" in payload) return "cursor";
|
|
6897
6900
|
if ("hook_event_name" in payload) return "claude";
|
|
6898
6901
|
if ("hookEventName" in payload) return "copilot";
|
|
6899
6902
|
if ("event_type" in payload) return "kiro";
|
|
@@ -6905,7 +6908,7 @@ function extractEventName(payload, agent) {
|
|
|
6905
6908
|
case "windsurf":
|
|
6906
6909
|
return payload.agent_action_name ?? "";
|
|
6907
6910
|
case "cursor":
|
|
6908
|
-
return payload
|
|
6911
|
+
return inferCursorEvent(payload);
|
|
6909
6912
|
case "claude":
|
|
6910
6913
|
return payload.hook_event_name ?? payload.hookEventName ?? "";
|
|
6911
6914
|
case "copilot":
|
|
@@ -6981,9 +6984,20 @@ function normalizeWindsurf(payload, event) {
|
|
|
6981
6984
|
}
|
|
6982
6985
|
return result;
|
|
6983
6986
|
}
|
|
6987
|
+
function inferCursorEvent(payload) {
|
|
6988
|
+
if ("composer_mode" in payload) return "sessionStart";
|
|
6989
|
+
if ("prompt" in payload) return "beforeSubmitPrompt";
|
|
6990
|
+
if ("old_content" in payload || "new_content" in payload) return "afterFileEdit";
|
|
6991
|
+
if ("command" in payload && "cwd" in payload) return "beforeShellExecution";
|
|
6992
|
+
if ("trigger" in payload && "context_usage_percent" in payload) return "preCompact";
|
|
6993
|
+
if ("reason" in payload && "duration_ms" in payload) return "sessionEnd";
|
|
6994
|
+
if ("mcp_server_name" in payload) return "afterMCPExecution";
|
|
6995
|
+
if ("reason" in payload) return "stop";
|
|
6996
|
+
return "";
|
|
6997
|
+
}
|
|
6984
6998
|
function normalizeCursor(payload, event) {
|
|
6985
6999
|
const result = {
|
|
6986
|
-
sessionId: payload.conversation_id ?? "",
|
|
7000
|
+
sessionId: payload.session_id ?? payload.conversation_id ?? "",
|
|
6987
7001
|
cwd: payload.cwd ?? ""
|
|
6988
7002
|
};
|
|
6989
7003
|
const roots = payload.workspace_roots;
|
|
@@ -7000,6 +7014,11 @@ function normalizeCursor(payload, event) {
|
|
|
7000
7014
|
case "post_edit":
|
|
7001
7015
|
result.filePath = payload.file_path ?? "";
|
|
7002
7016
|
break;
|
|
7017
|
+
case "post_tool":
|
|
7018
|
+
result.toolName = payload.mcp_server_name ?? "";
|
|
7019
|
+
result.toolInput = payload.mcp_tool_input;
|
|
7020
|
+
result.toolResult = payload.mcp_tool_output;
|
|
7021
|
+
break;
|
|
7003
7022
|
}
|
|
7004
7023
|
return result;
|
|
7005
7024
|
}
|
|
@@ -7066,11 +7085,16 @@ var init_normalizer = __esm({
|
|
|
7066
7085
|
pre_mcp_tool_use: "post_tool",
|
|
7067
7086
|
post_mcp_tool_use: "post_tool",
|
|
7068
7087
|
post_cascade_response: "post_response",
|
|
7069
|
-
// Cursor
|
|
7088
|
+
// Cursor (camelCase event names)
|
|
7089
|
+
sessionStart: "session_start",
|
|
7090
|
+
sessionEnd: "session_end",
|
|
7070
7091
|
beforeSubmitPrompt: "user_prompt",
|
|
7071
7092
|
beforeShellExecution: "post_command",
|
|
7093
|
+
afterShellExecution: "post_command",
|
|
7072
7094
|
beforeMCPExecution: "post_tool",
|
|
7095
|
+
afterMCPExecution: "post_tool",
|
|
7073
7096
|
afterFileEdit: "post_edit",
|
|
7097
|
+
preCompact: "pre_compact",
|
|
7074
7098
|
stop: "session_end"
|
|
7075
7099
|
};
|
|
7076
7100
|
}
|