memorix 0.3.8 → 0.4.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/README.md CHANGED
@@ -2,21 +2,24 @@
2
2
 
3
3
  > Universal memory layer for AI coding agents via MCP
4
4
 
5
+ [![npm version](https://img.shields.io/npm/v/memorix.svg)](https://www.npmjs.com/package/memorix)
6
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
7
+
5
8
  ## What is Memorix?
6
9
 
7
- Memorix is a lightweight local MCP server that acts as a **universal memory layer** across AI coding agents. Your knowledge from Cursor, Claude Code, Codex, and Windsurf is stored once and shared everywhere.
10
+ Memorix is a lightweight local MCP server that acts as a **universal memory layer** across AI coding agents. Your knowledge from **Windsurf, Cursor, Claude Code, Codex, and VS Code Copilot** is stored once and shared everywhere.
8
11
 
9
12
  ### The Problem
10
13
 
11
14
  - claude-mem only serves Claude Code
12
- - memU only serves OpenClaw
15
+ - mcp-memory-service has no cross-agent workspace sync
13
16
  - Your architecture decisions in Cursor are invisible to Claude Code
14
17
  - Bug fix knowledge in Windsurf doesn't transfer to Codex
15
- - **No one does cross-agent memory**
18
+ - **No one bridges memory AND workspace configs across agents**
16
19
 
17
20
  ### The Solution
18
21
 
19
- Memorix stores and indexes project knowledge (architecture decisions, bug fixes, code style preferences) and exposes it via MCP — so **any MCP-supporting agent** can access it.
22
+ Memorix stores and indexes project knowledge (architecture decisions, bug fixes, code style preferences) and exposes it via MCP — so **any MCP-supporting agent** can access it. It also **syncs MCP configs, rules, skills, and workflows** across all your agents automatically.
20
23
 
21
24
  ## Features
22
25
 
@@ -39,18 +42,21 @@ Memorix stores and indexes project knowledge (architecture decisions, bug fixes,
39
42
  - **Graceful Degradation**: No fastembed? Falls back to BM25 fulltext automatically
40
43
  - **Token Budget**: `maxTokens` parameter trims results to fit context windows
41
44
 
42
- ### P2 — Cross-Agent Sync
45
+ ### P2 — Cross-Agent Workspace Sync
43
46
 
47
+ - **5 Agent Adapters**: Windsurf, Cursor, Claude Code, Codex, VS Code Copilot
48
+ - **MCP Config Sync**: Detect and migrate MCP server configs across agents (merges into existing files — never overwrites)
44
49
  - **Rules Parser**: 4 format adapters (Cursor `.mdc`, Claude Code `CLAUDE.md`, Codex `SKILL.md`, Windsurf `.windsurfrules`)
45
50
  - **Rules Syncer**: Scan → Deduplicate → Conflict detection → Cross-format generation
46
- - **Workspace Sync**: MCP config migration + workflow sync across agents
47
- - **Skills Sync**: Scan `.codex/skills/`, `.cursor/skills/`, `.windsurf/skills/`, `.claude/skills/` copy entire skill folders across agents (no format conversion needed — SKILL.md is a universal standard)
51
+ - **Skills Sync**: Scan `.codex/skills/`, `.cursor/skills/`, `.windsurf/skills/`, `.claude/skills/` copy entire skill folders across agents
52
+ - **Sync Advisory**: On first `memorix_search`, auto-detects available configs/skills from other agents and prompts the user
53
+ - **Selective Sync**: Sync specific items by name (e.g. `items=["figma-remote-mcp-server", "create-subagent"]`)
48
54
  - **Apply with Safety**: Backup → Atomic write → Auto-rollback on failure
49
55
 
50
56
  ### P3 — Auto-Memory Hooks
51
57
 
52
58
  - **Hook Events**: `user_prompt`, `post_response`, `post_edit`, `post_command`, `post_tool`, `session_end`
53
- - **Agent Normalizer**: Maps Windsurf/Cursor/Claude/Codex native events to unified hook events
59
+ - **Agent Normalizer**: Maps Windsurf/Cursor/Claude Code/Codex native events to unified hook events
54
60
  - **Pattern Detection**: Auto-detects decisions, errors, gotchas, configurations, learnings, implementations
55
61
  - **Cooldown Filtering**: Prevents duplicate storage within configurable time windows
56
62
  - **Noise Filtering**: Skips trivial commands (`ls`, `cat`, `pwd`, etc.)
@@ -80,42 +86,63 @@ Memorix stores and indexes project knowledge (architecture decisions, bug fixes,
80
86
  ### Install
81
87
 
82
88
  ```bash
83
- npm install memorix
89
+ npm install -g memorix
84
90
  ```
85
91
 
86
92
  ### Configure in your agent
87
93
 
88
- **Cursor** (`.cursor/mcp.json`):
94
+ **Windsurf** (`~/.codeium/windsurf/mcp_config.json`):
89
95
  ```json
90
96
  {
91
97
  "mcpServers": {
92
98
  "memorix": {
93
- "command": "node",
94
- "args": ["node_modules/memorix/dist/index.js"]
99
+ "command": "memorix",
100
+ "args": ["serve"]
95
101
  }
96
102
  }
97
103
  }
98
104
  ```
99
105
 
100
- **Claude Code** (`claude_desktop_config.json`):
106
+ **Cursor** (`.cursor/mcp.json`):
101
107
  ```json
102
108
  {
103
109
  "mcpServers": {
104
110
  "memorix": {
105
- "command": "node",
106
- "args": ["node_modules/memorix/dist/index.js"]
111
+ "command": "memorix",
112
+ "args": ["serve"]
107
113
  }
108
114
  }
109
115
  }
110
116
  ```
111
117
 
112
- **Windsurf** (`~/.codeium/windsurf/mcp_config.json`):
118
+ **Claude Code** (`~/.claude.json`):
113
119
  ```json
114
120
  {
115
121
  "mcpServers": {
116
122
  "memorix": {
117
- "command": "node",
118
- "args": ["node_modules/memorix/dist/index.js"]
123
+ "command": "memorix",
124
+ "args": ["serve"]
125
+ }
126
+ }
127
+ }
128
+ ```
129
+
130
+ **Codex** (`~/.codex/config.toml`):
131
+ ```toml
132
+ [mcp_servers.memorix]
133
+ command = "memorix"
134
+ args = ["serve"]
135
+ ```
136
+
137
+ **VS Code Copilot** (VS Code `settings.json` or `.vscode/mcp.json`):
138
+ ```json
139
+ {
140
+ "mcp": {
141
+ "servers": {
142
+ "memorix": {
143
+ "command": "memorix",
144
+ "args": ["serve"]
145
+ }
119
146
  }
120
147
  }
121
148
  }
@@ -154,7 +181,7 @@ npm install memorix
154
181
  ```
155
182
  ┌─────────────────────────────────────────────┐
156
183
  │ MCP Clients │
157
- Cursor Claude Code Codex Windsurf
184
+ WindsurfCursor│Claude Code│Codex│Copilot
158
185
  └──────────────────┬──────────────────────────┘
159
186
  │ stdio
160
187
  ┌──────────────────▼──────────────────────────┐
@@ -177,7 +204,7 @@ npm install memorix
177
204
  │ │
178
205
  │ ┌────────────────────────────────────┐ │
179
206
  │ │ Rules & Skills Syncer │ │
180
- │ │ Cursor│Claude│Codex│Windsurf
207
+ │ │ Cursor│Claude Code│Codex│Windsurf│Copilot
181
208
  │ │ rules: scan→dedup→conflict→gen │ │
182
209
  │ │ skills: scan→copy (no convert) │ │
183
210
  │ └────────────────────────────────────┘ │
@@ -246,4 +273,4 @@ Memorix stands on the shoulders of these excellent projects:
246
273
 
247
274
  ## License
248
275
 
249
- MIT
276
+ Apache 2.0 — see [LICENSE](LICENSE)
package/dist/cli/index.js CHANGED
@@ -1520,6 +1520,93 @@ var init_windsurf = __esm({
1520
1520
  }
1521
1521
  });
1522
1522
 
1523
+ // src/rules/adapters/antigravity.ts
1524
+ import matter5 from "gray-matter";
1525
+ var AntigravityAdapter;
1526
+ var init_antigravity = __esm({
1527
+ "src/rules/adapters/antigravity.ts"() {
1528
+ "use strict";
1529
+ init_esm_shims();
1530
+ init_utils();
1531
+ AntigravityAdapter = class {
1532
+ source = "antigravity";
1533
+ filePatterns = [
1534
+ "GEMINI.md",
1535
+ ".agent/rules/*.md",
1536
+ ".agent/skills/*/SKILL.md"
1537
+ ];
1538
+ parse(filePath, content) {
1539
+ if (filePath.includes("SKILL.md")) {
1540
+ return this.parseSkillMd(filePath, content);
1541
+ }
1542
+ if (filePath.includes(".agent/rules/")) {
1543
+ return this.parseAgentRule(filePath, content);
1544
+ }
1545
+ if (filePath === "GEMINI.md" || filePath.endsWith("/GEMINI.md")) {
1546
+ return this.parseGeminiMd(filePath, content);
1547
+ }
1548
+ return [];
1549
+ }
1550
+ generate(rules) {
1551
+ const projectRules = rules.filter((r) => r.scope !== "path-specific");
1552
+ const pathRules = rules.filter((r) => r.scope === "path-specific");
1553
+ const files = [];
1554
+ for (const rule of [...projectRules, ...pathRules]) {
1555
+ const fm = {};
1556
+ if (rule.description) fm.description = rule.description;
1557
+ const fileName = rule.id.replace(/^antigravity:/, "").replace(/[^a-zA-Z0-9-_]/g, "-") || "rule";
1558
+ const body = Object.keys(fm).length > 0 ? matter5.stringify(rule.content, fm) : rule.content;
1559
+ files.push({
1560
+ filePath: `.agent/rules/${fileName}.md`,
1561
+ content: body
1562
+ });
1563
+ }
1564
+ return files;
1565
+ }
1566
+ parseGeminiMd(filePath, content) {
1567
+ const trimmed = content.trim();
1568
+ if (!trimmed) return [];
1569
+ return [{
1570
+ id: generateRuleId("antigravity", filePath),
1571
+ content: trimmed,
1572
+ source: "antigravity",
1573
+ scope: "global",
1574
+ priority: 10,
1575
+ hash: hashContent(trimmed)
1576
+ }];
1577
+ }
1578
+ parseAgentRule(filePath, content) {
1579
+ const { data, content: body } = matter5(content);
1580
+ const trimmed = body.trim();
1581
+ if (!trimmed) return [];
1582
+ return [{
1583
+ id: generateRuleId("antigravity", filePath),
1584
+ content: trimmed,
1585
+ description: data.description,
1586
+ source: "antigravity",
1587
+ scope: "project",
1588
+ priority: 5,
1589
+ hash: hashContent(trimmed)
1590
+ }];
1591
+ }
1592
+ parseSkillMd(filePath, content) {
1593
+ const { data, content: body } = matter5(content);
1594
+ const trimmed = body.trim();
1595
+ if (!trimmed) return [];
1596
+ return [{
1597
+ id: generateRuleId("antigravity", filePath),
1598
+ content: trimmed,
1599
+ description: data.description || void 0,
1600
+ source: "antigravity",
1601
+ scope: "project",
1602
+ priority: 5,
1603
+ hash: hashContent(trimmed)
1604
+ }];
1605
+ }
1606
+ };
1607
+ }
1608
+ });
1609
+
1523
1610
  // src/rules/syncer.ts
1524
1611
  var syncer_exports = {};
1525
1612
  __export(syncer_exports, {
@@ -1536,6 +1623,7 @@ var init_syncer = __esm({
1536
1623
  init_claude_code();
1537
1624
  init_codex();
1538
1625
  init_windsurf();
1626
+ init_antigravity();
1539
1627
  RulesSyncer = class {
1540
1628
  projectRoot;
1541
1629
  adapters;
@@ -1546,7 +1634,8 @@ var init_syncer = __esm({
1546
1634
  new CursorAdapter(),
1547
1635
  new ClaudeCodeAdapter(),
1548
1636
  new CodexAdapter(),
1549
- new WindsurfAdapter()
1637
+ new WindsurfAdapter(),
1638
+ new AntigravityAdapter()
1550
1639
  ];
1551
1640
  for (const a of all) {
1552
1641
  this.adapters.set(a.source, a);
@@ -2085,8 +2174,78 @@ var init_copilot = __esm({
2085
2174
  }
2086
2175
  });
2087
2176
 
2177
+ // src/workspace/mcp-adapters/antigravity.ts
2178
+ import { homedir as homedir6 } from "os";
2179
+ import { join as join6 } from "path";
2180
+ var AntigravityMCPAdapter;
2181
+ var init_antigravity2 = __esm({
2182
+ "src/workspace/mcp-adapters/antigravity.ts"() {
2183
+ "use strict";
2184
+ init_esm_shims();
2185
+ AntigravityMCPAdapter = class {
2186
+ source = "antigravity";
2187
+ parse(content) {
2188
+ try {
2189
+ const config = JSON.parse(content);
2190
+ const servers = config.mcpServers ?? config.mcp_servers ?? {};
2191
+ return Object.entries(servers).map(([name, entry]) => {
2192
+ const result = {
2193
+ name,
2194
+ command: entry.command ?? "",
2195
+ args: entry.args ?? []
2196
+ };
2197
+ if (entry.serverUrl) {
2198
+ result.url = entry.serverUrl;
2199
+ } else if (entry.url) {
2200
+ result.url = entry.url;
2201
+ }
2202
+ if (entry.headers && typeof entry.headers === "object" && Object.keys(entry.headers).length > 0) {
2203
+ result.headers = entry.headers;
2204
+ }
2205
+ if (entry.env && typeof entry.env === "object" && Object.keys(entry.env).length > 0) {
2206
+ result.env = entry.env;
2207
+ }
2208
+ if (entry.disabled === true) {
2209
+ result.disabled = true;
2210
+ }
2211
+ return result;
2212
+ });
2213
+ } catch {
2214
+ return [];
2215
+ }
2216
+ }
2217
+ generate(servers) {
2218
+ const mcpServers = {};
2219
+ for (const s of servers) {
2220
+ const entry = {};
2221
+ if (s.url) {
2222
+ entry.url = s.url;
2223
+ if (s.headers && Object.keys(s.headers).length > 0) {
2224
+ entry.headers = s.headers;
2225
+ }
2226
+ } else {
2227
+ entry.command = s.command;
2228
+ entry.args = s.args;
2229
+ }
2230
+ if (s.env && Object.keys(s.env).length > 0) {
2231
+ entry.env = s.env;
2232
+ }
2233
+ if (s.disabled === true) {
2234
+ entry.disabled = true;
2235
+ }
2236
+ mcpServers[s.name] = entry;
2237
+ }
2238
+ return JSON.stringify({ mcpServers }, null, 2);
2239
+ }
2240
+ getConfigPath(_projectRoot) {
2241
+ return join6(homedir6(), ".gemini", "antigravity", "mcp_config.json");
2242
+ }
2243
+ };
2244
+ }
2245
+ });
2246
+
2088
2247
  // src/workspace/workflow-sync.ts
2089
- import matter5 from "gray-matter";
2248
+ import matter6 from "gray-matter";
2090
2249
  var WorkflowSyncer;
2091
2250
  var init_workflow_sync = __esm({
2092
2251
  "src/workspace/workflow-sync.ts"() {
@@ -2101,7 +2260,7 @@ var init_workflow_sync = __esm({
2101
2260
  let description = "";
2102
2261
  let content = raw;
2103
2262
  try {
2104
- const parsed = matter5(raw);
2263
+ const parsed = matter6(raw);
2105
2264
  description = parsed.data?.description ?? "";
2106
2265
  content = parsed.content.trim();
2107
2266
  } catch {
@@ -2123,7 +2282,7 @@ var init_workflow_sync = __esm({
2123
2282
  if (wf.description) {
2124
2283
  fm.description = wf.description;
2125
2284
  }
2126
- const content = matter5.stringify(wf.content, fm);
2285
+ const content = matter6.stringify(wf.content, fm);
2127
2286
  return {
2128
2287
  filePath: `.agents/skills/${safeName}/SKILL.md`,
2129
2288
  content
@@ -2140,7 +2299,7 @@ var init_workflow_sync = __esm({
2140
2299
  }
2141
2300
  fm.globs = "";
2142
2301
  fm.alwaysApply = "false";
2143
- const content = matter5.stringify(wf.content, fm);
2302
+ const content = matter6.stringify(wf.content, fm);
2144
2303
  return {
2145
2304
  filePath: `.cursor/rules/${safeName}.mdc`,
2146
2305
  content
@@ -2328,8 +2487,8 @@ var init_applier = __esm({
2328
2487
 
2329
2488
  // src/workspace/engine.ts
2330
2489
  import { readFileSync as readFileSync2, readdirSync, existsSync as existsSync4, cpSync, mkdirSync as mkdirSync2 } from "fs";
2331
- import { join as join7 } from "path";
2332
- import { homedir as homedir6 } from "os";
2490
+ import { join as join8 } from "path";
2491
+ import { homedir as homedir7 } from "os";
2333
2492
  var WorkspaceSyncEngine;
2334
2493
  var init_engine2 = __esm({
2335
2494
  "src/workspace/engine.ts"() {
@@ -2340,6 +2499,7 @@ var init_engine2 = __esm({
2340
2499
  init_codex2();
2341
2500
  init_claude_code2();
2342
2501
  init_copilot();
2502
+ init_antigravity2();
2343
2503
  init_workflow_sync();
2344
2504
  init_syncer();
2345
2505
  init_sanitizer();
@@ -2352,7 +2512,8 @@ var init_engine2 = __esm({
2352
2512
  ["cursor", new CursorMCPAdapter()],
2353
2513
  ["codex", new CodexMCPAdapter()],
2354
2514
  ["claude-code", new ClaudeCodeMCPAdapter()],
2355
- ["copilot", new CopilotMCPAdapter()]
2515
+ ["copilot", new CopilotMCPAdapter()],
2516
+ ["antigravity", new AntigravityMCPAdapter()]
2356
2517
  ]);
2357
2518
  this.workflowSyncer = new WorkflowSyncer();
2358
2519
  this.rulesSyncer = new RulesSyncer(projectRoot);
@@ -2369,7 +2530,8 @@ var init_engine2 = __esm({
2369
2530
  cursor: [],
2370
2531
  codex: [],
2371
2532
  "claude-code": [],
2372
- copilot: []
2533
+ copilot: [],
2534
+ antigravity: []
2373
2535
  };
2374
2536
  for (const [target, adapter] of this.adapters) {
2375
2537
  const configPath = adapter.getConfigPath(this.projectRoot);
@@ -2460,13 +2622,14 @@ var init_engine2 = __esm({
2460
2622
  cursor: [".cursor/skills", ".cursor/skills-cursor"],
2461
2623
  windsurf: [".windsurf/skills"],
2462
2624
  "claude-code": [".claude/skills"],
2463
- copilot: []
2625
+ copilot: [],
2626
+ antigravity: [".agent/skills", ".gemini/skills", ".gemini/antigravity/skills"]
2464
2627
  };
2465
2628
  /** Get the target skills directory for an agent (null if agent has no skills support) */
2466
2629
  getTargetSkillsDir(target) {
2467
2630
  const dirs = _WorkspaceSyncEngine.SKILLS_DIRS[target];
2468
2631
  if (!dirs || dirs.length === 0) return null;
2469
- return join7(this.projectRoot, dirs[0]);
2632
+ return join8(this.projectRoot, dirs[0]);
2470
2633
  }
2471
2634
  /**
2472
2635
  * Scan all agent skills directories and collect unique skills.
@@ -2475,12 +2638,12 @@ var init_engine2 = __esm({
2475
2638
  const skills = [];
2476
2639
  const conflicts = [];
2477
2640
  const seen = /* @__PURE__ */ new Map();
2478
- const home = homedir6();
2641
+ const home = homedir7();
2479
2642
  for (const [agent, dirs] of Object.entries(_WorkspaceSyncEngine.SKILLS_DIRS)) {
2480
2643
  for (const dir of dirs) {
2481
2644
  const paths = [
2482
- join7(this.projectRoot, dir),
2483
- join7(home, dir)
2645
+ join8(this.projectRoot, dir),
2646
+ join8(home, dir)
2484
2647
  ];
2485
2648
  for (const skillsRoot of paths) {
2486
2649
  if (!existsSync4(skillsRoot)) continue;
@@ -2488,7 +2651,7 @@ var init_engine2 = __esm({
2488
2651
  const entries = readdirSync(skillsRoot, { withFileTypes: true });
2489
2652
  for (const entry of entries) {
2490
2653
  if (!entry.isDirectory()) continue;
2491
- const skillMd = join7(skillsRoot, entry.name, "SKILL.md");
2654
+ const skillMd = join8(skillsRoot, entry.name, "SKILL.md");
2492
2655
  if (!existsSync4(skillMd)) continue;
2493
2656
  let description = "";
2494
2657
  try {
@@ -2500,7 +2663,7 @@ var init_engine2 = __esm({
2500
2663
  const newEntry = {
2501
2664
  name: entry.name,
2502
2665
  description,
2503
- sourcePath: join7(skillsRoot, entry.name),
2666
+ sourcePath: join8(skillsRoot, entry.name),
2504
2667
  sourceAgent: agent
2505
2668
  };
2506
2669
  const existing = seen.get(entry.name);
@@ -2537,7 +2700,7 @@ var init_engine2 = __esm({
2537
2700
  }
2538
2701
  for (const skill of skills) {
2539
2702
  if (skill.sourceAgent === target) continue;
2540
- const dest = join7(targetDir, skill.name);
2703
+ const dest = join8(targetDir, skill.name);
2541
2704
  if (existsSync4(dest)) {
2542
2705
  skipped.push(`${skill.name} (already exists in ${target})`);
2543
2706
  continue;
@@ -2553,13 +2716,13 @@ var init_engine2 = __esm({
2553
2716
  }
2554
2717
  scanWorkflows() {
2555
2718
  const workflows = [];
2556
- const wfDir = join7(this.projectRoot, ".windsurf", "workflows");
2719
+ const wfDir = join8(this.projectRoot, ".windsurf", "workflows");
2557
2720
  if (!existsSync4(wfDir)) return workflows;
2558
2721
  try {
2559
2722
  const files = readdirSync(wfDir).filter((f) => f.endsWith(".md"));
2560
2723
  for (const file of files) {
2561
2724
  try {
2562
- const content = readFileSync2(join7(wfDir, file), "utf-8");
2725
+ const content = readFileSync2(join8(wfDir, file), "utf-8");
2563
2726
  workflows.push(this.workflowSyncer.parseWindsurfWorkflow(file, content));
2564
2727
  } catch {
2565
2728
  }
@@ -2646,7 +2809,8 @@ var init_engine2 = __esm({
2646
2809
  "claude-code": "claude-code",
2647
2810
  codex: "codex",
2648
2811
  windsurf: "windsurf",
2649
- copilot: "windsurf"
2812
+ copilot: "windsurf",
2813
+ antigravity: "antigravity"
2650
2814
  };
2651
2815
  return map[target] ?? null;
2652
2816
  }
@@ -3583,12 +3747,12 @@ Entity: ${entityName} | Type: ${type} | Project: ${project.id}${enrichment}`
3583
3747
  };
3584
3748
  }
3585
3749
  );
3586
- const RULE_SOURCES = ["cursor", "claude-code", "codex", "windsurf"];
3750
+ const RULE_SOURCES = ["cursor", "claude-code", "codex", "windsurf", "antigravity"];
3587
3751
  server.registerTool(
3588
3752
  "memorix_rules_sync",
3589
3753
  {
3590
3754
  title: "Rules Sync",
3591
- description: "Scan project for agent rule files (Cursor, Claude Code, Codex, Windsurf), deduplicate, detect conflicts, and optionally generate rules for a target agent format. Without target: returns sync status report. With target: generates converted rule files.",
3755
+ description: "Scan project for agent rule files (Cursor, Claude Code, Codex, Windsurf, Antigravity), deduplicate, detect conflicts, and optionally generate rules for a target agent format. Without target: returns sync status report. With target: generates converted rule files.",
3592
3756
  inputSchema: {
3593
3757
  action: z.enum(["status", "generate"]).describe('Action: "status" for report, "generate" to produce target files'),
3594
3758
  target: z.enum(RULE_SOURCES).optional().describe("Target agent format for generation (required when action=generate)")
@@ -3638,7 +3802,7 @@ Entity: ${entityName} | Type: ${type} | Project: ${project.id}${enrichment}`
3638
3802
  };
3639
3803
  }
3640
3804
  );
3641
- const AGENT_TARGETS = ["windsurf", "cursor", "claude-code", "codex", "copilot"];
3805
+ const AGENT_TARGETS = ["windsurf", "cursor", "claude-code", "codex", "copilot", "antigravity"];
3642
3806
  server.registerTool(
3643
3807
  "memorix_workspace_sync",
3644
3808
  {
@@ -3882,7 +4046,8 @@ var init_sync = __esm({
3882
4046
  cursor: "Cursor (.cursor/rules/*.mdc, .cursorrules)",
3883
4047
  "claude-code": "Claude Code (CLAUDE.md, .claude/rules/*.md)",
3884
4048
  codex: "Codex (SKILL.md, AGENTS.md)",
3885
- windsurf: "Windsurf (.windsurfrules, .windsurf/rules/*.md)"
4049
+ windsurf: "Windsurf (.windsurfrules, .windsurf/rules/*.md)",
4050
+ antigravity: "Antigravity (.agent/rules/*.md, GEMINI.md)"
3886
4051
  };
3887
4052
  sync_default = defineCommand3({
3888
4053
  meta: {
@@ -3892,7 +4057,7 @@ var init_sync = __esm({
3892
4057
  args: {
3893
4058
  target: {
3894
4059
  type: "string",
3895
- description: "Target agent format (cursor, claude-code, codex, windsurf)",
4060
+ description: "Target agent format (cursor, claude-code, codex, windsurf, antigravity)",
3896
4061
  required: false
3897
4062
  },
3898
4063
  dry: {
@@ -3935,11 +4100,11 @@ var init_sync = __esm({
3935
4100
  }
3936
4101
  let target = args.target;
3937
4102
  if (!target) {
3938
- const available = ["cursor", "claude-code", "codex", "windsurf"].filter(
4103
+ const available = ["cursor", "claude-code", "codex", "windsurf", "antigravity"].filter(
3939
4104
  (t) => !sources.includes(t)
3940
4105
  );
3941
4106
  if (available.length === 0) {
3942
- available.push("cursor", "claude-code", "codex", "windsurf");
4107
+ available.push("cursor", "claude-code", "codex", "windsurf", "antigravity");
3943
4108
  }
3944
4109
  const selected = await p2.select({
3945
4110
  message: "Generate rules for which agent?",
@@ -4706,7 +4871,7 @@ import { defineCommand as defineCommand9, runMain } from "citty";
4706
4871
  var main = defineCommand9({
4707
4872
  meta: {
4708
4873
  name: "memorix",
4709
- version: "0.3.8",
4874
+ version: "0.3.9",
4710
4875
  description: "Cross-Agent Memory Bridge \u2014 Universal memory layer for AI coding agents via MCP"
4711
4876
  },
4712
4877
  subCommands: {