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/dist/index.js CHANGED
@@ -1876,6 +1876,86 @@ var WindsurfAdapter = class {
1876
1876
  }
1877
1877
  };
1878
1878
 
1879
+ // src/rules/adapters/antigravity.ts
1880
+ init_esm_shims();
1881
+ import matter5 from "gray-matter";
1882
+ var AntigravityAdapter = class {
1883
+ source = "antigravity";
1884
+ filePatterns = [
1885
+ "GEMINI.md",
1886
+ ".agent/rules/*.md",
1887
+ ".agent/skills/*/SKILL.md"
1888
+ ];
1889
+ parse(filePath, content) {
1890
+ if (filePath.includes("SKILL.md")) {
1891
+ return this.parseSkillMd(filePath, content);
1892
+ }
1893
+ if (filePath.includes(".agent/rules/")) {
1894
+ return this.parseAgentRule(filePath, content);
1895
+ }
1896
+ if (filePath === "GEMINI.md" || filePath.endsWith("/GEMINI.md")) {
1897
+ return this.parseGeminiMd(filePath, content);
1898
+ }
1899
+ return [];
1900
+ }
1901
+ generate(rules) {
1902
+ const projectRules = rules.filter((r) => r.scope !== "path-specific");
1903
+ const pathRules = rules.filter((r) => r.scope === "path-specific");
1904
+ const files = [];
1905
+ for (const rule of [...projectRules, ...pathRules]) {
1906
+ const fm = {};
1907
+ if (rule.description) fm.description = rule.description;
1908
+ const fileName = rule.id.replace(/^antigravity:/, "").replace(/[^a-zA-Z0-9-_]/g, "-") || "rule";
1909
+ const body = Object.keys(fm).length > 0 ? matter5.stringify(rule.content, fm) : rule.content;
1910
+ files.push({
1911
+ filePath: `.agent/rules/${fileName}.md`,
1912
+ content: body
1913
+ });
1914
+ }
1915
+ return files;
1916
+ }
1917
+ parseGeminiMd(filePath, content) {
1918
+ const trimmed = content.trim();
1919
+ if (!trimmed) return [];
1920
+ return [{
1921
+ id: generateRuleId("antigravity", filePath),
1922
+ content: trimmed,
1923
+ source: "antigravity",
1924
+ scope: "global",
1925
+ priority: 10,
1926
+ hash: hashContent(trimmed)
1927
+ }];
1928
+ }
1929
+ parseAgentRule(filePath, content) {
1930
+ const { data, content: body } = matter5(content);
1931
+ const trimmed = body.trim();
1932
+ if (!trimmed) return [];
1933
+ return [{
1934
+ id: generateRuleId("antigravity", filePath),
1935
+ content: trimmed,
1936
+ description: data.description,
1937
+ source: "antigravity",
1938
+ scope: "project",
1939
+ priority: 5,
1940
+ hash: hashContent(trimmed)
1941
+ }];
1942
+ }
1943
+ parseSkillMd(filePath, content) {
1944
+ const { data, content: body } = matter5(content);
1945
+ const trimmed = body.trim();
1946
+ if (!trimmed) return [];
1947
+ return [{
1948
+ id: generateRuleId("antigravity", filePath),
1949
+ content: trimmed,
1950
+ description: data.description || void 0,
1951
+ source: "antigravity",
1952
+ scope: "project",
1953
+ priority: 5,
1954
+ hash: hashContent(trimmed)
1955
+ }];
1956
+ }
1957
+ };
1958
+
1879
1959
  // src/rules/syncer.ts
1880
1960
  var RulesSyncer = class {
1881
1961
  projectRoot;
@@ -1887,7 +1967,8 @@ var RulesSyncer = class {
1887
1967
  new CursorAdapter(),
1888
1968
  new ClaudeCodeAdapter(),
1889
1969
  new CodexAdapter(),
1890
- new WindsurfAdapter()
1970
+ new WindsurfAdapter(),
1971
+ new AntigravityAdapter()
1891
1972
  ];
1892
1973
  for (const a of all) {
1893
1974
  this.adapters.set(a.source, a);
@@ -2029,8 +2110,8 @@ var RulesSyncer = class {
2029
2110
  // src/workspace/engine.ts
2030
2111
  init_esm_shims();
2031
2112
  import { readFileSync as readFileSync2, readdirSync, existsSync as existsSync4, cpSync, mkdirSync as mkdirSync2 } from "fs";
2032
- import { join as join7 } from "path";
2033
- import { homedir as homedir6 } from "os";
2113
+ import { join as join8 } from "path";
2114
+ import { homedir as homedir7 } from "os";
2034
2115
 
2035
2116
  // src/workspace/mcp-adapters/windsurf.ts
2036
2117
  init_esm_shims();
@@ -2400,9 +2481,73 @@ var CopilotMCPAdapter = class {
2400
2481
  }
2401
2482
  };
2402
2483
 
2484
+ // src/workspace/mcp-adapters/antigravity.ts
2485
+ init_esm_shims();
2486
+ import { homedir as homedir6 } from "os";
2487
+ import { join as join6 } from "path";
2488
+ var AntigravityMCPAdapter = class {
2489
+ source = "antigravity";
2490
+ parse(content) {
2491
+ try {
2492
+ const config = JSON.parse(content);
2493
+ const servers = config.mcpServers ?? config.mcp_servers ?? {};
2494
+ return Object.entries(servers).map(([name, entry]) => {
2495
+ const result = {
2496
+ name,
2497
+ command: entry.command ?? "",
2498
+ args: entry.args ?? []
2499
+ };
2500
+ if (entry.serverUrl) {
2501
+ result.url = entry.serverUrl;
2502
+ } else if (entry.url) {
2503
+ result.url = entry.url;
2504
+ }
2505
+ if (entry.headers && typeof entry.headers === "object" && Object.keys(entry.headers).length > 0) {
2506
+ result.headers = entry.headers;
2507
+ }
2508
+ if (entry.env && typeof entry.env === "object" && Object.keys(entry.env).length > 0) {
2509
+ result.env = entry.env;
2510
+ }
2511
+ if (entry.disabled === true) {
2512
+ result.disabled = true;
2513
+ }
2514
+ return result;
2515
+ });
2516
+ } catch {
2517
+ return [];
2518
+ }
2519
+ }
2520
+ generate(servers) {
2521
+ const mcpServers = {};
2522
+ for (const s of servers) {
2523
+ const entry = {};
2524
+ if (s.url) {
2525
+ entry.url = s.url;
2526
+ if (s.headers && Object.keys(s.headers).length > 0) {
2527
+ entry.headers = s.headers;
2528
+ }
2529
+ } else {
2530
+ entry.command = s.command;
2531
+ entry.args = s.args;
2532
+ }
2533
+ if (s.env && Object.keys(s.env).length > 0) {
2534
+ entry.env = s.env;
2535
+ }
2536
+ if (s.disabled === true) {
2537
+ entry.disabled = true;
2538
+ }
2539
+ mcpServers[s.name] = entry;
2540
+ }
2541
+ return JSON.stringify({ mcpServers }, null, 2);
2542
+ }
2543
+ getConfigPath(_projectRoot) {
2544
+ return join6(homedir6(), ".gemini", "antigravity", "mcp_config.json");
2545
+ }
2546
+ };
2547
+
2403
2548
  // src/workspace/workflow-sync.ts
2404
2549
  init_esm_shims();
2405
- import matter5 from "gray-matter";
2550
+ import matter6 from "gray-matter";
2406
2551
  var WorkflowSyncer = class {
2407
2552
  /**
2408
2553
  * Parse a Windsurf workflow markdown file into a WorkflowEntry.
@@ -2412,7 +2557,7 @@ var WorkflowSyncer = class {
2412
2557
  let description = "";
2413
2558
  let content = raw;
2414
2559
  try {
2415
- const parsed = matter5(raw);
2560
+ const parsed = matter6(raw);
2416
2561
  description = parsed.data?.description ?? "";
2417
2562
  content = parsed.content.trim();
2418
2563
  } catch {
@@ -2434,7 +2579,7 @@ var WorkflowSyncer = class {
2434
2579
  if (wf.description) {
2435
2580
  fm.description = wf.description;
2436
2581
  }
2437
- const content = matter5.stringify(wf.content, fm);
2582
+ const content = matter6.stringify(wf.content, fm);
2438
2583
  return {
2439
2584
  filePath: `.agents/skills/${safeName}/SKILL.md`,
2440
2585
  content
@@ -2451,7 +2596,7 @@ var WorkflowSyncer = class {
2451
2596
  }
2452
2597
  fm.globs = "";
2453
2598
  fm.alwaysApply = "false";
2454
- const content = matter5.stringify(wf.content, fm);
2599
+ const content = matter6.stringify(wf.content, fm);
2455
2600
  return {
2456
2601
  filePath: `.cursor/rules/${safeName}.mdc`,
2457
2602
  content
@@ -2632,7 +2777,8 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2632
2777
  ["cursor", new CursorMCPAdapter()],
2633
2778
  ["codex", new CodexMCPAdapter()],
2634
2779
  ["claude-code", new ClaudeCodeMCPAdapter()],
2635
- ["copilot", new CopilotMCPAdapter()]
2780
+ ["copilot", new CopilotMCPAdapter()],
2781
+ ["antigravity", new AntigravityMCPAdapter()]
2636
2782
  ]);
2637
2783
  this.workflowSyncer = new WorkflowSyncer();
2638
2784
  this.rulesSyncer = new RulesSyncer(projectRoot);
@@ -2649,7 +2795,8 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2649
2795
  cursor: [],
2650
2796
  codex: [],
2651
2797
  "claude-code": [],
2652
- copilot: []
2798
+ copilot: [],
2799
+ antigravity: []
2653
2800
  };
2654
2801
  for (const [target, adapter] of this.adapters) {
2655
2802
  const configPath = adapter.getConfigPath(this.projectRoot);
@@ -2740,13 +2887,14 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2740
2887
  cursor: [".cursor/skills", ".cursor/skills-cursor"],
2741
2888
  windsurf: [".windsurf/skills"],
2742
2889
  "claude-code": [".claude/skills"],
2743
- copilot: []
2890
+ copilot: [],
2891
+ antigravity: [".agent/skills", ".gemini/skills", ".gemini/antigravity/skills"]
2744
2892
  };
2745
2893
  /** Get the target skills directory for an agent (null if agent has no skills support) */
2746
2894
  getTargetSkillsDir(target) {
2747
2895
  const dirs = _WorkspaceSyncEngine.SKILLS_DIRS[target];
2748
2896
  if (!dirs || dirs.length === 0) return null;
2749
- return join7(this.projectRoot, dirs[0]);
2897
+ return join8(this.projectRoot, dirs[0]);
2750
2898
  }
2751
2899
  /**
2752
2900
  * Scan all agent skills directories and collect unique skills.
@@ -2755,12 +2903,12 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2755
2903
  const skills = [];
2756
2904
  const conflicts = [];
2757
2905
  const seen = /* @__PURE__ */ new Map();
2758
- const home = homedir6();
2906
+ const home = homedir7();
2759
2907
  for (const [agent, dirs] of Object.entries(_WorkspaceSyncEngine.SKILLS_DIRS)) {
2760
2908
  for (const dir of dirs) {
2761
2909
  const paths = [
2762
- join7(this.projectRoot, dir),
2763
- join7(home, dir)
2910
+ join8(this.projectRoot, dir),
2911
+ join8(home, dir)
2764
2912
  ];
2765
2913
  for (const skillsRoot of paths) {
2766
2914
  if (!existsSync4(skillsRoot)) continue;
@@ -2768,7 +2916,7 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2768
2916
  const entries = readdirSync(skillsRoot, { withFileTypes: true });
2769
2917
  for (const entry of entries) {
2770
2918
  if (!entry.isDirectory()) continue;
2771
- const skillMd = join7(skillsRoot, entry.name, "SKILL.md");
2919
+ const skillMd = join8(skillsRoot, entry.name, "SKILL.md");
2772
2920
  if (!existsSync4(skillMd)) continue;
2773
2921
  let description = "";
2774
2922
  try {
@@ -2780,7 +2928,7 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2780
2928
  const newEntry = {
2781
2929
  name: entry.name,
2782
2930
  description,
2783
- sourcePath: join7(skillsRoot, entry.name),
2931
+ sourcePath: join8(skillsRoot, entry.name),
2784
2932
  sourceAgent: agent
2785
2933
  };
2786
2934
  const existing = seen.get(entry.name);
@@ -2817,7 +2965,7 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2817
2965
  }
2818
2966
  for (const skill of skills) {
2819
2967
  if (skill.sourceAgent === target) continue;
2820
- const dest = join7(targetDir, skill.name);
2968
+ const dest = join8(targetDir, skill.name);
2821
2969
  if (existsSync4(dest)) {
2822
2970
  skipped.push(`${skill.name} (already exists in ${target})`);
2823
2971
  continue;
@@ -2833,13 +2981,13 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2833
2981
  }
2834
2982
  scanWorkflows() {
2835
2983
  const workflows = [];
2836
- const wfDir = join7(this.projectRoot, ".windsurf", "workflows");
2984
+ const wfDir = join8(this.projectRoot, ".windsurf", "workflows");
2837
2985
  if (!existsSync4(wfDir)) return workflows;
2838
2986
  try {
2839
2987
  const files = readdirSync(wfDir).filter((f) => f.endsWith(".md"));
2840
2988
  for (const file of files) {
2841
2989
  try {
2842
- const content = readFileSync2(join7(wfDir, file), "utf-8");
2990
+ const content = readFileSync2(join8(wfDir, file), "utf-8");
2843
2991
  workflows.push(this.workflowSyncer.parseWindsurfWorkflow(file, content));
2844
2992
  } catch {
2845
2993
  }
@@ -2926,7 +3074,8 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2926
3074
  "claude-code": "claude-code",
2927
3075
  codex: "codex",
2928
3076
  windsurf: "windsurf",
2929
- copilot: "windsurf"
3077
+ copilot: "windsurf",
3078
+ antigravity: "antigravity"
2930
3079
  };
2931
3080
  return map[target] ?? null;
2932
3081
  }
@@ -3402,12 +3551,12 @@ Entity: ${entityName} | Type: ${type} | Project: ${project.id}${enrichment}`
3402
3551
  };
3403
3552
  }
3404
3553
  );
3405
- const RULE_SOURCES = ["cursor", "claude-code", "codex", "windsurf"];
3554
+ const RULE_SOURCES = ["cursor", "claude-code", "codex", "windsurf", "antigravity"];
3406
3555
  server.registerTool(
3407
3556
  "memorix_rules_sync",
3408
3557
  {
3409
3558
  title: "Rules Sync",
3410
- 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.",
3559
+ 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.",
3411
3560
  inputSchema: {
3412
3561
  action: z.enum(["status", "generate"]).describe('Action: "status" for report, "generate" to produce target files'),
3413
3562
  target: z.enum(RULE_SOURCES).optional().describe("Target agent format for generation (required when action=generate)")
@@ -3457,7 +3606,7 @@ Entity: ${entityName} | Type: ${type} | Project: ${project.id}${enrichment}`
3457
3606
  };
3458
3607
  }
3459
3608
  );
3460
- const AGENT_TARGETS = ["windsurf", "cursor", "claude-code", "codex", "copilot"];
3609
+ const AGENT_TARGETS = ["windsurf", "cursor", "claude-code", "codex", "copilot", "antigravity"];
3461
3610
  server.registerTool(
3462
3611
  "memorix_workspace_sync",
3463
3612
  {