@memrosetta/cli 0.3.1 → 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/chunk-356QK7TK.js +533 -0
- package/dist/chunk-3LSITXZ4.js +69 -0
- package/dist/chunk-6IOTBMUB.js +570 -0
- package/dist/chunk-BGXZ3MDD.js +341 -0
- package/dist/chunk-EZVP3OY7.js +52 -0
- package/dist/chunk-FCHV2JMZ.js +347 -0
- package/dist/{chunk-F7ZMZ6HN.js → chunk-HXZ7MAT6.js} +2 -1
- package/dist/chunk-IM6H35RB.js +341 -0
- package/dist/chunk-IS4IKWPL.js +749 -0
- package/dist/chunk-JGE6RXXH.js +48 -0
- package/dist/chunk-JPBSMZ26.js +343 -0
- package/dist/chunk-KSKRPUZZ.js +43 -0
- package/dist/chunk-L6S3TXHR.js +326 -0
- package/dist/chunk-OCCU5YEG.js +574 -0
- package/dist/chunk-PW52BB6L.js +61 -0
- package/dist/chunk-RABFL4EN.js +528 -0
- package/dist/chunk-RDUU53MG.js +343 -0
- package/dist/chunk-RYPYJJ2K.js +70 -0
- package/dist/{chunk-CATBN3ZT.js → chunk-TQOH7ZXN.js} +6 -18
- package/dist/chunk-Y6NH6K27.js +209 -0
- package/dist/{clear-MTL4CQM3.js → clear-4RQW6SYW.js} +10 -5
- package/dist/clear-BYRCL5ZN.js +39 -0
- package/dist/clear-ETQ7XFMV.js +39 -0
- package/dist/clear-P6H55OKZ.js +39 -0
- package/dist/clear-T3TWJQKL.js +39 -0
- package/dist/{compress-Z46R4N4M.js → compress-HDNYPXZ3.js} +10 -5
- package/dist/compress-S6MS4QW7.js +33 -0
- package/dist/compress-TVWXLW3L.js +33 -0
- package/dist/compress-VLYNZ5BQ.js +33 -0
- package/dist/compress-ZXWRRGHT.js +33 -0
- package/dist/{count-4TZ3C524.js → count-26AGY5XL.js} +10 -5
- package/dist/count-AVG5ZIRW.js +24 -0
- package/dist/count-CJIYYJKN.js +24 -0
- package/dist/count-KFFD4ML7.js +24 -0
- package/dist/count-UUAD3GEJ.js +24 -0
- package/dist/{get-B6AL75EW.js → get-75MGS4LN.js} +4 -2
- package/dist/index.js +6 -3
- package/dist/ingest-A3BAI2C4.js +95 -0
- package/dist/ingest-E7QDD5NY.js +95 -0
- package/dist/ingest-IGI7RXR4.js +95 -0
- package/dist/ingest-JPIHSH7W.js +95 -0
- package/dist/ingest-QGXA4Y6C.js +95 -0
- package/dist/init-2PRW64KV.js +146 -0
- package/dist/init-C3CONL23.js +146 -0
- package/dist/init-DAKOWQSW.js +169 -0
- package/dist/init-FYPMJDRN.js +146 -0
- package/dist/{init-C335O4TX.js → init-GCT4XEI6.js} +2 -2
- package/dist/init-HBEIXY3N.js +146 -0
- package/dist/init-MISGIVCC.js +146 -0
- package/dist/init-MNM4TXXJ.js +146 -0
- package/dist/init-OQW3KXTR.js +182 -0
- package/dist/init-SIEKAILM.js +113 -0
- package/dist/init-TM7GTHTJ.js +146 -0
- package/dist/init-VYWOSISP.js +146 -0
- package/dist/init-WCL7FZOJ.js +182 -0
- package/dist/init-Z53FKT6J.js +205 -0
- package/dist/init-ZLUDTJAP.js +182 -0
- package/dist/{invalidate-C54IVIGL.js → invalidate-D2O4VWZU.js} +4 -2
- package/dist/{maintain-ZPHG47YY.js → maintain-B65WIMGJ.js} +10 -5
- package/dist/maintain-EWOU3DGT.js +37 -0
- package/dist/maintain-FELKLG7O.js +37 -0
- package/dist/maintain-WRRDXEG3.js +37 -0
- package/dist/maintain-XTCSOQBU.js +37 -0
- package/dist/{relate-R6DQUJCQ.js → relate-2QMG5H2I.js} +5 -3
- package/dist/relate-C22YYJZT.js +46 -0
- package/dist/relate-V5RYMJJ5.js +47 -0
- package/dist/relate-W4BXPFJA.js +46 -0
- package/dist/reset-45EUG44R.js +95 -0
- package/dist/reset-5NDHFUC3.js +95 -0
- package/dist/reset-C7I3LA5M.js +95 -0
- package/dist/reset-F6F2R6BR.js +95 -0
- package/dist/reset-K3K4K5CT.js +95 -0
- package/dist/reset-K4WZJ4WU.js +95 -0
- package/dist/reset-LWRG2LIM.js +129 -0
- package/dist/{reset-P63V46RN.js → reset-NNQQJN6L.js} +2 -2
- package/dist/reset-P5FXLI4E.js +112 -0
- package/dist/reset-SORHIEKY.js +112 -0
- package/dist/reset-SVJMWYAK.js +95 -0
- package/dist/reset-W22RJGYZ.js +112 -0
- package/dist/reset-W3QVA632.js +95 -0
- package/dist/reset-WYEU6XJQ.js +112 -0
- package/dist/{search-YEYKOEXC.js → search-2SU5WQYK.js} +9 -4
- package/dist/search-5EE3XB2R.js +48 -0
- package/dist/search-L6P3XY47.js +48 -0
- package/dist/search-UA7Y55LQ.js +48 -0
- package/dist/search-ZKLRJXFT.js +48 -0
- package/dist/status-3XVXJF7M.js +170 -0
- package/dist/status-4THJLSJL.js +131 -0
- package/dist/status-4UYY7TOE.js +131 -0
- package/dist/status-7G3RMR6A.js +139 -0
- package/dist/status-7M4TJVDH.js +170 -0
- package/dist/status-7MEEKEC2.js +131 -0
- package/dist/status-BQL4VJ6Y.js +149 -0
- package/dist/status-BTEVCZ5K.js +125 -0
- package/dist/status-F3NZGGPH.js +131 -0
- package/dist/status-GQMXOMRN.js +131 -0
- package/dist/status-HJGTMHTD.js +131 -0
- package/dist/{status-AMMF6QGI.js → status-IEKR6SSH.js} +35 -6
- package/dist/status-JJGVWESB.js +139 -0
- package/dist/status-LDVRVYZH.js +131 -0
- package/dist/{status-PYD6U7U7.js → status-TATIX3R6.js} +1 -1
- package/dist/status-TLK2LKG6.js +218 -0
- package/dist/{store-ZMERYHI6.js → store-6D5OJ2DX.js} +12 -7
- package/dist/store-I4JNJWAZ.js +91 -0
- package/dist/store-R4LXYE57.js +91 -0
- package/dist/store-UMR2NOT7.js +91 -0
- package/dist/store-ZDI5AH4M.js +91 -0
- package/dist/update-XJLMXCDZ.js +36 -0
- package/dist/{working-memory-2RRQFX4Q.js → working-memory-2U33JHJB.js} +10 -6
- package/dist/working-memory-35TMFU3P.js +53 -0
- package/dist/working-memory-IBWGIXLW.js +53 -0
- package/dist/working-memory-RZE3GYQZ.js +53 -0
- package/dist/working-memory-WGB5DZ3B.js +53 -0
- package/package.json +3 -3
- package/dist/chunk-MWLPPS7U.js +0 -133
- package/dist/ingest-ZOR3XSAE.js +0 -152
- package/dist/init-7VFBCA4O.js +0 -26
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
// src/integrations/claude-code.ts
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { homedir } from "os";
|
|
4
|
+
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
5
|
+
var CLAUDE_DIR = join(homedir(), ".claude");
|
|
6
|
+
var CLAUDE_SETTINGS_PATH = join(CLAUDE_DIR, "settings.json");
|
|
7
|
+
var CLAUDE_MD_PATH = join(CLAUDE_DIR, "CLAUDE.md");
|
|
8
|
+
function isMemrosettaHook(command) {
|
|
9
|
+
return command.includes("memrosetta") && (command.includes("on-stop") || command.includes("on-prompt"));
|
|
10
|
+
}
|
|
11
|
+
function readClaudeSettings() {
|
|
12
|
+
if (!existsSync(CLAUDE_SETTINGS_PATH)) return {};
|
|
13
|
+
try {
|
|
14
|
+
return JSON.parse(
|
|
15
|
+
readFileSync(CLAUDE_SETTINGS_PATH, "utf-8")
|
|
16
|
+
);
|
|
17
|
+
} catch {
|
|
18
|
+
return {};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function writeClaudeSettings(settings) {
|
|
22
|
+
if (!existsSync(CLAUDE_DIR)) {
|
|
23
|
+
throw new Error(
|
|
24
|
+
"~/.claude directory does not exist. Is Claude Code installed?"
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
writeFileSync(
|
|
28
|
+
CLAUDE_SETTINGS_PATH,
|
|
29
|
+
JSON.stringify(settings, null, 2),
|
|
30
|
+
"utf-8"
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
function removeMemrosettaHooksFromSettings(settings) {
|
|
34
|
+
if (!settings.hooks) return settings;
|
|
35
|
+
const cleaned = {};
|
|
36
|
+
for (const [eventType, hookConfigs] of Object.entries(settings.hooks)) {
|
|
37
|
+
const filtered = hookConfigs.filter(
|
|
38
|
+
(hc) => !hc.hooks.some((h) => isMemrosettaHook(h.command))
|
|
39
|
+
);
|
|
40
|
+
cleaned[eventType] = filtered;
|
|
41
|
+
}
|
|
42
|
+
return { ...settings, hooks: cleaned };
|
|
43
|
+
}
|
|
44
|
+
function isClaudeCodeInstalled() {
|
|
45
|
+
return existsSync(CLAUDE_DIR);
|
|
46
|
+
}
|
|
47
|
+
function isClaudeCodeConfigured() {
|
|
48
|
+
const settings = readClaudeSettings();
|
|
49
|
+
const stopHooks = settings.hooks?.["Stop"] || [];
|
|
50
|
+
return stopHooks.some(
|
|
51
|
+
(hc) => hc.hooks.some((h) => isMemrosettaHook(h.command))
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
function registerClaudeCodeHooks() {
|
|
55
|
+
if (!isClaudeCodeInstalled()) return false;
|
|
56
|
+
let settings = readClaudeSettings();
|
|
57
|
+
if (!settings.hooks) {
|
|
58
|
+
settings = { ...settings, hooks: {} };
|
|
59
|
+
}
|
|
60
|
+
settings = removeMemrosettaHooksFromSettings(settings);
|
|
61
|
+
const stopHookConfigs = settings.hooks["Stop"] || [];
|
|
62
|
+
settings.hooks["Stop"] = [
|
|
63
|
+
...stopHookConfigs,
|
|
64
|
+
{
|
|
65
|
+
matcher: "*",
|
|
66
|
+
hooks: [
|
|
67
|
+
{
|
|
68
|
+
type: "command",
|
|
69
|
+
command: "npx -y @memrosetta/cli memrosetta-on-stop",
|
|
70
|
+
timeout: 15
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
];
|
|
75
|
+
writeClaudeSettings(settings);
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
function removeClaudeCodeHooks() {
|
|
79
|
+
if (!existsSync(CLAUDE_SETTINGS_PATH)) return false;
|
|
80
|
+
const settings = readClaudeSettings();
|
|
81
|
+
if (!settings.hooks) return false;
|
|
82
|
+
const cleaned = removeMemrosettaHooksFromSettings(settings);
|
|
83
|
+
writeClaudeSettings(cleaned);
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
function updateClaudeMd() {
|
|
87
|
+
if (!isClaudeCodeInstalled()) return false;
|
|
88
|
+
const marker = "## MemRosetta (Long-term Memory)";
|
|
89
|
+
const existing = existsSync(CLAUDE_MD_PATH) ? readFileSync(CLAUDE_MD_PATH, "utf-8") : "";
|
|
90
|
+
if (existing.includes(marker)) return false;
|
|
91
|
+
const memorySection = `
|
|
92
|
+
|
|
93
|
+
${marker}
|
|
94
|
+
|
|
95
|
+
MCP server \`memory-service\` provides long-term memory across sessions.
|
|
96
|
+
userId defaults to the system username -- no need to specify it.
|
|
97
|
+
|
|
98
|
+
### Search (mcp__memory-service__memrosetta_search)
|
|
99
|
+
When you need information not in the current context, search past memories.
|
|
100
|
+
No need to specify userId -- it defaults to the system username.
|
|
101
|
+
|
|
102
|
+
### Store (mcp__memory-service__memrosetta_store)
|
|
103
|
+
Every response, check if there is something worth storing. If yes, store immediately.
|
|
104
|
+
No need to specify userId -- it defaults to the system username.
|
|
105
|
+
- **decision**: tech choices, architecture decisions
|
|
106
|
+
- **fact**: key facts about projects or systems
|
|
107
|
+
- **preference**: user preferences
|
|
108
|
+
- **event**: completed work, incidents
|
|
109
|
+
|
|
110
|
+
Do NOT store:
|
|
111
|
+
- Code itself (that belongs in git)
|
|
112
|
+
- Intermediate steps, debugging attempts
|
|
113
|
+
- Simple confirmations ("yes", "go ahead")
|
|
114
|
+
- Content already in CLAUDE.md
|
|
115
|
+
|
|
116
|
+
Always include keywords -- they directly affect search quality.
|
|
117
|
+
`;
|
|
118
|
+
writeFileSync(CLAUDE_MD_PATH, existing + memorySection, "utf-8");
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
function removeClaudeMdSection() {
|
|
122
|
+
if (!existsSync(CLAUDE_MD_PATH)) return false;
|
|
123
|
+
const content = readFileSync(CLAUDE_MD_PATH, "utf-8");
|
|
124
|
+
const marker = "## MemRosetta (Long-term Memory)";
|
|
125
|
+
const markerIdx = content.indexOf(marker);
|
|
126
|
+
if (markerIdx === -1) return false;
|
|
127
|
+
const afterMarker = content.slice(markerIdx + marker.length);
|
|
128
|
+
const nextHeadingMatch = afterMarker.match(/\n## (?!MemRosetta)/);
|
|
129
|
+
const endIdx = nextHeadingMatch ? markerIdx + marker.length + (nextHeadingMatch.index ?? afterMarker.length) : content.length;
|
|
130
|
+
const before = content.slice(0, markerIdx).replace(/\n+$/, "");
|
|
131
|
+
const after = content.slice(endIdx);
|
|
132
|
+
const updated = (before + after).trimEnd() + "\n";
|
|
133
|
+
writeFileSync(CLAUDE_MD_PATH, updated, "utf-8");
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// src/integrations/mcp.ts
|
|
138
|
+
import { join as join2 } from "path";
|
|
139
|
+
import { homedir as homedir2 } from "os";
|
|
140
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
141
|
+
var MCP_CONFIG_PATH = join2(homedir2(), ".mcp.json");
|
|
142
|
+
var SERVER_NAME = "memory-service";
|
|
143
|
+
function readMcpConfig(path) {
|
|
144
|
+
if (!existsSync2(path)) return {};
|
|
145
|
+
try {
|
|
146
|
+
return JSON.parse(readFileSync2(path, "utf-8"));
|
|
147
|
+
} catch {
|
|
148
|
+
return {};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function writeMcpConfig(path, config) {
|
|
152
|
+
writeFileSync2(path, JSON.stringify(config, null, 2), "utf-8");
|
|
153
|
+
}
|
|
154
|
+
function mcpServerEntry() {
|
|
155
|
+
return {
|
|
156
|
+
command: "npx",
|
|
157
|
+
args: ["-y", "@memrosetta/mcp"],
|
|
158
|
+
env: {
|
|
159
|
+
MEMROSETTA_EMBEDDINGS: "false"
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function isGenericMCPConfigured() {
|
|
164
|
+
const config = readMcpConfig(MCP_CONFIG_PATH);
|
|
165
|
+
return !!config.mcpServers?.[SERVER_NAME];
|
|
166
|
+
}
|
|
167
|
+
function registerGenericMCP() {
|
|
168
|
+
const config = readMcpConfig(MCP_CONFIG_PATH);
|
|
169
|
+
const servers = config.mcpServers ?? {};
|
|
170
|
+
writeMcpConfig(MCP_CONFIG_PATH, {
|
|
171
|
+
...config,
|
|
172
|
+
mcpServers: { ...servers, [SERVER_NAME]: mcpServerEntry() }
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
function removeGenericMCP() {
|
|
176
|
+
if (!existsSync2(MCP_CONFIG_PATH)) return false;
|
|
177
|
+
const config = readMcpConfig(MCP_CONFIG_PATH);
|
|
178
|
+
if (!config.mcpServers?.[SERVER_NAME]) return false;
|
|
179
|
+
const { [SERVER_NAME]: _, ...rest } = config.mcpServers;
|
|
180
|
+
writeMcpConfig(MCP_CONFIG_PATH, { ...config, mcpServers: rest });
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
function getGenericMCPPath() {
|
|
184
|
+
return MCP_CONFIG_PATH;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// src/integrations/cursor.ts
|
|
188
|
+
import { join as join3 } from "path";
|
|
189
|
+
import { homedir as homedir3 } from "os";
|
|
190
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync } from "fs";
|
|
191
|
+
var SERVER_NAME2 = "memory-service";
|
|
192
|
+
var CURSOR_RULES_PATH_GETTER = () => join3(homedir3(), ".cursorrules");
|
|
193
|
+
var MEMROSETTA_CURSOR_RULES_MARKER = "## MemRosetta (Long-term Memory)";
|
|
194
|
+
var MEMROSETTA_CURSOR_RULES = `
|
|
195
|
+
|
|
196
|
+
${MEMROSETTA_CURSOR_RULES_MARKER}
|
|
197
|
+
|
|
198
|
+
MCP server \`memory-service\` provides persistent memory across sessions.
|
|
199
|
+
userId defaults to the system username -- no need to specify it.
|
|
200
|
+
|
|
201
|
+
### When to search (memrosetta_search)
|
|
202
|
+
When you need information not in the current context, search past memories.
|
|
203
|
+
No need to specify userId -- it defaults to the system username.
|
|
204
|
+
|
|
205
|
+
### When to store (memrosetta_store)
|
|
206
|
+
When you encounter important information, store it immediately.
|
|
207
|
+
No need to specify userId -- it defaults to the system username.
|
|
208
|
+
- **decision**: technical choices, architecture decisions
|
|
209
|
+
- **fact**: key facts about projects or systems
|
|
210
|
+
- **preference**: user preferences and coding style
|
|
211
|
+
- **event**: completed work, deployments, incidents
|
|
212
|
+
|
|
213
|
+
Do NOT store: code itself, debugging steps, simple confirmations.
|
|
214
|
+
Always include keywords for better search quality.
|
|
215
|
+
|
|
216
|
+
### When to relate (memrosetta_relate)
|
|
217
|
+
When new information updates or contradicts existing memories, create a relation.
|
|
218
|
+
|
|
219
|
+
### Working memory (memrosetta_working_memory)
|
|
220
|
+
Call this at the start of complex tasks to load relevant context.
|
|
221
|
+
No need to specify userId -- it defaults to the system username.
|
|
222
|
+
`;
|
|
223
|
+
function getCursorConfigDir() {
|
|
224
|
+
return join3(homedir3(), ".cursor");
|
|
225
|
+
}
|
|
226
|
+
function getCursorMcpPath() {
|
|
227
|
+
return join3(getCursorConfigDir(), "mcp.json");
|
|
228
|
+
}
|
|
229
|
+
function readCursorConfig(path) {
|
|
230
|
+
if (!existsSync3(path)) return {};
|
|
231
|
+
try {
|
|
232
|
+
return JSON.parse(readFileSync3(path, "utf-8"));
|
|
233
|
+
} catch {
|
|
234
|
+
return {};
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function writeCursorConfig(path, config) {
|
|
238
|
+
const dir = getCursorConfigDir();
|
|
239
|
+
if (!existsSync3(dir)) {
|
|
240
|
+
mkdirSync(dir, { recursive: true });
|
|
241
|
+
}
|
|
242
|
+
writeFileSync3(path, JSON.stringify(config, null, 2), "utf-8");
|
|
243
|
+
}
|
|
244
|
+
function mcpServerEntry2() {
|
|
245
|
+
return {
|
|
246
|
+
command: "npx",
|
|
247
|
+
args: ["-y", "@memrosetta/mcp"],
|
|
248
|
+
env: {
|
|
249
|
+
MEMROSETTA_EMBEDDINGS: "false"
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
function isCursorConfigured() {
|
|
254
|
+
const path = getCursorMcpPath();
|
|
255
|
+
const config = readCursorConfig(path);
|
|
256
|
+
return !!config.mcpServers?.[SERVER_NAME2];
|
|
257
|
+
}
|
|
258
|
+
function registerCursorMCP() {
|
|
259
|
+
const path = getCursorMcpPath();
|
|
260
|
+
const config = readCursorConfig(path);
|
|
261
|
+
const servers = config.mcpServers ?? {};
|
|
262
|
+
writeCursorConfig(path, {
|
|
263
|
+
...config,
|
|
264
|
+
mcpServers: { ...servers, [SERVER_NAME2]: mcpServerEntry2() }
|
|
265
|
+
});
|
|
266
|
+
updateCursorRules();
|
|
267
|
+
}
|
|
268
|
+
function removeCursorMCP() {
|
|
269
|
+
const path = getCursorMcpPath();
|
|
270
|
+
if (!existsSync3(path)) return false;
|
|
271
|
+
const config = readCursorConfig(path);
|
|
272
|
+
if (!config.mcpServers?.[SERVER_NAME2]) return false;
|
|
273
|
+
const { [SERVER_NAME2]: _, ...rest } = config.mcpServers;
|
|
274
|
+
writeCursorConfig(path, { ...config, mcpServers: rest });
|
|
275
|
+
removeCursorRulesSection();
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
function getCursorMcpConfigPath() {
|
|
279
|
+
return getCursorMcpPath();
|
|
280
|
+
}
|
|
281
|
+
function getCursorRulesPath() {
|
|
282
|
+
return CURSOR_RULES_PATH_GETTER();
|
|
283
|
+
}
|
|
284
|
+
function updateCursorRules() {
|
|
285
|
+
const rulesPath = CURSOR_RULES_PATH_GETTER();
|
|
286
|
+
const existing = existsSync3(rulesPath) ? readFileSync3(rulesPath, "utf-8") : "";
|
|
287
|
+
if (existing.includes(MEMROSETTA_CURSOR_RULES_MARKER)) return false;
|
|
288
|
+
writeFileSync3(rulesPath, existing + MEMROSETTA_CURSOR_RULES, "utf-8");
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
function removeCursorRulesSection() {
|
|
292
|
+
const rulesPath = CURSOR_RULES_PATH_GETTER();
|
|
293
|
+
if (!existsSync3(rulesPath)) return false;
|
|
294
|
+
const content = readFileSync3(rulesPath, "utf-8");
|
|
295
|
+
const markerIdx = content.indexOf(MEMROSETTA_CURSOR_RULES_MARKER);
|
|
296
|
+
if (markerIdx === -1) return false;
|
|
297
|
+
const afterMarker = content.slice(
|
|
298
|
+
markerIdx + MEMROSETTA_CURSOR_RULES_MARKER.length
|
|
299
|
+
);
|
|
300
|
+
const nextHeadingMatch = afterMarker.match(/\n## (?!MemRosetta)/);
|
|
301
|
+
const endIdx = nextHeadingMatch ? markerIdx + MEMROSETTA_CURSOR_RULES_MARKER.length + (nextHeadingMatch.index ?? afterMarker.length) : content.length;
|
|
302
|
+
const before = content.slice(0, markerIdx).replace(/\n+$/, "");
|
|
303
|
+
const after = content.slice(endIdx);
|
|
304
|
+
const updated = (before + after).trimEnd() + "\n";
|
|
305
|
+
writeFileSync3(rulesPath, updated, "utf-8");
|
|
306
|
+
return true;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export {
|
|
310
|
+
isClaudeCodeInstalled,
|
|
311
|
+
isClaudeCodeConfigured,
|
|
312
|
+
registerClaudeCodeHooks,
|
|
313
|
+
removeClaudeCodeHooks,
|
|
314
|
+
updateClaudeMd,
|
|
315
|
+
removeClaudeMdSection,
|
|
316
|
+
isGenericMCPConfigured,
|
|
317
|
+
registerGenericMCP,
|
|
318
|
+
removeGenericMCP,
|
|
319
|
+
getGenericMCPPath,
|
|
320
|
+
isCursorConfigured,
|
|
321
|
+
registerCursorMCP,
|
|
322
|
+
removeCursorMCP,
|
|
323
|
+
getCursorMcpConfigPath,
|
|
324
|
+
getCursorRulesPath,
|
|
325
|
+
removeCursorRulesSection
|
|
326
|
+
};
|