memorix 0.9.11 → 0.9.12
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 +15 -0
- package/README.md +25 -6
- package/README.zh-CN.md +25 -6
- package/dist/cli/index.js +209 -29
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +113 -19
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.9.12] — 2026-02-25
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- **Copilot hooks format completely wrong** — Was reusing Claude Code's `generateClaudeConfig()` (PascalCase events, `command` field). Copilot requires `version: 1`, `bash`/`powershell` fields, `timeoutSec`, and camelCase event names (`sessionStart`, `userPromptSubmitted`, `preToolUse`, `postToolUse`, `sessionEnd`, `errorOccurred`). Now uses dedicated `generateCopilotConfig()`. Source: [GitHub Docs](https://docs.github.com/en/copilot/reference/hooks-configuration).
|
|
9
|
+
- **Codex fake hooks.json removed** — Codex has no hooks system (only `notify` in config.toml for `agent-turn-complete`). Was generating a non-existent `.codex/hooks.json`. Now only installs rules (AGENTS.md). Source: [OpenAI Codex Config Reference](https://developers.openai.com/codex/config-reference/).
|
|
10
|
+
- **Kiro hook file extension wrong** — Was `.hook.md`, should be `.kiro.hook`. Now generates 3 hook files: `memorix-agent-stop.kiro.hook` (session memory), `memorix-prompt-submit.kiro.hook` (context loading), `memorix-file-save.kiro.hook` (file change tracking). Source: [Kiro Docs](https://kiro.dev/docs/hooks/).
|
|
11
|
+
- **Kiro only had 1 event** — Was only `file_saved`. Now covers `agent_stop`, `prompt_submit`, and `file_save` events.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- **Antigravity/Gemini CLI hook installer** — New `generateGeminiConfig()` for `.gemini/settings.json`. PascalCase events (`SessionStart`, `AfterTool`, `AfterAgent`, `PreCompress`), timeout in milliseconds (10000ms). Source: [Gemini CLI Docs](https://geminicli.com/docs/hooks/).
|
|
15
|
+
- **Copilot normalizer** — Dedicated `normalizeCopilot()` function with `inferCopilotEvent()` for payload-based event detection (Copilot sends typed payloads without explicit event names).
|
|
16
|
+
- **Gemini CLI normalizer** — Dedicated `normalizeGemini()` function with event mapping for all 11 Gemini CLI events (`BeforeAgent`, `AfterAgent`, `BeforeTool`, `AfterTool`, `PreCompress`, etc.).
|
|
17
|
+
- **Gemini CLI event mappings** — Full EVENT_MAP entries for Gemini CLI PascalCase events → normalized events.
|
|
18
|
+
- **Copilot event mappings** — EVENT_MAP entries for Copilot-specific camelCase events (`userPromptSubmitted`, `preToolUse`, `postToolUse`, `errorOccurred`).
|
|
19
|
+
|
|
5
20
|
## [0.9.11] — 2026-02-25
|
|
6
21
|
|
|
7
22
|
### Fixed
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<a href="https://www.npmjs.com/package/memorix"><img src="https://img.shields.io/npm/dm/memorix.svg?style=flat-square&color=blue" alt="npm downloads"></a>
|
|
9
9
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-green.svg?style=flat-square" alt="License"></a>
|
|
10
10
|
<a href="https://github.com/AVIDS2/memorix"><img src="https://img.shields.io/github/stars/AVIDS2/memorix?style=flat-square&color=yellow" alt="GitHub stars"></a>
|
|
11
|
-
<img src="https://img.shields.io/badge/tests-
|
|
11
|
+
<img src="https://img.shields.io/badge/tests-491%20passed-brightgreen?style=flat-square" alt="Tests">
|
|
12
12
|
</p>
|
|
13
13
|
<p align="center">
|
|
14
14
|
<img src="https://img.shields.io/badge/Works%20with-Cursor-orange?style=flat-square" alt="Cursor">
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
<img src="https://img.shields.io/badge/Works%20with-Copilot-lightblue?style=flat-square" alt="Copilot">
|
|
19
19
|
<img src="https://img.shields.io/badge/Works%20with-Kiro-red?style=flat-square" alt="Kiro">
|
|
20
20
|
<img src="https://img.shields.io/badge/Works%20with-Antigravity-grey?style=flat-square" alt="Antigravity">
|
|
21
|
+
<img src="https://img.shields.io/badge/Works%20with-Gemini%20CLI-4285F4?style=flat-square" alt="Gemini CLI">
|
|
21
22
|
</p>
|
|
22
23
|
<p align="center">
|
|
23
24
|
<a href="#-stop-re-explaining-your-project">Why</a> •
|
|
@@ -43,7 +44,7 @@ Your AI assistant forgets everything when you start a new chat. You spend 10 min
|
|
|
43
44
|
| **After 50 tool calls:** Context explodes, restart needed | **After restart:** Picks up right where you left off |
|
|
44
45
|
| **MCP configs:** Copy-paste between 7 IDEs manually | **MCP configs:** One command syncs everything |
|
|
45
46
|
|
|
46
|
-
**Memorix solves all of this.** One MCP server.
|
|
47
|
+
**Memorix solves all of this.** One MCP server. Eight agents. Zero context loss.
|
|
47
48
|
|
|
48
49
|
---
|
|
49
50
|
|
|
@@ -112,7 +113,7 @@ Add to Windsurf MCP settings (`~/.codeium/windsurf/mcp_config.json`):
|
|
|
112
113
|
</details>
|
|
113
114
|
|
|
114
115
|
<details>
|
|
115
|
-
<summary><strong>VS Code Copilot / Codex / Kiro
|
|
116
|
+
<summary><strong>VS Code Copilot / Codex / Kiro</strong></summary>
|
|
116
117
|
|
|
117
118
|
Same format — add to the agent's MCP config file:
|
|
118
119
|
```json
|
|
@@ -125,8 +126,24 @@ Same format — add to the agent's MCP config file:
|
|
|
125
126
|
}
|
|
126
127
|
}
|
|
127
128
|
```
|
|
129
|
+
</details>
|
|
130
|
+
|
|
131
|
+
<details>
|
|
132
|
+
<summary><strong>Antigravity / Gemini CLI</strong></summary>
|
|
128
133
|
|
|
129
|
-
|
|
134
|
+
Add to `.gemini/settings.json` (project) or `~/.gemini/settings.json` (global):
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"mcpServers": {
|
|
138
|
+
"memorix": {
|
|
139
|
+
"command": "memorix",
|
|
140
|
+
"args": ["serve"]
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Antigravity IDE only:** Antigravity uses its own install path as CWD. You **must** add:
|
|
130
147
|
```json
|
|
131
148
|
{
|
|
132
149
|
"mcpServers": {
|
|
@@ -140,13 +157,15 @@ Same format — add to the agent's MCP config file:
|
|
|
140
157
|
}
|
|
141
158
|
}
|
|
142
159
|
```
|
|
160
|
+
|
|
161
|
+
**Gemini CLI** reads MCP config from the same path. Hooks are automatically installed to `.gemini/settings.json`.
|
|
143
162
|
</details>
|
|
144
163
|
|
|
145
164
|
### Step 3: Restart your agent — done!
|
|
146
165
|
|
|
147
166
|
No API keys. No cloud accounts. No dependencies. Works with any directory (git repo or not).
|
|
148
167
|
|
|
149
|
-
> 📖 **Full setup guide for all
|
|
168
|
+
> 📖 **Full setup guide for all 8 agents** → [docs/SETUP.md](docs/SETUP.md)
|
|
150
169
|
|
|
151
170
|
<details>
|
|
152
171
|
<summary><strong>🔧 Troubleshooting</strong></summary>
|
|
@@ -293,7 +312,7 @@ You update your architecture decision 3 times over a week:
|
|
|
293
312
|
| What You Say | What Memorix Does |
|
|
294
313
|
|-------------|-------------------|
|
|
295
314
|
| "Sync my MCP servers to Kiro" | `memorix_workspace_sync` — Migrates configs, merges (never overwrites) |
|
|
296
|
-
| "Check my agent rules" | `memorix_rules_sync` — Scans
|
|
315
|
+
| "Check my agent rules" | `memorix_rules_sync` — Scans 8 agents, deduplicates, detects conflicts |
|
|
297
316
|
| "Generate rules for Cursor" | `memorix_rules_sync` — Cross-format conversion (`.mdc` ↔ `CLAUDE.md` ↔ `.kiro/steering/`) |
|
|
298
317
|
| "Generate project skills" | `memorix_skills` — Creates SKILL.md from observation patterns |
|
|
299
318
|
| "Inject the auth skill" | `memorix_skills` — Returns skill content directly into agent context |
|
package/README.zh-CN.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<a href="https://www.npmjs.com/package/memorix"><img src="https://img.shields.io/npm/dm/memorix.svg?style=flat-square&color=blue" alt="npm downloads"></a>
|
|
9
9
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-green.svg?style=flat-square" alt="License"></a>
|
|
10
10
|
<a href="https://github.com/AVIDS2/memorix"><img src="https://img.shields.io/github/stars/AVIDS2/memorix?style=flat-square&color=yellow" alt="GitHub stars"></a>
|
|
11
|
-
<img src="https://img.shields.io/badge/tests-
|
|
11
|
+
<img src="https://img.shields.io/badge/tests-491%20passed-brightgreen?style=flat-square" alt="Tests">
|
|
12
12
|
</p>
|
|
13
13
|
<p align="center">
|
|
14
14
|
<img src="https://img.shields.io/badge/Works%20with-Cursor-orange?style=flat-square" alt="Cursor">
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
<img src="https://img.shields.io/badge/Works%20with-Copilot-lightblue?style=flat-square" alt="Copilot">
|
|
19
19
|
<img src="https://img.shields.io/badge/Works%20with-Kiro-red?style=flat-square" alt="Kiro">
|
|
20
20
|
<img src="https://img.shields.io/badge/Works%20with-Antigravity-grey?style=flat-square" alt="Antigravity">
|
|
21
|
+
<img src="https://img.shields.io/badge/Works%20with-Gemini%20CLI-4285F4?style=flat-square" alt="Gemini CLI">
|
|
21
22
|
</p>
|
|
22
23
|
<p align="center">
|
|
23
24
|
<a href="#-别再反复解释你的项目了">痛点</a> •
|
|
@@ -41,9 +42,9 @@
|
|
|
41
42
|
| **切换 IDE:** 全部上下文丢失 | **切换 IDE:** 上下文立即跟随 |
|
|
42
43
|
| **新同事的 AI:** 从零开始 | **新同事的 AI:** 已了解整个代码库 |
|
|
43
44
|
| **50 次工具调用后:** 上下文爆炸,需要重开 | **重开后:** 无缝恢复到上次状态 |
|
|
44
|
-
| **MCP 配置:** 在
|
|
45
|
+
| **MCP 配置:** 在 8 个 IDE 之间手动复制粘贴 | **MCP 配置:** 一条命令全部同步 |
|
|
45
46
|
|
|
46
|
-
**Memorix 解决所有这些问题。** 一个 MCP
|
|
47
|
+
**Memorix 解决所有这些问题。** 一个 MCP 服务器。八个 Agent。零上下文丢失。
|
|
47
48
|
|
|
48
49
|
---
|
|
49
50
|
|
|
@@ -112,7 +113,7 @@ claude mcp add memorix -- memorix serve
|
|
|
112
113
|
</details>
|
|
113
114
|
|
|
114
115
|
<details>
|
|
115
|
-
<summary><strong>VS Code Copilot / Codex / Kiro
|
|
116
|
+
<summary><strong>VS Code Copilot / Codex / Kiro</strong></summary>
|
|
116
117
|
|
|
117
118
|
同样的格式 — 添加到对应 Agent 的 MCP 配置文件:
|
|
118
119
|
```json
|
|
@@ -125,8 +126,24 @@ claude mcp add memorix -- memorix serve
|
|
|
125
126
|
}
|
|
126
127
|
}
|
|
127
128
|
```
|
|
129
|
+
</details>
|
|
130
|
+
|
|
131
|
+
<details>
|
|
132
|
+
<summary><strong>Antigravity / Gemini CLI</strong></summary>
|
|
128
133
|
|
|
129
|
-
|
|
134
|
+
添加到 `.gemini/settings.json`(项目级)或 `~/.gemini/settings.json`(全局):
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"mcpServers": {
|
|
138
|
+
"memorix": {
|
|
139
|
+
"command": "memorix",
|
|
140
|
+
"args": ["serve"]
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**仅 Antigravity IDE:** Antigravity 使用自身安装路径作为工作目录,**必须**添加:
|
|
130
147
|
```json
|
|
131
148
|
{
|
|
132
149
|
"mcpServers": {
|
|
@@ -140,13 +157,15 @@ claude mcp add memorix -- memorix serve
|
|
|
140
157
|
}
|
|
141
158
|
}
|
|
142
159
|
```
|
|
160
|
+
|
|
161
|
+
**Gemini CLI** 读取相同路径的 MCP 配置。Hooks 会自动安装到 `.gemini/settings.json`。
|
|
143
162
|
</details>
|
|
144
163
|
|
|
145
164
|
### 第三步:重启你的 Agent — 完成!
|
|
146
165
|
|
|
147
166
|
不需要 API Key,不需要云账号,不需要额外依赖。**任何目录都能用**(有没有 git 都行)。
|
|
148
167
|
|
|
149
|
-
> 📖 **
|
|
168
|
+
> 📖 **8 个 Agent 的完整配置指南** → [docs/SETUP.md](docs/SETUP.md)
|
|
150
169
|
|
|
151
170
|
<details>
|
|
152
171
|
<summary><strong>🔧 常见问题</strong></summary>
|
package/dist/cli/index.js
CHANGED
|
@@ -39384,6 +39384,42 @@ function generateClaudeConfig() {
|
|
|
39384
39384
|
}
|
|
39385
39385
|
};
|
|
39386
39386
|
}
|
|
39387
|
+
function generateCopilotConfig() {
|
|
39388
|
+
const cmd = `${resolveHookCommand()} hook`;
|
|
39389
|
+
const hookEntry = {
|
|
39390
|
+
type: "command",
|
|
39391
|
+
bash: cmd,
|
|
39392
|
+
powershell: cmd,
|
|
39393
|
+
timeoutSec: 10
|
|
39394
|
+
};
|
|
39395
|
+
return {
|
|
39396
|
+
version: 1,
|
|
39397
|
+
hooks: {
|
|
39398
|
+
sessionStart: [hookEntry],
|
|
39399
|
+
sessionEnd: [hookEntry],
|
|
39400
|
+
userPromptSubmitted: [hookEntry],
|
|
39401
|
+
preToolUse: [hookEntry],
|
|
39402
|
+
postToolUse: [hookEntry],
|
|
39403
|
+
errorOccurred: [hookEntry]
|
|
39404
|
+
}
|
|
39405
|
+
};
|
|
39406
|
+
}
|
|
39407
|
+
function generateGeminiConfig() {
|
|
39408
|
+
const cmd = `${resolveHookCommand()} hook`;
|
|
39409
|
+
const hookEntry = {
|
|
39410
|
+
type: "command",
|
|
39411
|
+
command: cmd,
|
|
39412
|
+
timeout: 1e4
|
|
39413
|
+
};
|
|
39414
|
+
return {
|
|
39415
|
+
hooks: {
|
|
39416
|
+
SessionStart: [{ hooks: [hookEntry] }],
|
|
39417
|
+
AfterTool: [{ hooks: [hookEntry] }],
|
|
39418
|
+
AfterAgent: [{ hooks: [hookEntry] }],
|
|
39419
|
+
PreCompress: [{ hooks: [hookEntry] }]
|
|
39420
|
+
}
|
|
39421
|
+
};
|
|
39422
|
+
}
|
|
39387
39423
|
function generateWindsurfConfig() {
|
|
39388
39424
|
const cmd = `${resolveHookCommand()} hook`;
|
|
39389
39425
|
const hookEntry = {
|
|
@@ -39416,20 +39452,51 @@ function generateCursorConfig() {
|
|
|
39416
39452
|
}
|
|
39417
39453
|
};
|
|
39418
39454
|
}
|
|
39419
|
-
function
|
|
39420
|
-
|
|
39421
|
-
|
|
39422
|
-
|
|
39423
|
-
|
|
39424
|
-
|
|
39455
|
+
function generateKiroHookFiles() {
|
|
39456
|
+
const cmd = `${resolveHookCommand()} hook`;
|
|
39457
|
+
return [
|
|
39458
|
+
{
|
|
39459
|
+
filename: "memorix-agent-stop.kiro.hook",
|
|
39460
|
+
content: `---
|
|
39461
|
+
title: Memorix Session Memory
|
|
39462
|
+
description: Record session context when agent completes a turn
|
|
39463
|
+
event: agent_stop
|
|
39425
39464
|
---
|
|
39426
39465
|
|
|
39427
|
-
|
|
39466
|
+
Call memorix MCP tools to store important context from this conversation:
|
|
39467
|
+
1. Use memorix_store to record any decisions, bug fixes, gotchas, or configuration changes
|
|
39468
|
+
2. Include relevant file paths and concepts for searchability
|
|
39469
|
+
`
|
|
39470
|
+
},
|
|
39471
|
+
{
|
|
39472
|
+
filename: "memorix-prompt-submit.kiro.hook",
|
|
39473
|
+
content: `---
|
|
39474
|
+
title: Memorix Context Loader
|
|
39475
|
+
description: Load relevant memories when user submits a prompt
|
|
39476
|
+
event: prompt_submit
|
|
39477
|
+
---
|
|
39478
|
+
|
|
39479
|
+
Before responding, search for relevant context:
|
|
39480
|
+
1. Call memorix_search with a query related to the user's prompt
|
|
39481
|
+
2. If results are found, use memorix_detail to fetch the most relevant ones
|
|
39482
|
+
3. Reference relevant memories naturally in your response
|
|
39483
|
+
`
|
|
39484
|
+
},
|
|
39485
|
+
{
|
|
39486
|
+
filename: "memorix-file-save.kiro.hook",
|
|
39487
|
+
content: `---
|
|
39488
|
+
title: Memorix File Change Tracker
|
|
39489
|
+
description: Track significant file changes for cross-session memory
|
|
39490
|
+
event: file_save
|
|
39491
|
+
filePattern: "**/*.{ts,js,tsx,jsx,py,rs,go,java,md}"
|
|
39492
|
+
---
|
|
39428
39493
|
|
|
39429
39494
|
\`\`\`bash
|
|
39430
|
-
${
|
|
39495
|
+
${cmd}
|
|
39431
39496
|
\`\`\`
|
|
39432
|
-
|
|
39497
|
+
`
|
|
39498
|
+
}
|
|
39499
|
+
];
|
|
39433
39500
|
}
|
|
39434
39501
|
function getProjectConfigPath(agent, projectRoot) {
|
|
39435
39502
|
switch (agent) {
|
|
@@ -39442,9 +39509,11 @@ function getProjectConfigPath(agent, projectRoot) {
|
|
|
39442
39509
|
case "cursor":
|
|
39443
39510
|
return path6.join(projectRoot, ".cursor", "hooks.json");
|
|
39444
39511
|
case "kiro":
|
|
39445
|
-
return path6.join(projectRoot, ".kiro", "hooks", "memorix.hook
|
|
39512
|
+
return path6.join(projectRoot, ".kiro", "hooks", "memorix-agent-stop.kiro.hook");
|
|
39446
39513
|
case "codex":
|
|
39447
|
-
return path6.join(projectRoot, ".
|
|
39514
|
+
return path6.join(projectRoot, "AGENTS.md");
|
|
39515
|
+
case "antigravity":
|
|
39516
|
+
return path6.join(projectRoot, ".gemini", "settings.json");
|
|
39448
39517
|
default:
|
|
39449
39518
|
return path6.join(projectRoot, ".memorix", "hooks.json");
|
|
39450
39519
|
}
|
|
@@ -39459,6 +39528,8 @@ function getGlobalConfigPath(agent) {
|
|
|
39459
39528
|
return path6.join(home, ".codeium", "windsurf", "hooks.json");
|
|
39460
39529
|
case "cursor":
|
|
39461
39530
|
return path6.join(home, ".cursor", "hooks.json");
|
|
39531
|
+
case "antigravity":
|
|
39532
|
+
return path6.join(home, ".gemini", "settings.json");
|
|
39462
39533
|
default:
|
|
39463
39534
|
return path6.join(home, ".memorix", "hooks.json");
|
|
39464
39535
|
}
|
|
@@ -39504,9 +39575,9 @@ async function detectInstalledAgents() {
|
|
|
39504
39575
|
agents.push("codex");
|
|
39505
39576
|
} catch {
|
|
39506
39577
|
}
|
|
39507
|
-
const
|
|
39578
|
+
const geminiDir = path6.join(home, ".gemini");
|
|
39508
39579
|
try {
|
|
39509
|
-
await fs4.access(
|
|
39580
|
+
await fs4.access(geminiDir);
|
|
39510
39581
|
agents.push("antigravity");
|
|
39511
39582
|
} catch {
|
|
39512
39583
|
}
|
|
@@ -39517,24 +39588,42 @@ async function installHooks(agent, projectRoot, global = false) {
|
|
|
39517
39588
|
let generated;
|
|
39518
39589
|
switch (agent) {
|
|
39519
39590
|
case "claude":
|
|
39520
|
-
case "copilot":
|
|
39521
39591
|
generated = generateClaudeConfig();
|
|
39522
39592
|
break;
|
|
39593
|
+
case "copilot":
|
|
39594
|
+
generated = generateCopilotConfig();
|
|
39595
|
+
break;
|
|
39523
39596
|
case "windsurf":
|
|
39524
39597
|
generated = generateWindsurfConfig();
|
|
39525
39598
|
break;
|
|
39526
39599
|
case "cursor":
|
|
39527
39600
|
generated = generateCursorConfig();
|
|
39528
39601
|
break;
|
|
39602
|
+
case "antigravity":
|
|
39603
|
+
generated = generateGeminiConfig();
|
|
39604
|
+
break;
|
|
39529
39605
|
case "kiro":
|
|
39530
|
-
generated =
|
|
39606
|
+
generated = "kiro-multi";
|
|
39531
39607
|
break;
|
|
39608
|
+
case "codex":
|
|
39609
|
+
await installAgentRules(agent, projectRoot);
|
|
39610
|
+
return {
|
|
39611
|
+
agent,
|
|
39612
|
+
configPath: getProjectConfigPath(agent, projectRoot),
|
|
39613
|
+
events: [],
|
|
39614
|
+
generated: { note: "Codex has no hooks system, only rules (AGENTS.md) installed" }
|
|
39615
|
+
};
|
|
39532
39616
|
default:
|
|
39533
39617
|
generated = generateClaudeConfig();
|
|
39534
39618
|
}
|
|
39535
39619
|
await fs4.mkdir(path6.dirname(configPath), { recursive: true });
|
|
39536
39620
|
if (agent === "kiro") {
|
|
39537
|
-
|
|
39621
|
+
const hookFiles = generateKiroHookFiles();
|
|
39622
|
+
const hooksDir = path6.join(path6.dirname(configPath));
|
|
39623
|
+
await fs4.mkdir(hooksDir, { recursive: true });
|
|
39624
|
+
for (const hf of hookFiles) {
|
|
39625
|
+
await fs4.writeFile(path6.join(hooksDir, hf.filename), hf.content, "utf-8");
|
|
39626
|
+
}
|
|
39538
39627
|
} else {
|
|
39539
39628
|
let existing = {};
|
|
39540
39629
|
try {
|
|
@@ -39553,17 +39642,22 @@ async function installHooks(agent, projectRoot, global = false) {
|
|
|
39553
39642
|
const events = [];
|
|
39554
39643
|
switch (agent) {
|
|
39555
39644
|
case "claude":
|
|
39556
|
-
case "copilot":
|
|
39557
39645
|
events.push("session_start", "post_tool", "user_prompt", "pre_compact", "session_end");
|
|
39558
39646
|
break;
|
|
39647
|
+
case "copilot":
|
|
39648
|
+
events.push("session_start", "session_end", "user_prompt", "post_tool");
|
|
39649
|
+
break;
|
|
39559
39650
|
case "windsurf":
|
|
39560
39651
|
events.push("post_edit", "post_command", "post_tool", "user_prompt", "post_response");
|
|
39561
39652
|
break;
|
|
39562
39653
|
case "cursor":
|
|
39563
|
-
events.push("user_prompt", "post_edit", "session_end");
|
|
39654
|
+
events.push("session_start", "user_prompt", "post_edit", "post_tool", "pre_compact", "session_end");
|
|
39655
|
+
break;
|
|
39656
|
+
case "antigravity":
|
|
39657
|
+
events.push("session_start", "post_tool", "post_response", "pre_compact");
|
|
39564
39658
|
break;
|
|
39565
39659
|
case "kiro":
|
|
39566
|
-
events.push("post_edit");
|
|
39660
|
+
events.push("session_end", "user_prompt", "post_edit");
|
|
39567
39661
|
break;
|
|
39568
39662
|
}
|
|
39569
39663
|
await installAgentRules(agent, projectRoot);
|
|
@@ -43224,10 +43318,13 @@ var init_sync = __esm({
|
|
|
43224
43318
|
function detectAgent(payload) {
|
|
43225
43319
|
if ("agent_action_name" in payload) return "windsurf";
|
|
43226
43320
|
if ("conversation_id" in payload || "cursor_version" in payload) return "cursor";
|
|
43227
|
-
if ("
|
|
43228
|
-
if ("
|
|
43321
|
+
if ("gemini_session_id" in payload || "gemini_project_dir" in payload) return "antigravity";
|
|
43322
|
+
if ("hook_event_name" in payload && "session_id" in payload) return "claude";
|
|
43323
|
+
if ("hook_event_name" in payload) {
|
|
43324
|
+
return "claude";
|
|
43325
|
+
}
|
|
43326
|
+
if ("toolName" in payload || "initialPrompt" in payload || "reason" in payload) return "copilot";
|
|
43229
43327
|
if ("event_type" in payload) return "kiro";
|
|
43230
|
-
if ("hook_type" in payload) return "codex";
|
|
43231
43328
|
return "claude";
|
|
43232
43329
|
}
|
|
43233
43330
|
function extractEventName(payload, agent) {
|
|
@@ -43237,13 +43334,13 @@ function extractEventName(payload, agent) {
|
|
|
43237
43334
|
case "cursor":
|
|
43238
43335
|
return payload.hook_event_name ?? inferCursorEvent(payload);
|
|
43239
43336
|
case "claude":
|
|
43240
|
-
return payload.hook_event_name ??
|
|
43337
|
+
return payload.hook_event_name ?? "";
|
|
43338
|
+
case "antigravity":
|
|
43339
|
+
return payload.hook_event_name ?? "";
|
|
43241
43340
|
case "copilot":
|
|
43242
|
-
return payload
|
|
43341
|
+
return inferCopilotEvent(payload);
|
|
43243
43342
|
case "kiro":
|
|
43244
43343
|
return payload.event_type ?? "";
|
|
43245
|
-
case "codex":
|
|
43246
|
-
return payload.hook_type ?? "";
|
|
43247
43344
|
default:
|
|
43248
43345
|
return "";
|
|
43249
43346
|
}
|
|
@@ -43311,6 +43408,15 @@ function normalizeWindsurf(payload, event) {
|
|
|
43311
43408
|
}
|
|
43312
43409
|
return result;
|
|
43313
43410
|
}
|
|
43411
|
+
function inferCopilotEvent(payload) {
|
|
43412
|
+
if ("source" in payload && "initialPrompt" in payload) return "sessionStart";
|
|
43413
|
+
if ("reason" in payload && !("toolName" in payload)) return "sessionEnd";
|
|
43414
|
+
if ("prompt" in payload) return "userPromptSubmitted";
|
|
43415
|
+
if ("toolName" in payload && "toolResult" in payload) return "postToolUse";
|
|
43416
|
+
if ("toolName" in payload) return "preToolUse";
|
|
43417
|
+
if ("error" in payload) return "errorOccurred";
|
|
43418
|
+
return "";
|
|
43419
|
+
}
|
|
43314
43420
|
function inferCursorEvent(payload) {
|
|
43315
43421
|
if ("composer_mode" in payload) return "sessionStart";
|
|
43316
43422
|
if ("prompt" in payload) return "beforeSubmitPrompt";
|
|
@@ -43349,6 +43455,59 @@ function normalizeCursor(payload, event) {
|
|
|
43349
43455
|
}
|
|
43350
43456
|
return result;
|
|
43351
43457
|
}
|
|
43458
|
+
function normalizeCopilot(payload, event) {
|
|
43459
|
+
const result = {
|
|
43460
|
+
sessionId: "",
|
|
43461
|
+
cwd: payload.cwd ?? ""
|
|
43462
|
+
};
|
|
43463
|
+
switch (event) {
|
|
43464
|
+
case "session_start":
|
|
43465
|
+
result.userPrompt = payload.initialPrompt ?? "";
|
|
43466
|
+
break;
|
|
43467
|
+
case "user_prompt":
|
|
43468
|
+
result.userPrompt = payload.prompt ?? "";
|
|
43469
|
+
break;
|
|
43470
|
+
case "post_tool": {
|
|
43471
|
+
result.toolName = payload.toolName ?? "";
|
|
43472
|
+
const toolArgs = payload.toolArgs;
|
|
43473
|
+
if (toolArgs) {
|
|
43474
|
+
try {
|
|
43475
|
+
result.toolInput = JSON.parse(toolArgs);
|
|
43476
|
+
} catch {
|
|
43477
|
+
}
|
|
43478
|
+
}
|
|
43479
|
+
const toolResult = payload.toolResult;
|
|
43480
|
+
if (toolResult) {
|
|
43481
|
+
result.toolResult = toolResult.textResultForLlm ?? JSON.stringify(toolResult);
|
|
43482
|
+
}
|
|
43483
|
+
break;
|
|
43484
|
+
}
|
|
43485
|
+
case "session_end":
|
|
43486
|
+
break;
|
|
43487
|
+
}
|
|
43488
|
+
return result;
|
|
43489
|
+
}
|
|
43490
|
+
function normalizeGemini(payload, event) {
|
|
43491
|
+
const result = {
|
|
43492
|
+
sessionId: payload.gemini_session_id ?? payload.session_id ?? "",
|
|
43493
|
+
cwd: payload.cwd ?? payload.gemini_project_dir ?? ""
|
|
43494
|
+
};
|
|
43495
|
+
const toolName = payload.tool_name ?? "";
|
|
43496
|
+
if (toolName) {
|
|
43497
|
+
result.toolName = toolName;
|
|
43498
|
+
result.toolInput = payload.tool_input;
|
|
43499
|
+
const toolResponse = payload.tool_response ?? payload.tool_result;
|
|
43500
|
+
if (typeof toolResponse === "string") {
|
|
43501
|
+
result.toolResult = toolResponse;
|
|
43502
|
+
} else if (toolResponse && typeof toolResponse === "object") {
|
|
43503
|
+
result.toolResult = JSON.stringify(toolResponse);
|
|
43504
|
+
}
|
|
43505
|
+
}
|
|
43506
|
+
if (event === "user_prompt") {
|
|
43507
|
+
result.userPrompt = payload.prompt ?? "";
|
|
43508
|
+
}
|
|
43509
|
+
return result;
|
|
43510
|
+
}
|
|
43352
43511
|
function normalizeHookInput(payload) {
|
|
43353
43512
|
const directEvent = typeof payload.event === "string" ? EVENT_MAP[payload.event] : void 0;
|
|
43354
43513
|
const agent = detectAgent(payload);
|
|
@@ -43358,15 +43517,20 @@ function normalizeHookInput(payload) {
|
|
|
43358
43517
|
let agentSpecific = {};
|
|
43359
43518
|
switch (agent) {
|
|
43360
43519
|
case "claude":
|
|
43361
|
-
case "copilot":
|
|
43362
43520
|
agentSpecific = normalizeClaude(payload, event);
|
|
43363
43521
|
break;
|
|
43522
|
+
case "copilot":
|
|
43523
|
+
agentSpecific = normalizeCopilot(payload, event);
|
|
43524
|
+
break;
|
|
43364
43525
|
case "windsurf":
|
|
43365
43526
|
agentSpecific = normalizeWindsurf(payload, event);
|
|
43366
43527
|
break;
|
|
43367
43528
|
case "cursor":
|
|
43368
43529
|
agentSpecific = normalizeCursor(payload, event);
|
|
43369
43530
|
break;
|
|
43531
|
+
case "antigravity":
|
|
43532
|
+
agentSpecific = normalizeGemini(payload, event);
|
|
43533
|
+
break;
|
|
43370
43534
|
default:
|
|
43371
43535
|
agentSpecific = { sessionId: "", cwd: "" };
|
|
43372
43536
|
}
|
|
@@ -43396,7 +43560,7 @@ var init_normalizer = __esm({
|
|
|
43396
43560
|
pre_compact: "pre_compact",
|
|
43397
43561
|
session_end: "session_end",
|
|
43398
43562
|
post_response: "post_response",
|
|
43399
|
-
// Claude Code
|
|
43563
|
+
// Claude Code
|
|
43400
43564
|
SessionStart: "session_start",
|
|
43401
43565
|
UserPromptSubmit: "user_prompt",
|
|
43402
43566
|
PreToolUse: "post_tool",
|
|
@@ -43404,6 +43568,22 @@ var init_normalizer = __esm({
|
|
|
43404
43568
|
PostToolUse: "post_tool",
|
|
43405
43569
|
PreCompact: "pre_compact",
|
|
43406
43570
|
Stop: "session_end",
|
|
43571
|
+
SessionEnd: "session_end",
|
|
43572
|
+
// GitHub Copilot (camelCase, different names from Cursor)
|
|
43573
|
+
userPromptSubmitted: "user_prompt",
|
|
43574
|
+
preToolUse: "post_tool",
|
|
43575
|
+
postToolUse: "post_tool",
|
|
43576
|
+
errorOccurred: "session_end",
|
|
43577
|
+
// Gemini CLI / Antigravity (PascalCase, different events from Claude Code)
|
|
43578
|
+
BeforeAgent: "user_prompt",
|
|
43579
|
+
AfterAgent: "post_response",
|
|
43580
|
+
BeforeModel: "user_prompt",
|
|
43581
|
+
AfterModel: "post_response",
|
|
43582
|
+
BeforeToolSelection: "post_tool",
|
|
43583
|
+
BeforeTool: "post_tool",
|
|
43584
|
+
AfterTool: "post_tool",
|
|
43585
|
+
PreCompress: "pre_compact",
|
|
43586
|
+
Notification: "post_response",
|
|
43407
43587
|
// Windsurf
|
|
43408
43588
|
pre_user_prompt: "user_prompt",
|
|
43409
43589
|
post_write_code: "post_edit",
|
|
@@ -43412,7 +43592,7 @@ var init_normalizer = __esm({
|
|
|
43412
43592
|
pre_mcp_tool_use: "post_tool",
|
|
43413
43593
|
post_mcp_tool_use: "post_tool",
|
|
43414
43594
|
post_cascade_response: "post_response",
|
|
43415
|
-
// Cursor (camelCase event names)
|
|
43595
|
+
// Cursor (camelCase event names — distinct from Copilot by hook_event_name field)
|
|
43416
43596
|
sessionStart: "session_start",
|
|
43417
43597
|
sessionEnd: "session_end",
|
|
43418
43598
|
beforeSubmitPrompt: "user_prompt",
|