@shahmilsaari/memory-core 0.2.5 → 0.2.7
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/cli.js +75 -32
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -20,25 +20,26 @@ var __filename = fileURLToPath(import.meta.url);
|
|
|
20
20
|
var __dirname = dirname(__filename);
|
|
21
21
|
var PKG_ROOT = join(__dirname, "..");
|
|
22
22
|
var OUTPUT_FILES = [
|
|
23
|
-
{ template: "CLAUDE.md.hbs", path: "CLAUDE.md" },
|
|
24
|
-
{ template: "copilot-instructions.md.hbs", path: ".github/copilot-instructions.md" },
|
|
25
|
-
{ template: "cursorrules.hbs", path: ".cursorrules" },
|
|
26
|
-
{ template: "cursor-rule.mdc.hbs", path: ".cursor/rules/memory-core.mdc" },
|
|
27
|
-
{ template: "windsurfrules.hbs", path: ".windsurfrules" },
|
|
28
|
-
{ template: "clinerules.hbs", path: ".clinerules" },
|
|
29
|
-
{ template: "roo-rule.md.hbs", path: ".roo/rules/memory-core.md" },
|
|
30
|
-
{ template: "aider.conf.yml.hbs", path: ".aider.conf.yml" },
|
|
31
|
-
{ template: "continue-config.json.hbs", path: ".continue/config.json", skipIfExists: true },
|
|
32
|
-
{ template: "DEVIN.md.hbs", path: "DEVIN.md" },
|
|
33
|
-
{ template: "amazonq-guidelines.md.hbs", path: ".amazonq/dev/guidelines.md" },
|
|
34
|
-
{ template: "gemini-styleguide.md.hbs", path: ".gemini/styleguide.md" },
|
|
35
|
-
{ template: "zed-settings.json.hbs", path: ".zed/settings.json", skipIfExists: true },
|
|
36
|
-
{ template: "jetbrains-ai.md.hbs", path: ".idea/ai-instructions.md" },
|
|
37
|
-
{ template: "AGENTS.md.hbs", path: "AGENTS.md" },
|
|
38
|
-
{ template: "AI_RULES.md.hbs", path: "AI_RULES.md" },
|
|
39
|
-
{ template: "ARCHITECTURE.md.hbs", path: "ARCHITECTURE.md" },
|
|
40
|
-
{ template: "PROJECT_MEMORY.md.hbs", path: "PROJECT_MEMORY.md" }
|
|
23
|
+
{ template: "CLAUDE.md.hbs", path: "CLAUDE.md", agent: "Claude Code" },
|
|
24
|
+
{ template: "copilot-instructions.md.hbs", path: ".github/copilot-instructions.md", agent: "GitHub Copilot" },
|
|
25
|
+
{ template: "cursorrules.hbs", path: ".cursorrules", agent: "Cursor" },
|
|
26
|
+
{ template: "cursor-rule.mdc.hbs", path: ".cursor/rules/memory-core.mdc", agent: "Cursor" },
|
|
27
|
+
{ template: "windsurfrules.hbs", path: ".windsurfrules", agent: "Windsurf" },
|
|
28
|
+
{ template: "clinerules.hbs", path: ".clinerules", agent: "Cline" },
|
|
29
|
+
{ template: "roo-rule.md.hbs", path: ".roo/rules/memory-core.md", agent: "Roo Code" },
|
|
30
|
+
{ template: "aider.conf.yml.hbs", path: ".aider.conf.yml", agent: "Aider" },
|
|
31
|
+
{ template: "continue-config.json.hbs", path: ".continue/config.json", agent: "Continue.dev", skipIfExists: true },
|
|
32
|
+
{ template: "DEVIN.md.hbs", path: "DEVIN.md", agent: "Devin" },
|
|
33
|
+
{ template: "amazonq-guidelines.md.hbs", path: ".amazonq/dev/guidelines.md", agent: "Amazon Q" },
|
|
34
|
+
{ template: "gemini-styleguide.md.hbs", path: ".gemini/styleguide.md", agent: "Gemini Code Assist" },
|
|
35
|
+
{ template: "zed-settings.json.hbs", path: ".zed/settings.json", agent: "Zed AI", skipIfExists: true },
|
|
36
|
+
{ template: "jetbrains-ai.md.hbs", path: ".idea/ai-instructions.md", agent: "JetBrains AI" },
|
|
37
|
+
{ template: "AGENTS.md.hbs", path: "AGENTS.md", agent: "OpenHands" },
|
|
38
|
+
{ template: "AI_RULES.md.hbs", path: "AI_RULES.md", agent: "Shared" },
|
|
39
|
+
{ template: "ARCHITECTURE.md.hbs", path: "ARCHITECTURE.md", agent: "Shared" },
|
|
40
|
+
{ template: "PROJECT_MEMORY.md.hbs", path: "PROJECT_MEMORY.md", agent: "Shared" }
|
|
41
41
|
];
|
|
42
|
+
var AGENT_NAMES = [...new Set(OUTPUT_FILES.map((f) => f.agent))];
|
|
42
43
|
Handlebars.registerHelper(
|
|
43
44
|
"join",
|
|
44
45
|
(arr, sep) => Array.isArray(arr) ? arr.join(sep) : ""
|
|
@@ -127,23 +128,34 @@ function renderTemplate(templateName, data) {
|
|
|
127
128
|
function writeFile(filePath, content) {
|
|
128
129
|
const dir = dirname(filePath);
|
|
129
130
|
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
131
|
+
if (existsSync(filePath)) {
|
|
132
|
+
const existing = readFileSync(filePath, "utf-8");
|
|
133
|
+
if (existing === content) return "skipped";
|
|
134
|
+
}
|
|
130
135
|
writeFileSync(filePath, content, "utf-8");
|
|
136
|
+
return "written";
|
|
131
137
|
}
|
|
132
|
-
async function generate(options, cwd = process.cwd()) {
|
|
138
|
+
async function generate(options, cwd = process.cwd(), onlyAgents) {
|
|
133
139
|
const data = buildTemplateData(options);
|
|
134
140
|
const written = [];
|
|
135
|
-
|
|
141
|
+
const skipped = [];
|
|
142
|
+
const files = onlyAgents ? OUTPUT_FILES.filter((f) => onlyAgents.includes(f.agent)) : OUTPUT_FILES;
|
|
143
|
+
for (const output of files) {
|
|
136
144
|
const targetPath = join(cwd, output.path);
|
|
137
|
-
if (output.skipIfExists && existsSync(targetPath))
|
|
145
|
+
if (output.skipIfExists && existsSync(targetPath)) {
|
|
146
|
+
skipped.push(output.path);
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
138
149
|
try {
|
|
139
150
|
const content = renderTemplate(output.template, data);
|
|
140
|
-
writeFile(targetPath, content);
|
|
141
|
-
written.push(output.path);
|
|
151
|
+
const result = writeFile(targetPath, content);
|
|
152
|
+
if (result === "written") written.push(output.path);
|
|
153
|
+
else skipped.push(output.path);
|
|
142
154
|
} catch (err) {
|
|
143
155
|
if (!(err instanceof Error && err.message.includes("Template not found"))) throw err;
|
|
144
156
|
}
|
|
145
157
|
}
|
|
146
|
-
return written;
|
|
158
|
+
return { written, skipped };
|
|
147
159
|
}
|
|
148
160
|
|
|
149
161
|
// src/seeds.ts
|
|
@@ -1430,6 +1442,12 @@ program.command("init").description("Initialize memory-core in the current proje
|
|
|
1430
1442
|
]
|
|
1431
1443
|
});
|
|
1432
1444
|
}
|
|
1445
|
+
const { checkbox } = await import("@inquirer/prompts");
|
|
1446
|
+
const selectedAgents = await checkbox({
|
|
1447
|
+
message: "Which AI agents do you want to generate files for?",
|
|
1448
|
+
choices: AGENT_NAMES.filter((a) => a !== "Shared").map((name) => ({ name, value: name, checked: true })),
|
|
1449
|
+
instructions: " (Space to toggle, A to select all, Enter to confirm)"
|
|
1450
|
+
});
|
|
1433
1451
|
const enableHook = await confirm({
|
|
1434
1452
|
message: "Enable pre-commit hook? (blocks commits that violate your rules)",
|
|
1435
1453
|
default: true
|
|
@@ -1440,7 +1458,8 @@ program.command("init").description("Initialize memory-core in the current proje
|
|
|
1440
1458
|
backendArchitecture,
|
|
1441
1459
|
frontendFramework,
|
|
1442
1460
|
language,
|
|
1443
|
-
caveman: { enabled: installCaveman, intensity: cavemanIntensity }
|
|
1461
|
+
caveman: { enabled: installCaveman, intensity: cavemanIntensity },
|
|
1462
|
+
agents: selectedAgents
|
|
1444
1463
|
};
|
|
1445
1464
|
let memories = [];
|
|
1446
1465
|
if (pullMemories) {
|
|
@@ -1468,10 +1487,11 @@ program.command("init").description("Initialize memory-core in the current proje
|
|
|
1468
1487
|
const spinner = ora("Generating AI agent context files\u2026").start();
|
|
1469
1488
|
const written = await generate(
|
|
1470
1489
|
{ projectName, projectType, backendArchitecture, frontendFramework, language, memories, caveman: config2.caveman },
|
|
1471
|
-
process.cwd()
|
|
1490
|
+
process.cwd(),
|
|
1491
|
+
[...selectedAgents, "Shared"]
|
|
1472
1492
|
);
|
|
1473
1493
|
writeProjectConfig(config2);
|
|
1474
|
-
spinner.succeed(`Generated ${written.length} files`);
|
|
1494
|
+
spinner.succeed(`Generated ${written.written.length} files`);
|
|
1475
1495
|
if (enableHook) {
|
|
1476
1496
|
installHook();
|
|
1477
1497
|
}
|
|
@@ -1480,15 +1500,30 @@ program.command("init").description("Initialize memory-core in the current proje
|
|
|
1480
1500
|
process.env.OLLAMA_URL ?? "http://localhost:11434",
|
|
1481
1501
|
process.env.OLLAMA_CHAT_MODEL ?? "llama3.2"
|
|
1482
1502
|
);
|
|
1483
|
-
printBanner(config2.projectName, written.length, status);
|
|
1503
|
+
printBanner(config2.projectName, written.written.length, status);
|
|
1484
1504
|
await closePool();
|
|
1485
1505
|
});
|
|
1486
|
-
program.command("sync").description("Re-pull memories and regenerate
|
|
1506
|
+
program.command("sync").description("Re-pull memories and regenerate AI agent files").action(async () => {
|
|
1487
1507
|
const config2 = readProjectConfig();
|
|
1488
1508
|
if (!config2) {
|
|
1489
1509
|
console.error(chalk3.red("No .memory-core.json found. Run: memory-core init"));
|
|
1490
1510
|
process.exit(1);
|
|
1491
1511
|
}
|
|
1512
|
+
const { checkbox } = await import("@inquirer/prompts");
|
|
1513
|
+
const savedAgents = new Set(config2.agents ?? AGENT_NAMES.filter((a) => a !== "Shared"));
|
|
1514
|
+
const selectedAgents = await checkbox({
|
|
1515
|
+
message: "Which agents do you want to sync?",
|
|
1516
|
+
choices: AGENT_NAMES.filter((a) => a !== "Shared").map((name) => ({
|
|
1517
|
+
name,
|
|
1518
|
+
value: name,
|
|
1519
|
+
checked: savedAgents.has(name)
|
|
1520
|
+
})),
|
|
1521
|
+
instructions: " (Space to toggle, A to select all, Enter to confirm)"
|
|
1522
|
+
});
|
|
1523
|
+
if (selectedAgents.length === 0) {
|
|
1524
|
+
console.log(chalk3.yellow(" No agents selected \u2014 nothing to sync."));
|
|
1525
|
+
process.exit(0);
|
|
1526
|
+
}
|
|
1492
1527
|
const spinner = ora("Syncing memories\u2026").start();
|
|
1493
1528
|
let memories = [];
|
|
1494
1529
|
try {
|
|
@@ -1498,7 +1533,7 @@ program.command("sync").description("Re-pull memories and regenerate all AI agen
|
|
|
1498
1533
|
} catch (err) {
|
|
1499
1534
|
spinner.warn(`Could not retrieve memories: ${err.message}`);
|
|
1500
1535
|
}
|
|
1501
|
-
const
|
|
1536
|
+
const result = await generate(
|
|
1502
1537
|
{
|
|
1503
1538
|
projectName: config2.projectName,
|
|
1504
1539
|
projectType: config2.projectType,
|
|
@@ -1508,9 +1543,17 @@ program.command("sync").description("Re-pull memories and regenerate all AI agen
|
|
|
1508
1543
|
memories,
|
|
1509
1544
|
caveman: config2.caveman
|
|
1510
1545
|
},
|
|
1511
|
-
process.cwd()
|
|
1546
|
+
process.cwd(),
|
|
1547
|
+
[...selectedAgents, "Shared"]
|
|
1512
1548
|
);
|
|
1513
|
-
|
|
1549
|
+
const updatedCount = result.written.length;
|
|
1550
|
+
const skippedCount = result.skipped.length;
|
|
1551
|
+
spinner.succeed(
|
|
1552
|
+
`Synced \u2014 ${chalk3.green(`${updatedCount} updated`)}, ${chalk3.dim(`${skippedCount} already up to date`)}`
|
|
1553
|
+
);
|
|
1554
|
+
if (result.written.length > 0) {
|
|
1555
|
+
result.written.forEach((f) => console.log(chalk3.gray(` \u2713 ${f}`)));
|
|
1556
|
+
}
|
|
1514
1557
|
await closePool();
|
|
1515
1558
|
});
|
|
1516
1559
|
program.command("remember <text>").description("Save a new memory to the central database").option("-t, --type <type>", "Memory type (decision|rule|pattern|note)", "decision").option("-s, --scope <scope>", "Scope (global|project)", "project").option("--tags <tags>", "Comma-separated tags").option("-r, --reason <reason>", "Why this rule exists \u2014 helps agents understand intent and debug violations").action(async (text, opts) => {
|