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/CHANGELOG.md +20 -1
- package/README.md +278 -173
- package/dist/cli/index.js +106 -11
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +96 -9
- package/dist/index.js.map +1 -1
- package/package.json +19 -6
- package/examples/CLAUDE.md +0 -27
- package/examples/claude-desktop-config.json +0 -8
- package/examples/cursor-mcp.json +0 -8
- package/examples/windsurf-mcp.json +0 -8
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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: "
|
|
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)")
|