@memly/mcp-server 0.2.2 → 0.2.4
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 +321 -84
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20211,130 +20211,286 @@ I am ready to continue our work.`
|
|
|
20211
20211
|
}
|
|
20212
20212
|
|
|
20213
20213
|
// src/init.ts
|
|
20214
|
-
import { existsSync, mkdirSync, writeFileSync, readFileSync } from "node:fs";
|
|
20214
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync } from "node:fs";
|
|
20215
20215
|
import { join, resolve } from "node:path";
|
|
20216
20216
|
import { homedir, platform } from "node:os";
|
|
20217
20217
|
var MEMLY_INSTRUCTION_BLOCK = `
|
|
20218
|
-
## Memly
|
|
20218
|
+
## Memly — Persistent Memory (Auto-Enabled)
|
|
20219
20219
|
|
|
20220
20220
|
You have access to the Memly MCP server (\`memly\`).
|
|
20221
20221
|
|
|
20222
|
-
**RULES (always follow
|
|
20222
|
+
**RULES (always follow):**
|
|
20223
20223
|
|
|
20224
|
-
1. **At the start of EVERY conversation**, call \`load_context\` before answering
|
|
20225
|
-
-
|
|
20226
|
-
-
|
|
20227
|
-
- Otherwise call with no arguments.
|
|
20224
|
+
1. **At the start of EVERY conversation**, call \`load_context\` before answering.
|
|
20225
|
+
- Pass \`topic\` if the user's message has a clear subject (e.g., \`topic: "authentication"\`)
|
|
20226
|
+
- Otherwise call with no arguments
|
|
20228
20227
|
|
|
20229
|
-
2. **During the conversation**, call \`remember\` proactively
|
|
20230
|
-
-
|
|
20228
|
+
2. **During the conversation**, call \`remember\` proactively when:
|
|
20229
|
+
- User makes an architectural or technical decision
|
|
20231
20230
|
- You solve a non-trivial bug or problem
|
|
20232
|
-
-
|
|
20233
|
-
-
|
|
20231
|
+
- User shares important project context, preferences, or constraints
|
|
20232
|
+
- User explicitly says "remember this"
|
|
20234
20233
|
|
|
20235
|
-
3. **Never** ask
|
|
20234
|
+
3. **Never** ask if you should remember something — just do it silently.
|
|
20236
20235
|
`.trim();
|
|
20236
|
+
async function validateApiKey(apiKey) {
|
|
20237
|
+
try {
|
|
20238
|
+
const controller = new AbortController;
|
|
20239
|
+
const timeout = setTimeout(() => controller.abort(), 5000);
|
|
20240
|
+
const response = await fetch("https://api.memly.site/health", {
|
|
20241
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
20242
|
+
signal: controller.signal
|
|
20243
|
+
});
|
|
20244
|
+
clearTimeout(timeout);
|
|
20245
|
+
return response.ok;
|
|
20246
|
+
} catch {
|
|
20247
|
+
return false;
|
|
20248
|
+
}
|
|
20249
|
+
}
|
|
20237
20250
|
function writeCopilotInstructions(projectRoot) {
|
|
20238
20251
|
const githubDir = join(projectRoot, ".github");
|
|
20239
20252
|
const filePath = join(githubDir, "copilot-instructions.md");
|
|
20240
|
-
if (!existsSync(githubDir))
|
|
20241
|
-
mkdirSync(githubDir, { recursive: true });
|
|
20242
20253
|
const MARKER = "<!-- memly-instructions -->";
|
|
20243
|
-
|
|
20244
|
-
|
|
20245
|
-
|
|
20246
|
-
return { ide: "VS Code / GitHub Copilot", file: filePath, status: "skipped" };
|
|
20254
|
+
try {
|
|
20255
|
+
if (!existsSync(githubDir)) {
|
|
20256
|
+
mkdirSync(githubDir, { recursive: true });
|
|
20247
20257
|
}
|
|
20248
|
-
|
|
20258
|
+
if (existsSync(filePath)) {
|
|
20259
|
+
const existing = readFileSync(filePath, "utf-8");
|
|
20260
|
+
if (existing.includes(MARKER)) {
|
|
20261
|
+
return { ide: "VS Code / GitHub Copilot", file: filePath, status: "skipped" };
|
|
20262
|
+
}
|
|
20263
|
+
writeFileSync(filePath, `${existing.trimEnd()}
|
|
20249
20264
|
|
|
20250
20265
|
${MARKER}
|
|
20251
20266
|
${MEMLY_INSTRUCTION_BLOCK}
|
|
20252
20267
|
${MARKER}
|
|
20253
20268
|
`);
|
|
20254
|
-
|
|
20255
|
-
|
|
20256
|
-
|
|
20269
|
+
return { ide: "VS Code / GitHub Copilot", file: filePath, status: "updated" };
|
|
20270
|
+
}
|
|
20271
|
+
writeFileSync(filePath, `${MARKER}
|
|
20257
20272
|
${MEMLY_INSTRUCTION_BLOCK}
|
|
20258
20273
|
${MARKER}
|
|
20259
20274
|
`);
|
|
20260
|
-
|
|
20275
|
+
return { ide: "VS Code / GitHub Copilot", file: filePath, status: "created" };
|
|
20276
|
+
} catch (err) {
|
|
20277
|
+
return {
|
|
20278
|
+
ide: "VS Code / GitHub Copilot",
|
|
20279
|
+
file: filePath,
|
|
20280
|
+
status: "failed",
|
|
20281
|
+
error: err instanceof Error ? err.message : String(err)
|
|
20282
|
+
};
|
|
20283
|
+
}
|
|
20261
20284
|
}
|
|
20262
20285
|
function writeCursorRules(projectRoot) {
|
|
20263
20286
|
const filePath = join(projectRoot, ".cursorrules");
|
|
20264
20287
|
const MARKER = "# memly-instructions";
|
|
20265
|
-
|
|
20266
|
-
|
|
20267
|
-
|
|
20268
|
-
|
|
20269
|
-
|
|
20270
|
-
|
|
20288
|
+
try {
|
|
20289
|
+
if (existsSync(filePath)) {
|
|
20290
|
+
const existing = readFileSync(filePath, "utf-8");
|
|
20291
|
+
if (existing.includes(MARKER)) {
|
|
20292
|
+
return { ide: "Cursor", file: filePath, status: "skipped" };
|
|
20293
|
+
}
|
|
20294
|
+
writeFileSync(filePath, `${existing.trimEnd()}
|
|
20271
20295
|
|
|
20272
20296
|
${MARKER}
|
|
20273
20297
|
${MEMLY_INSTRUCTION_BLOCK}
|
|
20274
20298
|
`);
|
|
20275
|
-
|
|
20276
|
-
|
|
20277
|
-
|
|
20299
|
+
return { ide: "Cursor", file: filePath, status: "updated" };
|
|
20300
|
+
}
|
|
20301
|
+
writeFileSync(filePath, `${MARKER}
|
|
20278
20302
|
${MEMLY_INSTRUCTION_BLOCK}
|
|
20279
20303
|
`);
|
|
20280
|
-
|
|
20304
|
+
return { ide: "Cursor", file: filePath, status: "created" };
|
|
20305
|
+
} catch (err) {
|
|
20306
|
+
return {
|
|
20307
|
+
ide: "Cursor",
|
|
20308
|
+
file: filePath,
|
|
20309
|
+
status: "failed",
|
|
20310
|
+
error: err instanceof Error ? err.message : String(err)
|
|
20311
|
+
};
|
|
20312
|
+
}
|
|
20281
20313
|
}
|
|
20282
20314
|
function writeWindsurfRules(projectRoot) {
|
|
20283
20315
|
const filePath = join(projectRoot, ".windsurfrules");
|
|
20284
20316
|
const MARKER = "# memly-instructions";
|
|
20285
|
-
|
|
20286
|
-
|
|
20287
|
-
|
|
20288
|
-
|
|
20289
|
-
|
|
20290
|
-
|
|
20317
|
+
try {
|
|
20318
|
+
if (existsSync(filePath)) {
|
|
20319
|
+
const existing = readFileSync(filePath, "utf-8");
|
|
20320
|
+
if (existing.includes(MARKER)) {
|
|
20321
|
+
return { ide: "Windsurf", file: filePath, status: "skipped" };
|
|
20322
|
+
}
|
|
20323
|
+
writeFileSync(filePath, `${existing.trimEnd()}
|
|
20291
20324
|
|
|
20292
20325
|
${MARKER}
|
|
20293
20326
|
${MEMLY_INSTRUCTION_BLOCK}
|
|
20294
20327
|
`);
|
|
20295
|
-
|
|
20328
|
+
return { ide: "Windsurf", file: filePath, status: "updated" };
|
|
20329
|
+
}
|
|
20330
|
+
writeFileSync(filePath, `${MARKER}
|
|
20331
|
+
${MEMLY_INSTRUCTION_BLOCK}
|
|
20332
|
+
`);
|
|
20333
|
+
return { ide: "Windsurf", file: filePath, status: "created" };
|
|
20334
|
+
} catch (err) {
|
|
20335
|
+
return {
|
|
20336
|
+
ide: "Windsurf",
|
|
20337
|
+
file: filePath,
|
|
20338
|
+
status: "failed",
|
|
20339
|
+
error: err instanceof Error ? err.message : String(err)
|
|
20340
|
+
};
|
|
20296
20341
|
}
|
|
20297
|
-
|
|
20342
|
+
}
|
|
20343
|
+
function writeClineConfig(projectRoot) {
|
|
20344
|
+
const filePath = join(projectRoot, ".clinerules");
|
|
20345
|
+
const MARKER = "# memly-instructions";
|
|
20346
|
+
try {
|
|
20347
|
+
if (existsSync(filePath)) {
|
|
20348
|
+
const existing = readFileSync(filePath, "utf-8");
|
|
20349
|
+
if (existing.includes(MARKER)) {
|
|
20350
|
+
return { ide: "Cline (VS Code)", file: filePath, status: "skipped" };
|
|
20351
|
+
}
|
|
20352
|
+
writeFileSync(filePath, `${existing.trimEnd()}
|
|
20353
|
+
|
|
20354
|
+
${MARKER}
|
|
20355
|
+
${MEMLY_INSTRUCTION_BLOCK}
|
|
20356
|
+
`);
|
|
20357
|
+
return { ide: "Cline (VS Code)", file: filePath, status: "updated" };
|
|
20358
|
+
}
|
|
20359
|
+
writeFileSync(filePath, `${MARKER}
|
|
20298
20360
|
${MEMLY_INSTRUCTION_BLOCK}
|
|
20299
20361
|
`);
|
|
20300
|
-
|
|
20362
|
+
return { ide: "Cline (VS Code)", file: filePath, status: "created" };
|
|
20363
|
+
} catch (err) {
|
|
20364
|
+
return {
|
|
20365
|
+
ide: "Cline (VS Code)",
|
|
20366
|
+
file: filePath,
|
|
20367
|
+
status: "failed",
|
|
20368
|
+
error: err instanceof Error ? err.message : String(err)
|
|
20369
|
+
};
|
|
20370
|
+
}
|
|
20371
|
+
}
|
|
20372
|
+
function writeContinueConfig() {
|
|
20373
|
+
const configPath = join(homedir(), ".continue", "config.json");
|
|
20374
|
+
if (!existsSync(configPath))
|
|
20375
|
+
return null;
|
|
20376
|
+
try {
|
|
20377
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
20378
|
+
const config2 = JSON.parse(raw);
|
|
20379
|
+
const mcpServers = config2["mcpServers"] ?? {};
|
|
20380
|
+
if (mcpServers["memly"]) {
|
|
20381
|
+
return { ide: "Continue.dev", file: configPath, status: "skipped" };
|
|
20382
|
+
}
|
|
20383
|
+
mcpServers["memly"] = {
|
|
20384
|
+
command: "npx",
|
|
20385
|
+
args: ["-y", "@memly/mcp-server"],
|
|
20386
|
+
env: { MEMLY_API_KEY: process.env.MEMLY_API_KEY ?? "<your-memly-api-key>" }
|
|
20387
|
+
};
|
|
20388
|
+
config2["mcpServers"] = mcpServers;
|
|
20389
|
+
writeFileSync(configPath, JSON.stringify(config2, null, 2));
|
|
20390
|
+
return { ide: "Continue.dev", file: configPath, status: "updated" };
|
|
20391
|
+
} catch (err) {
|
|
20392
|
+
return {
|
|
20393
|
+
ide: "Continue.dev",
|
|
20394
|
+
file: configPath,
|
|
20395
|
+
status: "failed",
|
|
20396
|
+
error: err instanceof Error ? err.message : String(err)
|
|
20397
|
+
};
|
|
20398
|
+
}
|
|
20399
|
+
}
|
|
20400
|
+
function writeZedConfig() {
|
|
20401
|
+
const os = platform();
|
|
20402
|
+
const configPath = os === "darwin" ? join(homedir(), "Library", "Application Support", "Zed", "settings.json") : join(homedir(), ".config", "zed", "settings.json");
|
|
20403
|
+
if (!existsSync(configPath))
|
|
20404
|
+
return null;
|
|
20405
|
+
try {
|
|
20406
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
20407
|
+
const config2 = JSON.parse(raw);
|
|
20408
|
+
const assistant = config2["assistant"] ?? {};
|
|
20409
|
+
const instructions = assistant["instructions"] ?? "";
|
|
20410
|
+
if (instructions.includes("Memly")) {
|
|
20411
|
+
return { ide: "Zed", file: configPath, status: "skipped" };
|
|
20412
|
+
}
|
|
20413
|
+
assistant["instructions"] = instructions ? `${instructions}
|
|
20414
|
+
|
|
20415
|
+
${MEMLY_INSTRUCTION_BLOCK}` : MEMLY_INSTRUCTION_BLOCK;
|
|
20416
|
+
config2["assistant"] = assistant;
|
|
20417
|
+
writeFileSync(configPath, JSON.stringify(config2, null, 2));
|
|
20418
|
+
return { ide: "Zed", file: configPath, status: "updated" };
|
|
20419
|
+
} catch (err) {
|
|
20420
|
+
return {
|
|
20421
|
+
ide: "Zed",
|
|
20422
|
+
file: configPath,
|
|
20423
|
+
status: "failed",
|
|
20424
|
+
error: err instanceof Error ? err.message : String(err)
|
|
20425
|
+
};
|
|
20426
|
+
}
|
|
20427
|
+
}
|
|
20428
|
+
function writeAiderConfig() {
|
|
20429
|
+
const configPath = join(homedir(), ".aider.conf.yml");
|
|
20430
|
+
if (!existsSync(configPath))
|
|
20431
|
+
return null;
|
|
20432
|
+
try {
|
|
20433
|
+
const existing = readFileSync(configPath, "utf-8");
|
|
20434
|
+
if (existing.includes("memly-instructions")) {
|
|
20435
|
+
return { ide: "Aider (CLI)", file: configPath, status: "skipped" };
|
|
20436
|
+
}
|
|
20437
|
+
const instruction = `
|
|
20438
|
+
# memly-instructions
|
|
20439
|
+
edit-format: |
|
|
20440
|
+
${MEMLY_INSTRUCTION_BLOCK.replace(/\n/g, `
|
|
20441
|
+
`)}
|
|
20442
|
+
`;
|
|
20443
|
+
writeFileSync(configPath, existing + instruction);
|
|
20444
|
+
return { ide: "Aider (CLI)", file: configPath, status: "updated" };
|
|
20445
|
+
} catch (err) {
|
|
20446
|
+
return {
|
|
20447
|
+
ide: "Aider (CLI)",
|
|
20448
|
+
file: configPath,
|
|
20449
|
+
status: "failed",
|
|
20450
|
+
error: err instanceof Error ? err.message : String(err)
|
|
20451
|
+
};
|
|
20452
|
+
}
|
|
20301
20453
|
}
|
|
20302
20454
|
function writeJetBrains(projectRoot) {
|
|
20303
20455
|
const ideaDir = join(projectRoot, ".idea");
|
|
20304
20456
|
if (!existsSync(ideaDir))
|
|
20305
20457
|
return null;
|
|
20306
20458
|
const filePath = join(ideaDir, "mcp.json");
|
|
20307
|
-
|
|
20308
|
-
|
|
20309
|
-
|
|
20310
|
-
if (existing.includes(MARKER)) {
|
|
20311
|
-
return { ide: "JetBrains", file: filePath, status: "skipped" };
|
|
20312
|
-
}
|
|
20313
|
-
try {
|
|
20459
|
+
try {
|
|
20460
|
+
if (existsSync(filePath)) {
|
|
20461
|
+
const existing = readFileSync(filePath, "utf-8");
|
|
20314
20462
|
const config2 = JSON.parse(existing);
|
|
20463
|
+
if (config2.servers?.["memly"]) {
|
|
20464
|
+
return { ide: "JetBrains", file: filePath, status: "skipped" };
|
|
20465
|
+
}
|
|
20315
20466
|
config2.servers = config2.servers ?? {};
|
|
20316
20467
|
config2.servers["memly"] = {
|
|
20317
20468
|
command: "npx",
|
|
20318
20469
|
args: ["-y", "@memly/mcp-server"],
|
|
20319
|
-
env: { MEMLY_API_KEY: "<your-memly-api-key>" }
|
|
20470
|
+
env: { MEMLY_API_KEY: process.env.MEMLY_API_KEY ?? "<your-memly-api-key>" }
|
|
20320
20471
|
};
|
|
20321
20472
|
writeFileSync(filePath, JSON.stringify(config2, null, 2));
|
|
20322
20473
|
return { ide: "JetBrains", file: filePath, status: "updated" };
|
|
20323
|
-
} catch {
|
|
20324
|
-
return null;
|
|
20325
20474
|
}
|
|
20326
|
-
|
|
20327
|
-
|
|
20328
|
-
|
|
20329
|
-
|
|
20330
|
-
|
|
20331
|
-
|
|
20332
|
-
|
|
20333
|
-
|
|
20475
|
+
mkdirSync(ideaDir, { recursive: true });
|
|
20476
|
+
writeFileSync(filePath, JSON.stringify({
|
|
20477
|
+
servers: {
|
|
20478
|
+
memly: {
|
|
20479
|
+
command: "npx",
|
|
20480
|
+
args: ["-y", "@memly/mcp-server"],
|
|
20481
|
+
env: { MEMLY_API_KEY: process.env.MEMLY_API_KEY ?? "<your-memly-api-key>" }
|
|
20482
|
+
}
|
|
20334
20483
|
}
|
|
20335
|
-
}
|
|
20336
|
-
|
|
20337
|
-
|
|
20484
|
+
}, null, 2));
|
|
20485
|
+
return { ide: "JetBrains", file: filePath, status: "created" };
|
|
20486
|
+
} catch (err) {
|
|
20487
|
+
return {
|
|
20488
|
+
ide: "JetBrains",
|
|
20489
|
+
file: filePath,
|
|
20490
|
+
status: "failed",
|
|
20491
|
+
error: err instanceof Error ? err.message : String(err)
|
|
20492
|
+
};
|
|
20493
|
+
}
|
|
20338
20494
|
}
|
|
20339
20495
|
function writeClaudeDesktop() {
|
|
20340
20496
|
const os = platform();
|
|
@@ -20360,59 +20516,140 @@ function writeClaudeDesktop() {
|
|
|
20360
20516
|
servers["memly"]["systemPrompt"] = MEMLY_INSTRUCTION_BLOCK;
|
|
20361
20517
|
writeFileSync(configPath, JSON.stringify(config2, null, 2));
|
|
20362
20518
|
return { ide: "Claude Desktop", file: configPath, status: "updated" };
|
|
20363
|
-
} catch {
|
|
20364
|
-
return
|
|
20519
|
+
} catch (err) {
|
|
20520
|
+
return {
|
|
20521
|
+
ide: "Claude Desktop",
|
|
20522
|
+
file: configPath,
|
|
20523
|
+
status: "failed",
|
|
20524
|
+
error: err instanceof Error ? err.message : String(err)
|
|
20525
|
+
};
|
|
20365
20526
|
}
|
|
20366
20527
|
}
|
|
20367
|
-
function
|
|
20528
|
+
async function reportTelemetry(results) {
|
|
20529
|
+
try {
|
|
20530
|
+
const controller = new AbortController;
|
|
20531
|
+
const timeout = setTimeout(() => controller.abort(), 3000);
|
|
20532
|
+
await fetch("https://api.memly.site/api/telemetry/init", {
|
|
20533
|
+
method: "POST",
|
|
20534
|
+
headers: { "Content-Type": "application/json" },
|
|
20535
|
+
body: JSON.stringify({
|
|
20536
|
+
ides: results.map((r) => r.ide),
|
|
20537
|
+
os: platform(),
|
|
20538
|
+
timestamp: new Date().toISOString()
|
|
20539
|
+
}),
|
|
20540
|
+
signal: controller.signal
|
|
20541
|
+
});
|
|
20542
|
+
clearTimeout(timeout);
|
|
20543
|
+
} catch {}
|
|
20544
|
+
}
|
|
20545
|
+
async function runInit() {
|
|
20368
20546
|
const projectRoot = resolve(process.cwd());
|
|
20369
|
-
|
|
20547
|
+
if (projectRoot === homedir()) {
|
|
20548
|
+
console.error("Error: Running in home directory.");
|
|
20549
|
+
console.error(`Run this command inside your project folder.
|
|
20550
|
+
`);
|
|
20551
|
+
process.exit(1);
|
|
20552
|
+
}
|
|
20370
20553
|
console.log(`
|
|
20371
|
-
|
|
20554
|
+
â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”`);
|
|
20555
|
+
console.log(" Memly Init — Auto-Memory Setup");
|
|
20556
|
+
console.log(`â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”
|
|
20557
|
+
`);
|
|
20558
|
+
const apiKey = process.env.MEMLY_API_KEY;
|
|
20559
|
+
if (!apiKey) {
|
|
20560
|
+
console.error(`Error: MEMLY_API_KEY not set.
|
|
20561
|
+
`);
|
|
20562
|
+
console.error("Get your API key at: https://memly.site/dashboard");
|
|
20563
|
+
console.error(`Then run: export MEMLY_API_KEY=memly_...
|
|
20564
|
+
`);
|
|
20565
|
+
process.exit(1);
|
|
20566
|
+
}
|
|
20567
|
+
process.stdout.write("Validating API key... ");
|
|
20568
|
+
const valid = await validateApiKey(apiKey);
|
|
20569
|
+
if (!valid) {
|
|
20570
|
+
console.error(`✗ Invalid
|
|
20372
20571
|
`);
|
|
20373
|
-
|
|
20572
|
+
console.error(`Check your API key at: https://memly.site/dashboard
|
|
20374
20573
|
`);
|
|
20574
|
+
process.exit(1);
|
|
20575
|
+
}
|
|
20576
|
+
console.log(`✓ Valid
|
|
20577
|
+
`);
|
|
20578
|
+
console.log(`Project: ${projectRoot}
|
|
20579
|
+
`);
|
|
20580
|
+
console.log(`Detecting IDEs...
|
|
20581
|
+
`);
|
|
20582
|
+
const results = [];
|
|
20375
20583
|
results.push(writeCopilotInstructions(projectRoot));
|
|
20376
20584
|
const hasCursor = existsSync(join(projectRoot, ".cursor")) || existsSync(join(projectRoot, ".cursorrules")) || existsSync(join(homedir(), ".cursor"));
|
|
20377
|
-
if (hasCursor)
|
|
20585
|
+
if (hasCursor)
|
|
20378
20586
|
results.push(writeCursorRules(projectRoot));
|
|
20379
|
-
}
|
|
20380
20587
|
const hasWindsurf = existsSync(join(projectRoot, ".windsurfrules")) || existsSync(join(homedir(), ".codeium"));
|
|
20381
|
-
if (hasWindsurf)
|
|
20588
|
+
if (hasWindsurf)
|
|
20382
20589
|
results.push(writeWindsurfRules(projectRoot));
|
|
20383
|
-
|
|
20590
|
+
const clineExtDir = join(homedir(), ".vscode", "extensions");
|
|
20591
|
+
const hasCline = existsSync(join(projectRoot, ".clinerules")) || existsSync(clineExtDir) && readdirSync(clineExtDir).some((d) => d.startsWith("saoudrizwan.claude-dev"));
|
|
20592
|
+
if (hasCline)
|
|
20593
|
+
results.push(writeClineConfig(projectRoot));
|
|
20594
|
+
const continueResult = writeContinueConfig();
|
|
20595
|
+
if (continueResult)
|
|
20596
|
+
results.push(continueResult);
|
|
20597
|
+
const zedResult = writeZedConfig();
|
|
20598
|
+
if (zedResult)
|
|
20599
|
+
results.push(zedResult);
|
|
20600
|
+
const aiderResult = writeAiderConfig();
|
|
20601
|
+
if (aiderResult)
|
|
20602
|
+
results.push(aiderResult);
|
|
20384
20603
|
const claudeResult = writeClaudeDesktop();
|
|
20385
20604
|
if (claudeResult)
|
|
20386
20605
|
results.push(claudeResult);
|
|
20387
20606
|
const jetbrainsResult = writeJetBrains(projectRoot);
|
|
20388
20607
|
if (jetbrainsResult)
|
|
20389
20608
|
results.push(jetbrainsResult);
|
|
20390
|
-
const icons = {
|
|
20391
|
-
|
|
20392
|
-
|
|
20393
|
-
|
|
20394
|
-
|
|
20609
|
+
const icons = { created: "✓", updated: "✓", skipped: "⊘", failed: "✗" };
|
|
20610
|
+
console.log(`Results:
|
|
20611
|
+
`);
|
|
20612
|
+
console.log(" IDE Status File");
|
|
20613
|
+
console.log(" ──────────────────────────────────────────────────────────────────");
|
|
20395
20614
|
for (const r of results) {
|
|
20396
20615
|
const rel = r.file.replace(projectRoot, ".").replace(homedir(), "~");
|
|
20397
|
-
|
|
20616
|
+
const statusLabel = r.status === "failed" ? `failed (${r.error})` : r.status;
|
|
20617
|
+
console.log(` ${icons[r.status]} ${r.ide.padEnd(28)} ${r.status.padEnd(8)} ${rel}`);
|
|
20618
|
+
if (r.status === "failed")
|
|
20619
|
+
console.log(` └─ ${statusLabel}`);
|
|
20398
20620
|
}
|
|
20399
20621
|
if (results.length === 0) {
|
|
20400
|
-
console.log(
|
|
20401
|
-
|
|
20622
|
+
console.log(`
|
|
20623
|
+
No supported IDEs detected.`);
|
|
20624
|
+
console.log(` Add this block manually to your IDE config:
|
|
20402
20625
|
`);
|
|
20403
20626
|
console.log(MEMLY_INSTRUCTION_BLOCK);
|
|
20627
|
+
console.log(`
|
|
20628
|
+
`);
|
|
20629
|
+
return;
|
|
20404
20630
|
}
|
|
20631
|
+
try {
|
|
20632
|
+
writeFileSync(join(projectRoot, ".memly-initialized"), new Date().toISOString());
|
|
20633
|
+
} catch {}
|
|
20634
|
+
await reportTelemetry(results);
|
|
20405
20635
|
console.log(`
|
|
20406
|
-
|
|
20636
|
+
â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”
|
|
20637
|
+
`);
|
|
20638
|
+
console.log(`Setup complete. Next steps:
|
|
20639
|
+
`);
|
|
20640
|
+
console.log(" 1. Restart your IDE");
|
|
20641
|
+
console.log(" 2. Start a new conversation");
|
|
20642
|
+
console.log(` 3. Memly loads context automatically
|
|
20407
20643
|
`);
|
|
20408
|
-
console.log(
|
|
20644
|
+
console.log("Dashboard: https://memly.site/dashboard");
|
|
20645
|
+
console.log(`Docs: https://memly.site/docs
|
|
20409
20646
|
`);
|
|
20410
20647
|
}
|
|
20411
20648
|
|
|
20412
20649
|
// src/index.ts
|
|
20413
20650
|
var apiKey = process.env.MEMLY_API_KEY;
|
|
20414
20651
|
if (process.argv.includes("--init") || process.argv.includes("init")) {
|
|
20415
|
-
runInit();
|
|
20652
|
+
await runInit();
|
|
20416
20653
|
process.exit(0);
|
|
20417
20654
|
}
|
|
20418
20655
|
if (!apiKey) {
|