coding-friend-cli 1.16.0 → 1.17.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/README.md +12 -0
- package/dist/{chunk-D4EWPGBL.js → chunk-C5LYVVEI.js} +1 -1
- package/dist/{chunk-X5WEODUD.js → chunk-CYQU33FY.js} +1 -0
- package/dist/{chunk-QNLL3ZDF.js → chunk-G6CEEMAR.js} +3 -3
- package/dist/{chunk-4DB4XTSL.js → chunk-KTX4MGMR.js} +15 -1
- package/dist/{chunk-KJUGTLPQ.js → chunk-YO6JKGR3.js} +38 -2
- package/dist/{config-AIZJJ5D2.js → config-LZFXXOI4.js} +276 -14
- package/dist/{dev-WJ5QQ35B.js → dev-R3IYWZ3M.js} +2 -2
- package/dist/{disable-JDVOQNZG.js → disable-R6K5YJN4.js} +2 -2
- package/dist/{enable-JBJ4Q2S7.js → enable-HF4PYVJN.js} +2 -2
- package/dist/{host-NA7LZ4HX.js → host-SYZH3FVC.js} +4 -4
- package/dist/index.js +78 -18
- package/dist/{init-FZ3GG53E.js → init-YK6YRTOT.js} +102 -6
- package/dist/{install-I3GOS56Q.js → install-Q4PWEU43.js} +4 -4
- package/dist/{mcp-DLS3J6QJ.js → mcp-TBEDYELW.js} +4 -4
- package/dist/memory-7RM67ZLS.js +668 -0
- package/dist/postinstall.js +1 -1
- package/dist/{session-E3CZJJZQ.js → session-H4XW2WXH.js} +1 -1
- package/dist/{statusline-6HQCDWBD.js → statusline-6Y2EBAFQ.js} +1 -1
- package/dist/{uninstall-JN5YIKKM.js → uninstall-3PSUDGI4.js} +3 -3
- package/dist/{update-OWS4IJTG.js → update-WL6SFGGO.js} +4 -4
- package/lib/cf-memory/CHANGELOG.md +15 -0
- package/lib/cf-memory/README.md +284 -0
- package/lib/cf-memory/package-lock.json +2790 -0
- package/lib/cf-memory/package.json +31 -0
- package/lib/cf-memory/scripts/migrate-frontmatter.ts +134 -0
- package/lib/cf-memory/src/__tests__/daemon-e2e.test.ts +223 -0
- package/lib/cf-memory/src/__tests__/daemon.test.ts +407 -0
- package/lib/cf-memory/src/__tests__/dedup.test.ts +103 -0
- package/lib/cf-memory/src/__tests__/embeddings.test.ts +292 -0
- package/lib/cf-memory/src/__tests__/lazy-install.test.ts +210 -0
- package/lib/cf-memory/src/__tests__/markdown-backend.test.ts +410 -0
- package/lib/cf-memory/src/__tests__/migration.test.ts +255 -0
- package/lib/cf-memory/src/__tests__/migrations.test.ts +288 -0
- package/lib/cf-memory/src/__tests__/minisearch-backend.test.ts +262 -0
- package/lib/cf-memory/src/__tests__/ollama.test.ts +48 -0
- package/lib/cf-memory/src/__tests__/schema.test.ts +128 -0
- package/lib/cf-memory/src/__tests__/search.test.ts +115 -0
- package/lib/cf-memory/src/__tests__/temporal-decay.test.ts +54 -0
- package/lib/cf-memory/src/__tests__/tier.test.ts +293 -0
- package/lib/cf-memory/src/__tests__/tools.test.ts +83 -0
- package/lib/cf-memory/src/backends/markdown.ts +318 -0
- package/lib/cf-memory/src/backends/minisearch.ts +203 -0
- package/lib/cf-memory/src/backends/sqlite/embeddings.ts +286 -0
- package/lib/cf-memory/src/backends/sqlite/index.ts +549 -0
- package/lib/cf-memory/src/backends/sqlite/migrations.ts +188 -0
- package/lib/cf-memory/src/backends/sqlite/schema.ts +120 -0
- package/lib/cf-memory/src/backends/sqlite/search.ts +296 -0
- package/lib/cf-memory/src/bin/cf-memory.ts +2 -0
- package/lib/cf-memory/src/daemon/entry.ts +99 -0
- package/lib/cf-memory/src/daemon/process.ts +220 -0
- package/lib/cf-memory/src/daemon/server.ts +166 -0
- package/lib/cf-memory/src/daemon/watcher.ts +90 -0
- package/lib/cf-memory/src/index.ts +45 -0
- package/lib/cf-memory/src/lib/backend.ts +23 -0
- package/lib/cf-memory/src/lib/daemon-client.ts +163 -0
- package/lib/cf-memory/src/lib/dedup.ts +80 -0
- package/lib/cf-memory/src/lib/lazy-install.ts +274 -0
- package/lib/cf-memory/src/lib/ollama.ts +76 -0
- package/lib/cf-memory/src/lib/temporal-decay.ts +19 -0
- package/lib/cf-memory/src/lib/tier.ts +107 -0
- package/lib/cf-memory/src/lib/types.ts +109 -0
- package/lib/cf-memory/src/resources/index.ts +62 -0
- package/lib/cf-memory/src/server.ts +20 -0
- package/lib/cf-memory/src/tools/delete.ts +38 -0
- package/lib/cf-memory/src/tools/list.ts +38 -0
- package/lib/cf-memory/src/tools/retrieve.ts +52 -0
- package/lib/cf-memory/src/tools/search.ts +47 -0
- package/lib/cf-memory/src/tools/store.ts +70 -0
- package/lib/cf-memory/src/tools/update.ts +62 -0
- package/lib/cf-memory/tsconfig.json +15 -0
- package/lib/cf-memory/vitest.config.ts +7 -0
- package/lib/learn-host/CHANGELOG.md +4 -0
- package/lib/learn-host/package.json +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { MemoryBackend } from "../lib/backend.js";
|
|
3
|
+
|
|
4
|
+
export function registerAllResources(
|
|
5
|
+
server: McpServer,
|
|
6
|
+
backend: MemoryBackend,
|
|
7
|
+
): void {
|
|
8
|
+
// memory://index — browse all memories
|
|
9
|
+
server.registerResource(
|
|
10
|
+
"memory-index",
|
|
11
|
+
"memory://index",
|
|
12
|
+
{
|
|
13
|
+
title: "Memory Index",
|
|
14
|
+
description: "Browse all stored memories with titles, types, and tags",
|
|
15
|
+
mimeType: "application/json",
|
|
16
|
+
},
|
|
17
|
+
async (uri) => {
|
|
18
|
+
const metas = await backend.list({});
|
|
19
|
+
return {
|
|
20
|
+
contents: [
|
|
21
|
+
{
|
|
22
|
+
uri: uri.href,
|
|
23
|
+
text: JSON.stringify(
|
|
24
|
+
metas.map((m) => ({
|
|
25
|
+
id: m.id,
|
|
26
|
+
title: m.frontmatter.title,
|
|
27
|
+
description: m.frontmatter.description,
|
|
28
|
+
type: m.frontmatter.type,
|
|
29
|
+
tags: m.frontmatter.tags,
|
|
30
|
+
updated: m.frontmatter.updated,
|
|
31
|
+
})),
|
|
32
|
+
null,
|
|
33
|
+
2,
|
|
34
|
+
),
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
// memory://stats — storage statistics
|
|
42
|
+
server.registerResource(
|
|
43
|
+
"memory-stats",
|
|
44
|
+
"memory://stats",
|
|
45
|
+
{
|
|
46
|
+
title: "Memory Stats",
|
|
47
|
+
description: "Storage statistics: total count, by category, by type",
|
|
48
|
+
mimeType: "application/json",
|
|
49
|
+
},
|
|
50
|
+
async (uri) => {
|
|
51
|
+
const stats = await backend.stats();
|
|
52
|
+
return {
|
|
53
|
+
contents: [
|
|
54
|
+
{
|
|
55
|
+
uri: uri.href,
|
|
56
|
+
text: JSON.stringify(stats, null, 2),
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
);
|
|
62
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { MemoryBackend } from "./lib/backend.js";
|
|
3
|
+
import { registerStore } from "./tools/store.js";
|
|
4
|
+
import { registerSearch } from "./tools/search.js";
|
|
5
|
+
import { registerRetrieve } from "./tools/retrieve.js";
|
|
6
|
+
import { registerList } from "./tools/list.js";
|
|
7
|
+
import { registerUpdate } from "./tools/update.js";
|
|
8
|
+
import { registerDelete } from "./tools/delete.js";
|
|
9
|
+
|
|
10
|
+
export function registerAllTools(
|
|
11
|
+
server: McpServer,
|
|
12
|
+
backend: MemoryBackend,
|
|
13
|
+
): void {
|
|
14
|
+
registerStore(server, backend);
|
|
15
|
+
registerSearch(server, backend);
|
|
16
|
+
registerRetrieve(server, backend);
|
|
17
|
+
registerList(server, backend);
|
|
18
|
+
registerUpdate(server, backend);
|
|
19
|
+
registerDelete(server, backend);
|
|
20
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { MemoryBackend } from "../lib/backend.js";
|
|
4
|
+
|
|
5
|
+
export function registerDelete(
|
|
6
|
+
server: McpServer,
|
|
7
|
+
backend: MemoryBackend,
|
|
8
|
+
): void {
|
|
9
|
+
server.tool(
|
|
10
|
+
"memory_delete",
|
|
11
|
+
"Delete a memory by ID.",
|
|
12
|
+
{
|
|
13
|
+
id: z.string().describe("Memory ID (e.g. features/auth-pattern)"),
|
|
14
|
+
},
|
|
15
|
+
async ({ id }) => {
|
|
16
|
+
const deleted = await backend.delete(id);
|
|
17
|
+
if (!deleted) {
|
|
18
|
+
return {
|
|
19
|
+
content: [
|
|
20
|
+
{
|
|
21
|
+
type: "text" as const,
|
|
22
|
+
text: JSON.stringify({ error: "Memory not found", id }),
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
isError: true,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
content: [
|
|
30
|
+
{
|
|
31
|
+
type: "text" as const,
|
|
32
|
+
text: JSON.stringify({ id, deleted: true }, null, 2),
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
);
|
|
38
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { MemoryBackend } from "../lib/backend.js";
|
|
4
|
+
import { MEMORY_TYPES } from "../lib/types.js";
|
|
5
|
+
|
|
6
|
+
export function registerList(server: McpServer, backend: MemoryBackend): void {
|
|
7
|
+
server.tool(
|
|
8
|
+
"memory_list",
|
|
9
|
+
"List memories with optional filtering by type or category.",
|
|
10
|
+
{
|
|
11
|
+
type: z.enum(MEMORY_TYPES).optional().describe("Filter by memory type"),
|
|
12
|
+
category: z.string().optional().describe("Filter by category folder"),
|
|
13
|
+
limit: z.number().optional().describe("Max results, default 50"),
|
|
14
|
+
},
|
|
15
|
+
async ({ type, category, limit }) => {
|
|
16
|
+
const metas = await backend.list({ type, category, limit });
|
|
17
|
+
return {
|
|
18
|
+
content: [
|
|
19
|
+
{
|
|
20
|
+
type: "text" as const,
|
|
21
|
+
text: JSON.stringify(
|
|
22
|
+
metas.map((m) => ({
|
|
23
|
+
id: m.id,
|
|
24
|
+
title: m.frontmatter.title,
|
|
25
|
+
description: m.frontmatter.description,
|
|
26
|
+
type: m.frontmatter.type,
|
|
27
|
+
tags: m.frontmatter.tags,
|
|
28
|
+
updated: m.frontmatter.updated,
|
|
29
|
+
})),
|
|
30
|
+
null,
|
|
31
|
+
2,
|
|
32
|
+
),
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
);
|
|
38
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { MemoryBackend } from "../lib/backend.js";
|
|
4
|
+
|
|
5
|
+
export function registerRetrieve(
|
|
6
|
+
server: McpServer,
|
|
7
|
+
backend: MemoryBackend,
|
|
8
|
+
): void {
|
|
9
|
+
server.tool(
|
|
10
|
+
"memory_retrieve",
|
|
11
|
+
"Retrieve a specific memory by ID (format: category/slug).",
|
|
12
|
+
{
|
|
13
|
+
id: z.string().describe("Memory ID (e.g. features/auth-pattern)"),
|
|
14
|
+
},
|
|
15
|
+
async ({ id }) => {
|
|
16
|
+
const memory = await backend.retrieve(id);
|
|
17
|
+
if (!memory) {
|
|
18
|
+
return {
|
|
19
|
+
content: [
|
|
20
|
+
{
|
|
21
|
+
type: "text" as const,
|
|
22
|
+
text: JSON.stringify({ error: "Memory not found", id }),
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
isError: true,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
content: [
|
|
30
|
+
{
|
|
31
|
+
type: "text" as const,
|
|
32
|
+
text: JSON.stringify(
|
|
33
|
+
{
|
|
34
|
+
id: memory.id,
|
|
35
|
+
title: memory.frontmatter.title,
|
|
36
|
+
description: memory.frontmatter.description,
|
|
37
|
+
type: memory.frontmatter.type,
|
|
38
|
+
tags: memory.frontmatter.tags,
|
|
39
|
+
importance: memory.frontmatter.importance,
|
|
40
|
+
created: memory.frontmatter.created,
|
|
41
|
+
updated: memory.frontmatter.updated,
|
|
42
|
+
content: memory.content,
|
|
43
|
+
},
|
|
44
|
+
null,
|
|
45
|
+
2,
|
|
46
|
+
),
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { MemoryBackend } from "../lib/backend.js";
|
|
4
|
+
import { MEMORY_TYPES } from "../lib/types.js";
|
|
5
|
+
|
|
6
|
+
export function registerSearch(
|
|
7
|
+
server: McpServer,
|
|
8
|
+
backend: MemoryBackend,
|
|
9
|
+
): void {
|
|
10
|
+
server.tool(
|
|
11
|
+
"memory_search",
|
|
12
|
+
"Search memories by query. Returns ranked results matching title, description, tags, or content.",
|
|
13
|
+
{
|
|
14
|
+
query: z.string().describe("Search query"),
|
|
15
|
+
type: z.enum(MEMORY_TYPES).optional().describe("Filter by memory type"),
|
|
16
|
+
tags: z
|
|
17
|
+
.array(z.string())
|
|
18
|
+
.optional()
|
|
19
|
+
.describe("Filter by tags (OR match)"),
|
|
20
|
+
limit: z.number().optional().describe("Max results, default 10"),
|
|
21
|
+
},
|
|
22
|
+
async ({ query, type, tags, limit }) => {
|
|
23
|
+
const results = await backend.search({ query, type, tags, limit });
|
|
24
|
+
return {
|
|
25
|
+
content: [
|
|
26
|
+
{
|
|
27
|
+
type: "text" as const,
|
|
28
|
+
text: JSON.stringify(
|
|
29
|
+
results.map((r) => ({
|
|
30
|
+
id: r.memory.id,
|
|
31
|
+
title: r.memory.frontmatter.title,
|
|
32
|
+
description: r.memory.frontmatter.description,
|
|
33
|
+
type: r.memory.frontmatter.type,
|
|
34
|
+
tags: r.memory.frontmatter.tags,
|
|
35
|
+
score: r.score,
|
|
36
|
+
matchedOn: r.matchedOn,
|
|
37
|
+
excerpt: r.memory.excerpt,
|
|
38
|
+
})),
|
|
39
|
+
null,
|
|
40
|
+
2,
|
|
41
|
+
),
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
);
|
|
47
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { MemoryBackend } from "../lib/backend.js";
|
|
4
|
+
import { MEMORY_TYPES } from "../lib/types.js";
|
|
5
|
+
import { checkDuplicate } from "../lib/dedup.js";
|
|
6
|
+
|
|
7
|
+
export function registerStore(server: McpServer, backend: MemoryBackend): void {
|
|
8
|
+
server.tool(
|
|
9
|
+
"memory_store",
|
|
10
|
+
"Store a new memory. Provide title, description, type, tags, and content.",
|
|
11
|
+
{
|
|
12
|
+
title: z.string().describe("Memory title"),
|
|
13
|
+
description: z
|
|
14
|
+
.string()
|
|
15
|
+
.describe("One-line searchable summary, under 100 chars"),
|
|
16
|
+
type: z.enum(MEMORY_TYPES).describe("Memory type"),
|
|
17
|
+
tags: z.array(z.string()).describe("3-5 keyword tags"),
|
|
18
|
+
content: z.string().describe("Markdown content (without frontmatter)"),
|
|
19
|
+
importance: z
|
|
20
|
+
.number()
|
|
21
|
+
.min(1)
|
|
22
|
+
.max(5)
|
|
23
|
+
.optional()
|
|
24
|
+
.describe("Importance 1-5, default 3"),
|
|
25
|
+
source: z
|
|
26
|
+
.string()
|
|
27
|
+
.optional()
|
|
28
|
+
.describe("Source: conversation, auto-capture, manual"),
|
|
29
|
+
},
|
|
30
|
+
async ({ title, description, type, tags, content, importance, source }) => {
|
|
31
|
+
const input = {
|
|
32
|
+
title,
|
|
33
|
+
description,
|
|
34
|
+
type,
|
|
35
|
+
tags,
|
|
36
|
+
content,
|
|
37
|
+
importance,
|
|
38
|
+
source,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
let dedup: Awaited<ReturnType<typeof checkDuplicate>> | null = null;
|
|
42
|
+
try {
|
|
43
|
+
dedup = await checkDuplicate(backend, input);
|
|
44
|
+
} catch {
|
|
45
|
+
// Dedup is best-effort — don't block store on search errors
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const memory = await backend.store(input);
|
|
49
|
+
|
|
50
|
+
const response: Record<string, unknown> = {
|
|
51
|
+
id: memory.id,
|
|
52
|
+
title: memory.frontmatter.title,
|
|
53
|
+
stored: true,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
if (dedup?.isDuplicate) {
|
|
57
|
+
response.warning = `Near-duplicate found: ${dedup.similarId} (similarity: ${dedup.similarity.toFixed(2)}). Memory stored anyway.`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
content: [
|
|
62
|
+
{
|
|
63
|
+
type: "text" as const,
|
|
64
|
+
text: JSON.stringify(response, null, 2),
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
);
|
|
70
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { MemoryBackend } from "../lib/backend.js";
|
|
4
|
+
|
|
5
|
+
export function registerUpdate(
|
|
6
|
+
server: McpServer,
|
|
7
|
+
backend: MemoryBackend,
|
|
8
|
+
): void {
|
|
9
|
+
server.tool(
|
|
10
|
+
"memory_update",
|
|
11
|
+
"Update an existing memory. Provide the ID and fields to update. Content is appended.",
|
|
12
|
+
{
|
|
13
|
+
id: z.string().describe("Memory ID (e.g. features/auth-pattern)"),
|
|
14
|
+
title: z.string().optional().describe("New title"),
|
|
15
|
+
description: z.string().optional().describe("New description"),
|
|
16
|
+
tags: z
|
|
17
|
+
.array(z.string())
|
|
18
|
+
.optional()
|
|
19
|
+
.describe("Tags to add (merged with existing)"),
|
|
20
|
+
content: z.string().optional().describe("Content to append to existing"),
|
|
21
|
+
importance: z
|
|
22
|
+
.number()
|
|
23
|
+
.min(1)
|
|
24
|
+
.max(5)
|
|
25
|
+
.optional()
|
|
26
|
+
.describe("New importance"),
|
|
27
|
+
},
|
|
28
|
+
async ({ id, title, description, tags, content, importance }) => {
|
|
29
|
+
const memory = await backend.update({
|
|
30
|
+
id,
|
|
31
|
+
title,
|
|
32
|
+
description,
|
|
33
|
+
tags,
|
|
34
|
+
content,
|
|
35
|
+
importance,
|
|
36
|
+
});
|
|
37
|
+
if (!memory) {
|
|
38
|
+
return {
|
|
39
|
+
content: [
|
|
40
|
+
{
|
|
41
|
+
type: "text" as const,
|
|
42
|
+
text: JSON.stringify({ error: "Memory not found", id }),
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
isError: true,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
content: [
|
|
50
|
+
{
|
|
51
|
+
type: "text" as const,
|
|
52
|
+
text: JSON.stringify(
|
|
53
|
+
{ id: memory.id, title: memory.frontmatter.title, updated: true },
|
|
54
|
+
null,
|
|
55
|
+
2,
|
|
56
|
+
),
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
);
|
|
62
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"outDir": "dist",
|
|
7
|
+
"rootDir": "src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"declaration": true
|
|
12
|
+
},
|
|
13
|
+
"include": ["src"],
|
|
14
|
+
"exclude": ["node_modules", "dist"]
|
|
15
|
+
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog (Learn Host)
|
|
2
2
|
|
|
3
|
+
## v0.2.2 (2026-03-16)
|
|
4
|
+
|
|
5
|
+
- Improve `cf init` to be more interactive with step-by-step guided setup ([#d5bbc9c](https://github.com/dinhanhthi/coding-friend/commit/d5bbc9c))
|
|
6
|
+
|
|
3
7
|
## v0.2.1 (2026-03-05)
|
|
4
8
|
|
|
5
9
|
- Fix TOC heading text stripping markdown links from slug generation ([#9a8fb5c](https://github.com/dinhanhthi/coding-friend/commit/9a8fb5c))
|