coding-friend-cli 1.21.1 → 1.23.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-PDVSGGH6.js → chunk-2ETE7NEL.js} +32 -28
- package/dist/{chunk-PYTEAC6K.js → chunk-DMJCO6LJ.js} +1 -1
- package/dist/{chunk-3KXYEC2T.js → chunk-LTHJTWJ6.js} +82 -3
- package/dist/chunk-NREZK463.js +41 -0
- package/dist/{chunk-BIX7AJU3.js → chunk-O4CNZB5H.js} +1 -1
- package/dist/{memory-27ZSRPM7.js → chunk-WCSNAEOF.js} +155 -73
- package/dist/{config-5I3XJEEL.js → config-5DKOGWWJ.js} +9 -14
- package/dist/{dev-4A5CTBGK.js → dev-S7S3SFKI.js} +19 -18
- package/dist/{disable-FNMRPUO7.js → disable-V7OLXEUH.js} +2 -2
- package/dist/{enable-HUKTMK5U.js → enable-OLHRKZCV.js} +2 -2
- package/dist/{host-V5O3PDCF.js → host-RR6FT7AX.js} +7 -6
- package/dist/index.js +31 -31
- package/dist/{init-3XMC6YJI.js → init-6B2OHKFX.js} +22 -40
- package/dist/{install-5ZBHH2OM.js → install-BURZ5QEM.js} +7 -6
- package/dist/mcp-CB4PUUES.js +156 -0
- package/dist/memory-TJZNGTOA.js +37 -0
- package/dist/{permission-BEC6YZQA.js → permission-QIJLEMJ6.js} +4 -3
- package/dist/postinstall.js +2 -2
- package/dist/{session-ZDJ2APGL.js → session-IECOM63R.js} +1 -1
- package/dist/{status-F6WASK7N.js → status-ZZRJ3VGF.js} +7 -7
- package/dist/{statusline-AISH77XP.js → statusline-YL44XYGF.js} +4 -3
- package/dist/{uninstall-RJ6SBB76.js → uninstall-OXWRPWYF.js} +7 -6
- package/dist/{update-536C3YG7.js → update-6N7EASFT.js} +4 -4
- package/dist/{update-check-L5TNWT2J.js → update-check-XSETLRVR.js} +1 -1
- package/lib/cf-memory/README.md +4 -1
- package/lib/cf-memory/package.json +0 -1
- package/lib/cf-memory/src/__tests__/daemon-client.test.ts +146 -0
- package/lib/cf-memory/src/daemon/process.ts +7 -0
- package/lib/cf-memory/src/index.ts +21 -2
- package/lib/cf-memory/src/lib/daemon-client.ts +54 -3
- package/lib/cf-memory/src/lib/tier.ts +27 -3
- package/lib/learn-host/package.json +0 -1
- package/lib/learn-mcp/package.json +0 -1
- package/lib/learn-mcp/src/index.ts +8 -1
- package/package.json +1 -1
- package/dist/chunk-W5CD7WTX.js +0 -15
- package/dist/mcp-U34LFD34.js +0 -106
- package/lib/cf-memory/CHANGELOG.md +0 -42
- package/lib/learn-host/CHANGELOG.md +0 -35
- package/lib/learn-mcp/CHANGELOG.md +0 -16
|
@@ -4,19 +4,20 @@ import {
|
|
|
4
4
|
editMemoryDaemonTimeout,
|
|
5
5
|
editMemoryEmbedding,
|
|
6
6
|
editMemoryTier,
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
getMemoryMcpStatus,
|
|
8
|
+
memoryConfigMenu,
|
|
9
|
+
writeMemoryMcpEntry
|
|
10
|
+
} from "./chunk-LTHJTWJ6.js";
|
|
11
|
+
import {
|
|
12
|
+
getLibPath
|
|
13
|
+
} from "./chunk-RZRT7NGT.js";
|
|
9
14
|
import {
|
|
10
15
|
loadConfig,
|
|
11
16
|
resolveMemoryDir
|
|
12
17
|
} from "./chunk-SIQJPT47.js";
|
|
13
|
-
import {
|
|
14
|
-
getLibPath
|
|
15
|
-
} from "./chunk-RZRT7NGT.js";
|
|
16
|
-
import "./chunk-PRIH34UB.js";
|
|
17
18
|
import {
|
|
18
19
|
showConfigHint
|
|
19
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-O4CNZB5H.js";
|
|
20
21
|
import {
|
|
21
22
|
run,
|
|
22
23
|
runWithStderr
|
|
@@ -29,8 +30,9 @@ import {
|
|
|
29
30
|
localConfigPath
|
|
30
31
|
} from "./chunk-DO6FV6BL.js";
|
|
31
32
|
import {
|
|
32
|
-
log
|
|
33
|
-
|
|
33
|
+
log,
|
|
34
|
+
printBanner
|
|
35
|
+
} from "./chunk-NREZK463.js";
|
|
34
36
|
|
|
35
37
|
// src/commands/memory.ts
|
|
36
38
|
import { existsSync, readdirSync, statSync, rmSync } from "fs";
|
|
@@ -62,7 +64,7 @@ function truncateError(text) {
|
|
|
62
64
|
const skipped = lines.length - 28;
|
|
63
65
|
return [...head, ` ... (${skipped} lines omitted) ...`, ...tail].join("\n");
|
|
64
66
|
}
|
|
65
|
-
function
|
|
67
|
+
function ensureMemoryBuilt(mcpDir) {
|
|
66
68
|
if (!existsSync(join(mcpDir, "node_modules"))) {
|
|
67
69
|
log.step("Installing memory server dependencies (one-time setup)...");
|
|
68
70
|
const result = runWithStderr("npm", ["install"], { cwd: mcpDir });
|
|
@@ -84,6 +86,77 @@ function ensureBuilt(mcpDir) {
|
|
|
84
86
|
log.success("Done.");
|
|
85
87
|
}
|
|
86
88
|
}
|
|
89
|
+
function printMemoryMcpConfig(serverPath, memoryDir) {
|
|
90
|
+
console.log(chalk.dim("Add this to your MCP client config:"));
|
|
91
|
+
console.log();
|
|
92
|
+
console.log(
|
|
93
|
+
chalk.yellow.bold("--- Claude Code (.mcp.json in project root) ---")
|
|
94
|
+
);
|
|
95
|
+
console.log(`
|
|
96
|
+
{
|
|
97
|
+
"mcpServers": {
|
|
98
|
+
"coding-friend-memory": {
|
|
99
|
+
"command": "node",
|
|
100
|
+
"args": ["${serverPath}", "${memoryDir}"]
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}`);
|
|
104
|
+
console.log();
|
|
105
|
+
console.log(
|
|
106
|
+
chalk.yellow.bold(
|
|
107
|
+
"--- Claude Desktop / Claude Chat (claude_desktop_config.json) ---"
|
|
108
|
+
)
|
|
109
|
+
);
|
|
110
|
+
console.log(`
|
|
111
|
+
{
|
|
112
|
+
"mcpServers": {
|
|
113
|
+
"coding-friend-memory": {
|
|
114
|
+
"command": "node",
|
|
115
|
+
"args": ["${serverPath}", "${memoryDir}"]
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}`);
|
|
119
|
+
console.log();
|
|
120
|
+
console.log(chalk.yellow.bold("--- Generic MCP client ---"));
|
|
121
|
+
console.log(`
|
|
122
|
+
Server command: node ${serverPath} ${memoryDir}
|
|
123
|
+
Transport: stdio`);
|
|
124
|
+
console.log();
|
|
125
|
+
console.log(chalk.yellow.bold("--- Available tools ---"));
|
|
126
|
+
console.log();
|
|
127
|
+
console.log(
|
|
128
|
+
` ${chalk.white("memory_store")} ${chalk.dim("Store a new memory")}`
|
|
129
|
+
);
|
|
130
|
+
console.log(
|
|
131
|
+
` ${chalk.white("memory_search")} ${chalk.dim("Search memories (keyword match)")}`
|
|
132
|
+
);
|
|
133
|
+
console.log(
|
|
134
|
+
` ${chalk.white("memory_retrieve")} ${chalk.dim("Get a specific memory by ID")}`
|
|
135
|
+
);
|
|
136
|
+
console.log(
|
|
137
|
+
` ${chalk.white("memory_list")} ${chalk.dim("List memories with filtering")}`
|
|
138
|
+
);
|
|
139
|
+
console.log(
|
|
140
|
+
` ${chalk.white("memory_update")} ${chalk.dim("Update existing memory")}`
|
|
141
|
+
);
|
|
142
|
+
console.log(
|
|
143
|
+
` ${chalk.white("memory_delete")} ${chalk.dim("Delete a memory")}`
|
|
144
|
+
);
|
|
145
|
+
console.log();
|
|
146
|
+
console.log(chalk.yellow.bold("--- Resources ---"));
|
|
147
|
+
console.log();
|
|
148
|
+
console.log(
|
|
149
|
+
` ${chalk.white("memory://index")} ${chalk.dim("Browse all memories")}`
|
|
150
|
+
);
|
|
151
|
+
console.log(
|
|
152
|
+
` ${chalk.white("memory://stats")} ${chalk.dim("Storage statistics")}`
|
|
153
|
+
);
|
|
154
|
+
console.log();
|
|
155
|
+
log.warn(
|
|
156
|
+
"Note: The memory path is project-specific. Use local .mcp.json (per project), not global ~/.claude/.mcp.json."
|
|
157
|
+
);
|
|
158
|
+
console.log();
|
|
159
|
+
}
|
|
87
160
|
function formatUptime(seconds) {
|
|
88
161
|
if (seconds < 60) return `${Math.round(seconds)}s`;
|
|
89
162
|
if (seconds < 3600) return `${Math.round(seconds / 60)}m`;
|
|
@@ -93,7 +166,7 @@ async function memoryStatusCommand() {
|
|
|
93
166
|
const memoryDir = getMemoryDir();
|
|
94
167
|
const docCount = countMdFiles(memoryDir);
|
|
95
168
|
const mcpDir = getLibPath("cf-memory");
|
|
96
|
-
|
|
169
|
+
ensureMemoryBuilt(mcpDir);
|
|
97
170
|
const { isDaemonRunning, getDaemonInfo } = await import(join(mcpDir, "dist/daemon/process.js"));
|
|
98
171
|
const { areSqliteDepsAvailable } = await import(join(mcpDir, "dist/lib/lazy-install.js"));
|
|
99
172
|
const sqliteAvailable = areSqliteDepsAvailable();
|
|
@@ -107,7 +180,7 @@ async function memoryStatusCommand() {
|
|
|
107
180
|
} else {
|
|
108
181
|
tierLabel = chalk.cyan("Tier 3 (Markdown)");
|
|
109
182
|
}
|
|
110
|
-
|
|
183
|
+
printBanner("\u{1F9E0} Coding Friend Memory");
|
|
111
184
|
console.log();
|
|
112
185
|
log.info(`Tier: ${tierLabel}`);
|
|
113
186
|
log.info(`Memory dir: ${chalk.cyan(memoryDir)}`);
|
|
@@ -140,6 +213,20 @@ async function memoryStatusCommand() {
|
|
|
140
213
|
const model = embeddingConfig.model ?? (provider === "ollama" ? "all-minilm:l6-v2" : "Xenova/all-MiniLM-L6-v2");
|
|
141
214
|
log.info(`Embedding: ${chalk.cyan(model)} ${chalk.dim(`(${provider})`)}`);
|
|
142
215
|
}
|
|
216
|
+
const mcpStatus = getMemoryMcpStatus();
|
|
217
|
+
if (mcpStatus.configured && mcpStatus.scope === "local") {
|
|
218
|
+
log.info(
|
|
219
|
+
`MCP: ${chalk.green("configured")} ${chalk.dim("(local .mcp.json)")}`
|
|
220
|
+
);
|
|
221
|
+
} else if (mcpStatus.configured && mcpStatus.scope === "global") {
|
|
222
|
+
log.info(
|
|
223
|
+
`MCP: ${chalk.green("configured")} ${chalk.dim("(global ~/.claude/.mcp.json)")} ${chalk.yellow("\u26A0 global config uses a fixed path \u2014 only works for one project")}`
|
|
224
|
+
);
|
|
225
|
+
} else {
|
|
226
|
+
log.info(
|
|
227
|
+
`MCP: ${chalk.dim("not configured")} ${chalk.dim('(run "cf memory init" or add manually via "cf memory mcp")')}`
|
|
228
|
+
);
|
|
229
|
+
}
|
|
143
230
|
const autoCapture = config.memory?.autoCapture ?? false;
|
|
144
231
|
log.info(
|
|
145
232
|
`Auto-capture: ${autoCapture ? chalk.green("on") : chalk.dim("off")}`
|
|
@@ -165,7 +252,7 @@ async function memorySearchCommand(query) {
|
|
|
165
252
|
process.exit(1);
|
|
166
253
|
}
|
|
167
254
|
const mcpDir = getLibPath("cf-memory");
|
|
168
|
-
|
|
255
|
+
ensureMemoryBuilt(mcpDir);
|
|
169
256
|
const result = run(
|
|
170
257
|
"node",
|
|
171
258
|
[
|
|
@@ -205,7 +292,7 @@ async function memoryListCommand(opts) {
|
|
|
205
292
|
return;
|
|
206
293
|
}
|
|
207
294
|
const mcpDir = getLibPath("cf-memory");
|
|
208
|
-
|
|
295
|
+
ensureMemoryBuilt(mcpDir);
|
|
209
296
|
const result = run(
|
|
210
297
|
"node",
|
|
211
298
|
[
|
|
@@ -246,7 +333,7 @@ async function memoryListCommand(opts) {
|
|
|
246
333
|
async function memoryStartDaemonCommand() {
|
|
247
334
|
const memoryDir = getMemoryDir();
|
|
248
335
|
const mcpDir = getLibPath("cf-memory");
|
|
249
|
-
|
|
336
|
+
ensureMemoryBuilt(mcpDir);
|
|
250
337
|
const { isDaemonRunning, getDaemonInfo, spawnDaemon } = await import(join(mcpDir, "dist/daemon/process.js"));
|
|
251
338
|
if (await isDaemonRunning()) {
|
|
252
339
|
const info = getDaemonInfo();
|
|
@@ -256,7 +343,8 @@ async function memoryStartDaemonCommand() {
|
|
|
256
343
|
log.step("Starting memory daemon...");
|
|
257
344
|
const config = loadConfig();
|
|
258
345
|
const embedding = config.memory?.embedding;
|
|
259
|
-
const
|
|
346
|
+
const idleTimeoutMs = config.memory?.daemon?.idleTimeout;
|
|
347
|
+
const result = await spawnDaemon(memoryDir, embedding, { idleTimeoutMs });
|
|
260
348
|
if (result) {
|
|
261
349
|
log.success(`Daemon started (PID ${result.pid})`);
|
|
262
350
|
log.info(`Watching ${chalk.cyan(memoryDir)} for changes`);
|
|
@@ -267,7 +355,7 @@ async function memoryStartDaemonCommand() {
|
|
|
267
355
|
}
|
|
268
356
|
async function memoryStopDaemonCommand() {
|
|
269
357
|
const mcpDir = getLibPath("cf-memory");
|
|
270
|
-
|
|
358
|
+
ensureMemoryBuilt(mcpDir);
|
|
271
359
|
const { stopDaemon, isDaemonRunning } = await import(join(mcpDir, "dist/daemon/process.js"));
|
|
272
360
|
if (!await isDaemonRunning()) {
|
|
273
361
|
log.info("Daemon is not running.");
|
|
@@ -284,7 +372,7 @@ async function memoryStopDaemonCommand() {
|
|
|
284
372
|
async function memoryRebuildCommand() {
|
|
285
373
|
const memoryDir = getMemoryDir();
|
|
286
374
|
const mcpDir = getLibPath("cf-memory");
|
|
287
|
-
|
|
375
|
+
ensureMemoryBuilt(mcpDir);
|
|
288
376
|
const { areSqliteDepsAvailable } = await import(join(mcpDir, "dist/lib/lazy-install.js"));
|
|
289
377
|
if (areSqliteDepsAvailable()) {
|
|
290
378
|
log.step("Rebuilding SQLite index + embeddings...");
|
|
@@ -345,7 +433,6 @@ function getDbPath(memoryDir) {
|
|
|
345
433
|
return null;
|
|
346
434
|
}
|
|
347
435
|
}
|
|
348
|
-
var em = chalk.hex("#10b981");
|
|
349
436
|
async function ensureSqliteDepsIfNeeded(mcpDir) {
|
|
350
437
|
const config = loadConfig();
|
|
351
438
|
const tier = config.memory?.tier ?? "auto";
|
|
@@ -369,10 +456,38 @@ async function ensureSqliteDepsIfNeeded(mcpDir) {
|
|
|
369
456
|
log.success("Dependencies installed.");
|
|
370
457
|
return true;
|
|
371
458
|
}
|
|
459
|
+
async function setupMemoryMcp(memoryDir, mcpDir) {
|
|
460
|
+
const mcpStatus = getMemoryMcpStatus();
|
|
461
|
+
if (mcpStatus.configured && mcpStatus.scope === "local") {
|
|
462
|
+
log.info(`MCP: ${chalk.green("already configured")} in .mcp.json`);
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
console.log();
|
|
466
|
+
log.step("MCP setup");
|
|
467
|
+
log.dim(
|
|
468
|
+
"The Memory MCP connects Claude Code to the memory system so skills can store and search memories."
|
|
469
|
+
);
|
|
470
|
+
const addMcp = await confirm({
|
|
471
|
+
message: "Add coding-friend-memory to .mcp.json?",
|
|
472
|
+
default: true
|
|
473
|
+
});
|
|
474
|
+
if (!addMcp) {
|
|
475
|
+
log.dim('Skipped. Run "cf memory mcp" anytime to get the config.');
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
const serverPath = join(mcpDir, "dist", "index.js");
|
|
479
|
+
if (!existsSync(serverPath)) {
|
|
480
|
+
log.warn(
|
|
481
|
+
"cf-memory not built yet. Run `cf memory mcp` after building to get the config."
|
|
482
|
+
);
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
writeMemoryMcpEntry(serverPath, memoryDir);
|
|
486
|
+
}
|
|
372
487
|
async function memoryInitCommand() {
|
|
373
488
|
const memoryDir = getMemoryDir();
|
|
374
489
|
const mcpDir = getLibPath("cf-memory");
|
|
375
|
-
|
|
490
|
+
ensureMemoryBuilt(mcpDir);
|
|
376
491
|
const dbExists = getDbPath(memoryDir) !== null;
|
|
377
492
|
if (dbExists) {
|
|
378
493
|
console.log();
|
|
@@ -386,12 +501,7 @@ async function memoryInitCommand() {
|
|
|
386
501
|
return;
|
|
387
502
|
}
|
|
388
503
|
console.log();
|
|
389
|
-
|
|
390
|
-
console.log(
|
|
391
|
-
em(" \u2502 ") + "\u{1F9E0}" + em(" ") + chalk.bold.white("Memory Setup") + em(" \u2502")
|
|
392
|
-
);
|
|
393
|
-
console.log(em(" \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F"));
|
|
394
|
-
console.log(em(" \u2570\u2500\u25B8"));
|
|
504
|
+
printBanner("\u{1F9E0} Memory Setup");
|
|
395
505
|
console.log();
|
|
396
506
|
showConfigHint();
|
|
397
507
|
log.step("Step 1/5: Search tier");
|
|
@@ -427,12 +537,14 @@ async function memoryInitCommand() {
|
|
|
427
537
|
const config = loadConfig();
|
|
428
538
|
const tier = config.memory?.tier ?? "auto";
|
|
429
539
|
if (tier === "markdown") {
|
|
540
|
+
await setupMemoryMcp(memoryDir, mcpDir);
|
|
430
541
|
log.success(
|
|
431
542
|
'Memory initialized with Tier 3 (markdown). Run "cf memory status" to verify.'
|
|
432
543
|
);
|
|
433
544
|
return;
|
|
434
545
|
}
|
|
435
546
|
if (tier === "lite") {
|
|
547
|
+
await setupMemoryMcp(memoryDir, mcpDir);
|
|
436
548
|
log.success(
|
|
437
549
|
'Memory initialized. Run "cf memory start-daemon" to enable Tier 2 search.'
|
|
438
550
|
);
|
|
@@ -444,12 +556,14 @@ async function memoryInitCommand() {
|
|
|
444
556
|
log.info(
|
|
445
557
|
"No memory directory found. Memories will be indexed as they're created."
|
|
446
558
|
);
|
|
559
|
+
await setupMemoryMcp(memoryDir, mcpDir);
|
|
447
560
|
log.success('Memory initialized. Run "cf memory status" to verify.');
|
|
448
561
|
return;
|
|
449
562
|
}
|
|
450
563
|
const docCount = countMdFiles(memoryDir);
|
|
451
564
|
if (docCount === 0) {
|
|
452
565
|
log.info("No existing memories to import.");
|
|
566
|
+
await setupMemoryMcp(memoryDir, mcpDir);
|
|
453
567
|
log.success('Memory initialized. Run "cf memory status" to verify.');
|
|
454
568
|
return;
|
|
455
569
|
}
|
|
@@ -470,6 +584,7 @@ async function memoryInitCommand() {
|
|
|
470
584
|
} finally {
|
|
471
585
|
await backend.close();
|
|
472
586
|
}
|
|
587
|
+
await setupMemoryMcp(memoryDir, mcpDir);
|
|
473
588
|
console.log();
|
|
474
589
|
log.success('Memory initialized! Run "cf memory status" to verify.');
|
|
475
590
|
log.info(
|
|
@@ -478,12 +593,7 @@ async function memoryInitCommand() {
|
|
|
478
593
|
}
|
|
479
594
|
async function memoryConfigCommand() {
|
|
480
595
|
console.log();
|
|
481
|
-
|
|
482
|
-
console.log(
|
|
483
|
-
em(" \u2502 ") + "\u{1F9E0}" + em(" ") + chalk.bold.white("Memory Config") + em(" \u2502")
|
|
484
|
-
);
|
|
485
|
-
console.log(em(" \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F"));
|
|
486
|
-
console.log(em(" \u2570\u2500\u25B8"));
|
|
596
|
+
printBanner("\u{1F9E0} Memory Config");
|
|
487
597
|
console.log();
|
|
488
598
|
showConfigHint();
|
|
489
599
|
await memoryConfigMenu({ exitLabel: "Done" });
|
|
@@ -569,7 +679,7 @@ function getProjectInfo(projectDir, projectId, mcpDir, knownSourceDir) {
|
|
|
569
679
|
async function memoryListProjectsCommand() {
|
|
570
680
|
const baseDir = getProjectsBaseDir();
|
|
571
681
|
const mcpDir = getLibPath("cf-memory");
|
|
572
|
-
|
|
682
|
+
ensureMemoryBuilt(mcpDir);
|
|
573
683
|
if (!existsSync(baseDir)) {
|
|
574
684
|
log.info("No memory projects found.");
|
|
575
685
|
log.dim('Run "cf memory init" in a project to create one.');
|
|
@@ -623,7 +733,7 @@ async function memoryRmCommand(opts) {
|
|
|
623
733
|
}
|
|
624
734
|
if (opts.prune) {
|
|
625
735
|
const mcpDir = getLibPath("cf-memory");
|
|
626
|
-
|
|
736
|
+
ensureMemoryBuilt(mcpDir);
|
|
627
737
|
const dirs = readdirSync(baseDir, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith(".")).map((d) => d.name);
|
|
628
738
|
const orphaned = [];
|
|
629
739
|
for (const id of dirs) {
|
|
@@ -740,50 +850,22 @@ async function memoryRmCommand(opts) {
|
|
|
740
850
|
async function memoryMcpCommand() {
|
|
741
851
|
const memoryDir = getMemoryDir();
|
|
742
852
|
const mcpDir = getLibPath("cf-memory");
|
|
743
|
-
|
|
853
|
+
ensureMemoryBuilt(mcpDir);
|
|
744
854
|
const serverPath = join(mcpDir, "dist", "index.js");
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
--- Claude Desktop / Claude Chat (claude_desktop_config.json) ---
|
|
748
|
-
|
|
749
|
-
{
|
|
750
|
-
"mcpServers": {
|
|
751
|
-
"coding-friend-memory": {
|
|
752
|
-
"command": "node",
|
|
753
|
-
"args": ["${serverPath}", "${memoryDir}"]
|
|
754
|
-
}
|
|
755
|
-
}
|
|
855
|
+
printMemoryMcpConfig(serverPath, memoryDir);
|
|
756
856
|
}
|
|
757
857
|
|
|
758
|
-
--- Generic MCP client ---
|
|
759
|
-
|
|
760
|
-
Server command: node ${serverPath} ${memoryDir}
|
|
761
|
-
Transport: stdio
|
|
762
|
-
|
|
763
|
-
--- Available tools ---
|
|
764
|
-
|
|
765
|
-
memory_store Store a new memory
|
|
766
|
-
memory_search Search memories (keyword match)
|
|
767
|
-
memory_retrieve Get a specific memory by ID
|
|
768
|
-
memory_list List memories with filtering
|
|
769
|
-
memory_update Update existing memory
|
|
770
|
-
memory_delete Delete a memory
|
|
771
|
-
|
|
772
|
-
--- Resources ---
|
|
773
|
-
|
|
774
|
-
memory://index Browse all memories
|
|
775
|
-
memory://stats Storage statistics
|
|
776
|
-
`);
|
|
777
|
-
}
|
|
778
858
|
export {
|
|
779
|
-
|
|
780
|
-
|
|
859
|
+
ensureMemoryBuilt,
|
|
860
|
+
printMemoryMcpConfig,
|
|
861
|
+
memoryStatusCommand,
|
|
862
|
+
memorySearchCommand,
|
|
781
863
|
memoryListCommand,
|
|
782
|
-
|
|
864
|
+
memoryStartDaemonCommand,
|
|
865
|
+
memoryStopDaemonCommand,
|
|
783
866
|
memoryRebuildCommand,
|
|
867
|
+
memoryInitCommand,
|
|
868
|
+
memoryConfigCommand,
|
|
784
869
|
memoryRmCommand,
|
|
785
|
-
|
|
786
|
-
memoryStartDaemonCommand,
|
|
787
|
-
memoryStatusCommand,
|
|
788
|
-
memoryStopDaemonCommand
|
|
870
|
+
memoryMcpCommand
|
|
789
871
|
};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
memoryConfigMenu
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-LTHJTWJ6.js";
|
|
4
4
|
import {
|
|
5
5
|
getAllRules,
|
|
6
6
|
getExistingRules
|
|
7
7
|
} from "./chunk-HEBLANJO.js";
|
|
8
8
|
import "./chunk-RZRT7NGT.js";
|
|
9
|
+
import "./chunk-SIQJPT47.js";
|
|
9
10
|
import {
|
|
10
11
|
findStatuslineHookPath,
|
|
11
12
|
isStatuslineConfigured,
|
|
@@ -21,7 +22,7 @@ import {
|
|
|
21
22
|
ensureShellCompletion,
|
|
22
23
|
hasShellCompletion,
|
|
23
24
|
removeShellCompletion
|
|
24
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-DMJCO6LJ.js";
|
|
25
26
|
import {
|
|
26
27
|
BACK,
|
|
27
28
|
applyDocsDirChange,
|
|
@@ -31,7 +32,7 @@ import {
|
|
|
31
32
|
getScopeLabel,
|
|
32
33
|
injectBackChoice,
|
|
33
34
|
showConfigHint
|
|
34
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-O4CNZB5H.js";
|
|
35
36
|
import {
|
|
36
37
|
run
|
|
37
38
|
} from "./chunk-EVGXUDX4.js";
|
|
@@ -47,8 +48,9 @@ import {
|
|
|
47
48
|
resolvePath
|
|
48
49
|
} from "./chunk-DO6FV6BL.js";
|
|
49
50
|
import {
|
|
50
|
-
log
|
|
51
|
-
|
|
51
|
+
log,
|
|
52
|
+
printBanner
|
|
53
|
+
} from "./chunk-NREZK463.js";
|
|
52
54
|
|
|
53
55
|
// src/commands/config.ts
|
|
54
56
|
import { checkbox, confirm, input, select } from "@inquirer/prompts";
|
|
@@ -542,7 +544,7 @@ async function editPermissions() {
|
|
|
542
544
|
)
|
|
543
545
|
});
|
|
544
546
|
if (choice === BACK) return;
|
|
545
|
-
const { permissionCommand } = await import("./permission-
|
|
547
|
+
const { permissionCommand } = await import("./permission-QIJLEMJ6.js");
|
|
546
548
|
switch (choice) {
|
|
547
549
|
case "interactive":
|
|
548
550
|
await permissionCommand({});
|
|
@@ -555,16 +557,9 @@ async function editPermissions() {
|
|
|
555
557
|
break;
|
|
556
558
|
}
|
|
557
559
|
}
|
|
558
|
-
var em = chalk.hex("#10b981");
|
|
559
560
|
async function configCommand() {
|
|
560
561
|
console.log();
|
|
561
|
-
|
|
562
|
-
console.log(
|
|
563
|
-
em(" \u2502 ") + "\u2726" + em(" ") + chalk.bold.white("Coding Friend") + em(" \u2726 \u2502")
|
|
564
|
-
);
|
|
565
|
-
console.log(em(" \u2502 ") + chalk.dim("Config") + em(" \u2502"));
|
|
566
|
-
console.log(em(" \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F"));
|
|
567
|
-
console.log(em(" \u2570\u2500\u25B8"));
|
|
562
|
+
printBanner("\u2728 Coding Friend Config \u2728");
|
|
568
563
|
console.log();
|
|
569
564
|
showConfigHint();
|
|
570
565
|
while (true) {
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import "./chunk-PRIH34UB.js";
|
|
9
9
|
import {
|
|
10
10
|
ensureShellCompletion
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-DMJCO6LJ.js";
|
|
12
12
|
import {
|
|
13
13
|
commandExists,
|
|
14
14
|
run
|
|
@@ -23,8 +23,9 @@ import {
|
|
|
23
23
|
pluginCachePath
|
|
24
24
|
} from "./chunk-DO6FV6BL.js";
|
|
25
25
|
import {
|
|
26
|
-
log
|
|
27
|
-
|
|
26
|
+
log,
|
|
27
|
+
printBanner
|
|
28
|
+
} from "./chunk-NREZK463.js";
|
|
28
29
|
|
|
29
30
|
// src/commands/dev.ts
|
|
30
31
|
import {
|
|
@@ -88,12 +89,12 @@ async function devOnCommand(path) {
|
|
|
88
89
|
return;
|
|
89
90
|
}
|
|
90
91
|
const version = getLocalPluginVersion(localPath);
|
|
91
|
-
const versionLabel = version ? `
|
|
92
|
-
console.log(
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
);
|
|
92
|
+
const versionLabel = version ? ` (v${version})` : "";
|
|
93
|
+
console.log();
|
|
94
|
+
printBanner(`Switching to local dev mode${versionLabel}`, {
|
|
95
|
+
color: chalk.green
|
|
96
|
+
});
|
|
97
|
+
console.log();
|
|
97
98
|
log.info(`Local path: ${chalk.cyan(localPath)}`);
|
|
98
99
|
if (isPluginInstalled()) {
|
|
99
100
|
if (!runClaude(
|
|
@@ -145,11 +146,11 @@ async function devOffCommand() {
|
|
|
145
146
|
return;
|
|
146
147
|
}
|
|
147
148
|
if (!ensureClaude()) return;
|
|
148
|
-
console.log(
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
);
|
|
149
|
+
console.log();
|
|
150
|
+
printBanner("Switching back to remote marketplace", {
|
|
151
|
+
color: chalk.yellow
|
|
152
|
+
});
|
|
153
|
+
console.log();
|
|
153
154
|
if (isPluginInstalled()) {
|
|
154
155
|
if (!runClaude(
|
|
155
156
|
["plugin", "uninstall", PLUGIN_ID],
|
|
@@ -265,10 +266,10 @@ async function devReinstall(path, label) {
|
|
|
265
266
|
if (!ensureClaude()) return;
|
|
266
267
|
const localPath = path ?? state?.localPath;
|
|
267
268
|
const version = localPath ? getLocalPluginVersion(localPath) : null;
|
|
268
|
-
const
|
|
269
|
-
console.log(
|
|
270
|
-
|
|
271
|
-
|
|
269
|
+
const bannerTitle = version ? `${label} (v${version})` : label;
|
|
270
|
+
console.log();
|
|
271
|
+
printBanner(bannerTitle, { color: chalk.cyan });
|
|
272
|
+
console.log();
|
|
272
273
|
if (state) {
|
|
273
274
|
await devOffCommand();
|
|
274
275
|
console.log();
|
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
} from "./chunk-5UEY7HQX.js";
|
|
5
5
|
import {
|
|
6
6
|
resolveScope
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-O4CNZB5H.js";
|
|
8
8
|
import "./chunk-EVGXUDX4.js";
|
|
9
9
|
import "./chunk-5UVDWG5L.js";
|
|
10
10
|
import "./chunk-DO6FV6BL.js";
|
|
11
11
|
import {
|
|
12
12
|
log
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-NREZK463.js";
|
|
14
14
|
|
|
15
15
|
// src/commands/disable.ts
|
|
16
16
|
import chalk from "chalk";
|
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
} from "./chunk-5UEY7HQX.js";
|
|
5
5
|
import {
|
|
6
6
|
resolveScope
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-O4CNZB5H.js";
|
|
8
8
|
import "./chunk-EVGXUDX4.js";
|
|
9
9
|
import "./chunk-5UVDWG5L.js";
|
|
10
10
|
import "./chunk-DO6FV6BL.js";
|
|
11
11
|
import {
|
|
12
12
|
log
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-NREZK463.js";
|
|
14
14
|
|
|
15
15
|
// src/commands/enable.ts
|
|
16
16
|
import chalk from "chalk";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
resolveDocsDir
|
|
3
|
-
} from "./chunk-SIQJPT47.js";
|
|
4
1
|
import {
|
|
5
2
|
getLibPath
|
|
6
3
|
} from "./chunk-RZRT7NGT.js";
|
|
4
|
+
import {
|
|
5
|
+
resolveDocsDir
|
|
6
|
+
} from "./chunk-SIQJPT47.js";
|
|
7
7
|
import "./chunk-PRIH34UB.js";
|
|
8
8
|
import {
|
|
9
9
|
run,
|
|
@@ -12,8 +12,9 @@ import {
|
|
|
12
12
|
import "./chunk-5UVDWG5L.js";
|
|
13
13
|
import "./chunk-DO6FV6BL.js";
|
|
14
14
|
import {
|
|
15
|
-
log
|
|
16
|
-
|
|
15
|
+
log,
|
|
16
|
+
printBanner
|
|
17
|
+
} from "./chunk-NREZK463.js";
|
|
17
18
|
|
|
18
19
|
// src/commands/host.ts
|
|
19
20
|
import { existsSync, readdirSync } from "fs";
|
|
@@ -50,7 +51,7 @@ async function hostCommand(path, opts) {
|
|
|
50
51
|
process.exit(1);
|
|
51
52
|
}
|
|
52
53
|
const catCount = countCategories(docsDir);
|
|
53
|
-
|
|
54
|
+
printBanner("\u2728 Coding Friend Host \u2728");
|
|
54
55
|
log.info(`Docs folder: ${docsDir}`);
|
|
55
56
|
log.info(`Found: ${docCount} docs in ${catCount} categories`);
|
|
56
57
|
console.log();
|