memorix 0.4.0 → 0.5.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
@@ -1956,6 +1956,92 @@ var AntigravityAdapter = class {
1956
1956
  }
1957
1957
  };
1958
1958
 
1959
+ // src/rules/adapters/copilot.ts
1960
+ init_esm_shims();
1961
+ import matter6 from "gray-matter";
1962
+ var CopilotAdapter = class {
1963
+ source = "copilot";
1964
+ filePatterns = [
1965
+ ".github/copilot-instructions.md",
1966
+ ".github/instructions/*.instructions.md"
1967
+ ];
1968
+ parse(filePath, content) {
1969
+ if (filePath.includes(".instructions.md") && filePath.includes(".github/instructions")) {
1970
+ return this.parsePathSpecific(filePath, content);
1971
+ }
1972
+ if (filePath.includes("copilot-instructions.md")) {
1973
+ return this.parseRepoWide(filePath, content);
1974
+ }
1975
+ return [];
1976
+ }
1977
+ generate(rules) {
1978
+ if (rules.length === 1 && (!rules[0].paths || rules[0].paths.length === 0)) {
1979
+ return [{
1980
+ filePath: ".github/copilot-instructions.md",
1981
+ content: rules[0].content
1982
+ }];
1983
+ }
1984
+ return rules.map((rule, i) => {
1985
+ const fm = {};
1986
+ if (rule.paths && rule.paths.length > 0) {
1987
+ fm.applyTo = rule.paths.join(",");
1988
+ }
1989
+ if (rule.description) {
1990
+ fm.description = rule.description;
1991
+ }
1992
+ const fileName = rule.id.replace(/^copilot:/, "").replace(/[^a-zA-Z0-9-_]/g, "-") || `instruction-${i}`;
1993
+ const body = Object.keys(fm).length > 0 ? matter6.stringify(rule.content, fm) : rule.content;
1994
+ return {
1995
+ filePath: `.github/instructions/${fileName}.instructions.md`,
1996
+ content: body
1997
+ };
1998
+ });
1999
+ }
2000
+ /**
2001
+ * Parse repository-wide .github/copilot-instructions.md
2002
+ * This is plain Markdown with no frontmatter.
2003
+ */
2004
+ parseRepoWide(filePath, content) {
2005
+ const trimmed = content.trim();
2006
+ if (!trimmed) return [];
2007
+ return [{
2008
+ id: generateRuleId("copilot", filePath),
2009
+ content: trimmed,
2010
+ description: "Repository-wide Copilot instructions",
2011
+ source: "copilot",
2012
+ scope: "project",
2013
+ priority: 3,
2014
+ hash: hashContent(trimmed)
2015
+ }];
2016
+ }
2017
+ /**
2018
+ * Parse path-specific .github/instructions/*.instructions.md
2019
+ * These have YAML frontmatter with `applyTo` glob pattern(s).
2020
+ */
2021
+ parsePathSpecific(filePath, content) {
2022
+ const { data, content: body } = matter6(content);
2023
+ const trimmed = body.trim();
2024
+ if (!trimmed) return [];
2025
+ const applyTo = data.applyTo;
2026
+ const hasApplyTo = !!applyTo;
2027
+ const rule = {
2028
+ id: generateRuleId("copilot", filePath),
2029
+ content: trimmed,
2030
+ source: "copilot",
2031
+ scope: hasApplyTo ? "path-specific" : "project",
2032
+ priority: 5,
2033
+ hash: hashContent(trimmed)
2034
+ };
2035
+ if (hasApplyTo) {
2036
+ rule.paths = applyTo.split(",").map((p) => p.trim());
2037
+ }
2038
+ if (data.description) {
2039
+ rule.description = data.description;
2040
+ }
2041
+ return [rule];
2042
+ }
2043
+ };
2044
+
1959
2045
  // src/rules/syncer.ts
1960
2046
  var RulesSyncer = class {
1961
2047
  projectRoot;
@@ -1968,7 +2054,8 @@ var RulesSyncer = class {
1968
2054
  new ClaudeCodeAdapter(),
1969
2055
  new CodexAdapter(),
1970
2056
  new WindsurfAdapter(),
1971
- new AntigravityAdapter()
2057
+ new AntigravityAdapter(),
2058
+ new CopilotAdapter()
1972
2059
  ];
1973
2060
  for (const a of all) {
1974
2061
  this.adapters.set(a.source, a);
@@ -2547,7 +2634,7 @@ var AntigravityMCPAdapter = class {
2547
2634
 
2548
2635
  // src/workspace/workflow-sync.ts
2549
2636
  init_esm_shims();
2550
- import matter6 from "gray-matter";
2637
+ import matter7 from "gray-matter";
2551
2638
  var WorkflowSyncer = class {
2552
2639
  /**
2553
2640
  * Parse a Windsurf workflow markdown file into a WorkflowEntry.
@@ -2557,7 +2644,7 @@ var WorkflowSyncer = class {
2557
2644
  let description = "";
2558
2645
  let content = raw;
2559
2646
  try {
2560
- const parsed = matter6(raw);
2647
+ const parsed = matter7(raw);
2561
2648
  description = parsed.data?.description ?? "";
2562
2649
  content = parsed.content.trim();
2563
2650
  } catch {
@@ -2579,7 +2666,7 @@ var WorkflowSyncer = class {
2579
2666
  if (wf.description) {
2580
2667
  fm.description = wf.description;
2581
2668
  }
2582
- const content = matter6.stringify(wf.content, fm);
2669
+ const content = matter7.stringify(wf.content, fm);
2583
2670
  return {
2584
2671
  filePath: `.agents/skills/${safeName}/SKILL.md`,
2585
2672
  content
@@ -2596,7 +2683,7 @@ var WorkflowSyncer = class {
2596
2683
  }
2597
2684
  fm.globs = "";
2598
2685
  fm.alwaysApply = "false";
2599
- const content = matter6.stringify(wf.content, fm);
2686
+ const content = matter7.stringify(wf.content, fm);
2600
2687
  return {
2601
2688
  filePath: `.cursor/rules/${safeName}.mdc`,
2602
2689
  content
@@ -2887,7 +2974,7 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2887
2974
  cursor: [".cursor/skills", ".cursor/skills-cursor"],
2888
2975
  windsurf: [".windsurf/skills"],
2889
2976
  "claude-code": [".claude/skills"],
2890
- copilot: [],
2977
+ copilot: [".github/skills", ".copilot/skills"],
2891
2978
  antigravity: [".agent/skills", ".gemini/skills", ".gemini/antigravity/skills"]
2892
2979
  };
2893
2980
  /** Get the target skills directory for an agent (null if agent has no skills support) */
@@ -3074,7 +3161,7 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
3074
3161
  "claude-code": "claude-code",
3075
3162
  codex: "codex",
3076
3163
  windsurf: "windsurf",
3077
- copilot: "windsurf",
3164
+ copilot: "copilot",
3078
3165
  antigravity: "antigravity"
3079
3166
  };
3080
3167
  return map[target] ?? null;
@@ -3551,12 +3638,12 @@ Entity: ${entityName} | Type: ${type} | Project: ${project.id}${enrichment}`
3551
3638
  };
3552
3639
  }
3553
3640
  );
3554
- const RULE_SOURCES = ["cursor", "claude-code", "codex", "windsurf", "antigravity"];
3641
+ const RULE_SOURCES = ["cursor", "claude-code", "codex", "windsurf", "antigravity", "copilot"];
3555
3642
  server.registerTool(
3556
3643
  "memorix_rules_sync",
3557
3644
  {
3558
3645
  title: "Rules Sync",
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.",
3646
+ description: "Scan project for agent rule files (Cursor, Claude Code, Codex, Windsurf, Antigravity, Copilot), deduplicate, detect conflicts, and optionally generate rules for a target agent format. Without target: returns sync status report. With target: generates converted rule files.",
3560
3647
  inputSchema: {
3561
3648
  action: z.enum(["status", "generate"]).describe('Action: "status" for report, "generate" to produce target files'),
3562
3649
  target: z.enum(RULE_SOURCES).optional().describe("Target agent format for generation (required when action=generate)")