mnotes-cli 1.9.0 → 1.9.2
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/client.d.ts +20 -0
- package/dist/client.js +8 -0
- package/dist/commands/connect/__tests__/wizard.test.js +24 -23
- package/dist/commands/connect/wizard.js +2 -1
- package/dist/commands/recall-knowledge.js +38 -13
- package/dist/output.d.ts +11 -0
- package/dist/output.js +23 -0
- package/dist/templates/claude-code/skills.d.ts +7 -3
- package/dist/templates/claude-code/skills.js +9 -8
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -72,6 +72,26 @@ export declare function createClient(baseUrl: string, apiKey: string): {
|
|
|
72
72
|
isDefault: boolean;
|
|
73
73
|
}>;
|
|
74
74
|
}>;
|
|
75
|
+
recallKnowledge(opts: {
|
|
76
|
+
query: string;
|
|
77
|
+
workspaceId?: string;
|
|
78
|
+
tags?: string[];
|
|
79
|
+
limit?: number;
|
|
80
|
+
}): Promise<{
|
|
81
|
+
data: {
|
|
82
|
+
results: Array<{
|
|
83
|
+
id: string;
|
|
84
|
+
title: string;
|
|
85
|
+
key: string | null;
|
|
86
|
+
excerpt: string;
|
|
87
|
+
importance: number | null;
|
|
88
|
+
tags: string[];
|
|
89
|
+
semanticScore: number;
|
|
90
|
+
freshnessScore: number;
|
|
91
|
+
finalScore: number;
|
|
92
|
+
}>;
|
|
93
|
+
};
|
|
94
|
+
}>;
|
|
75
95
|
queryGraph(opts?: {
|
|
76
96
|
workspaceId?: string;
|
|
77
97
|
query?: string;
|
package/dist/client.js
CHANGED
|
@@ -51,6 +51,14 @@ function createClient(baseUrl, apiKey) {
|
|
|
51
51
|
async listWorkspaces() {
|
|
52
52
|
return request("GET", "/api/v1/workspaces");
|
|
53
53
|
},
|
|
54
|
+
async recallKnowledge(opts) {
|
|
55
|
+
return request("POST", "/api/v1/knowledge/recall", {
|
|
56
|
+
query: opts.query,
|
|
57
|
+
workspaceId: opts.workspaceId,
|
|
58
|
+
tags: opts.tags,
|
|
59
|
+
limit: opts.limit,
|
|
60
|
+
});
|
|
61
|
+
},
|
|
54
62
|
async queryGraph(opts) {
|
|
55
63
|
const params = new URLSearchParams();
|
|
56
64
|
if (opts?.workspaceId)
|
|
@@ -79,11 +79,11 @@ const DEFAULT_OPTS = {
|
|
|
79
79
|
const skills = (0, skills_1.generateSkillTemplates)(DEFAULT_OPTS);
|
|
80
80
|
(0, vitest_1.expect)(skills).toHaveLength(2);
|
|
81
81
|
});
|
|
82
|
-
(0, vitest_1.it)("generates store and recall skills", () => {
|
|
82
|
+
(0, vitest_1.it)("generates store and recall skills as SKILL.md inside their own folder (AC-1)", () => {
|
|
83
83
|
const skills = (0, skills_1.generateSkillTemplates)(DEFAULT_OPTS);
|
|
84
|
-
const
|
|
85
|
-
(0, vitest_1.expect)(
|
|
86
|
-
(0, vitest_1.expect)(
|
|
84
|
+
const paths = skills.map((s) => s.path);
|
|
85
|
+
(0, vitest_1.expect)(paths).toContain("mnotes-store/SKILL.md");
|
|
86
|
+
(0, vitest_1.expect)(paths).toContain("mnotes-recall/SKILL.md");
|
|
87
87
|
});
|
|
88
88
|
(0, vitest_1.it)("includes m-notes generated header (AC-8)", () => {
|
|
89
89
|
const skills = (0, skills_1.generateSkillTemplates)(DEFAULT_OPTS);
|
|
@@ -97,12 +97,13 @@ const DEFAULT_OPTS = {
|
|
|
97
97
|
(0, vitest_1.expect)(skill.content).toContain("ws-test-123");
|
|
98
98
|
}
|
|
99
99
|
});
|
|
100
|
-
(0, vitest_1.it)("includes frontmatter with name and
|
|
100
|
+
(0, vitest_1.it)("includes frontmatter with name and description and omits non-standard fields", () => {
|
|
101
101
|
const skills = (0, skills_1.generateSkillTemplates)(DEFAULT_OPTS);
|
|
102
102
|
for (const skill of skills) {
|
|
103
103
|
(0, vitest_1.expect)(skill.content).toContain("---");
|
|
104
104
|
(0, vitest_1.expect)(skill.content).toContain("name:");
|
|
105
|
-
(0, vitest_1.expect)(skill.content).toContain("
|
|
105
|
+
(0, vitest_1.expect)(skill.content).toContain("description:");
|
|
106
|
+
(0, vitest_1.expect)(skill.content).not.toMatch(/^trigger:/m);
|
|
106
107
|
}
|
|
107
108
|
});
|
|
108
109
|
});
|
|
@@ -211,38 +212,38 @@ const DEFAULT_OPTS = {
|
|
|
211
212
|
(0, vitest_1.afterEach)(() => {
|
|
212
213
|
cleanTmpDir(tmpDir);
|
|
213
214
|
});
|
|
214
|
-
(0, vitest_1.it)("creates skill files
|
|
215
|
+
(0, vitest_1.it)("creates skill files as .claude/skills/<name>/SKILL.md (AC-4)", () => {
|
|
215
216
|
const results = (0, wizard_1.scaffoldItems)(tmpDir, ["skills"], DEFAULT_OPTS);
|
|
216
217
|
(0, vitest_1.expect)(results).toHaveLength(1);
|
|
217
218
|
(0, vitest_1.expect)(results[0].item).toBe("skills");
|
|
218
219
|
(0, vitest_1.expect)(results[0].filesWritten.length).toBeGreaterThan(0);
|
|
219
220
|
const skillsDir = path.join(tmpDir, ".claude", "skills");
|
|
220
|
-
(0, vitest_1.expect)(fs.existsSync(path.join(skillsDir, "mnotes-store.md"))).toBe(true);
|
|
221
|
-
(0, vitest_1.expect)(fs.existsSync(path.join(skillsDir, "mnotes-recall.md"))).toBe(true);
|
|
221
|
+
(0, vitest_1.expect)(fs.existsSync(path.join(skillsDir, "mnotes-store", "SKILL.md"))).toBe(true);
|
|
222
|
+
(0, vitest_1.expect)(fs.existsSync(path.join(skillsDir, "mnotes-recall", "SKILL.md"))).toBe(true);
|
|
222
223
|
});
|
|
223
224
|
(0, vitest_1.it)("generated skill files include header (AC-8)", () => {
|
|
224
225
|
(0, wizard_1.scaffoldItems)(tmpDir, ["skills"], DEFAULT_OPTS);
|
|
225
|
-
const storeContent = fs.readFileSync(path.join(tmpDir, ".claude", "skills", "mnotes-store.md"), "utf-8");
|
|
226
|
+
const storeContent = fs.readFileSync(path.join(tmpDir, ".claude", "skills", "mnotes-store", "SKILL.md"), "utf-8");
|
|
226
227
|
(0, vitest_1.expect)(storeContent).toContain("Generated by m-notes CLI");
|
|
227
228
|
});
|
|
228
229
|
(0, vitest_1.it)("preserves user-created skill files (AC-5)", () => {
|
|
229
|
-
const
|
|
230
|
-
fs.mkdirSync(
|
|
231
|
-
// Write a user-created file
|
|
232
|
-
fs.writeFileSync(path.join(
|
|
233
|
-
|
|
230
|
+
const storeDir = path.join(tmpDir, ".claude", "skills", "mnotes-store");
|
|
231
|
+
fs.mkdirSync(storeDir, { recursive: true });
|
|
232
|
+
// Write a user-created file at the same path
|
|
233
|
+
fs.writeFileSync(path.join(storeDir, "SKILL.md"), "# My custom store skill\nCustom content here", "utf-8");
|
|
234
|
+
(0, wizard_1.scaffoldItems)(tmpDir, ["skills"], DEFAULT_OPTS);
|
|
234
235
|
// The user file should be preserved
|
|
235
|
-
const content = fs.readFileSync(path.join(
|
|
236
|
+
const content = fs.readFileSync(path.join(storeDir, "SKILL.md"), "utf-8");
|
|
236
237
|
(0, vitest_1.expect)(content).toContain("My custom store skill");
|
|
237
238
|
(0, vitest_1.expect)(content).not.toContain("Generated by m-notes CLI");
|
|
238
239
|
// The recall skill should still be written (new file)
|
|
239
|
-
(0, vitest_1.expect)(fs.existsSync(path.join(
|
|
240
|
+
(0, vitest_1.expect)(fs.existsSync(path.join(tmpDir, ".claude", "skills", "mnotes-recall", "SKILL.md"))).toBe(true);
|
|
240
241
|
});
|
|
241
242
|
(0, vitest_1.it)("overwrites m-notes generated skill files on re-run (AC-5)", () => {
|
|
242
243
|
(0, wizard_1.scaffoldItems)(tmpDir, ["skills"], DEFAULT_OPTS);
|
|
243
244
|
// Re-run with different workspaceId
|
|
244
245
|
(0, wizard_1.scaffoldItems)(tmpDir, ["skills"], { url: "http://new-url.com", workspaceId: "ws-new" });
|
|
245
|
-
const content = fs.readFileSync(path.join(tmpDir, ".claude", "skills", "mnotes-store.md"), "utf-8");
|
|
246
|
+
const content = fs.readFileSync(path.join(tmpDir, ".claude", "skills", "mnotes-store", "SKILL.md"), "utf-8");
|
|
246
247
|
(0, vitest_1.expect)(content).toContain("ws-new");
|
|
247
248
|
});
|
|
248
249
|
});
|
|
@@ -298,8 +299,8 @@ const DEFAULT_OPTS = {
|
|
|
298
299
|
(0, vitest_1.expect)(items).toContain("agents");
|
|
299
300
|
// Verify files exist
|
|
300
301
|
(0, vitest_1.expect)(fs.existsSync(path.join(tmpDir, ".claude", "settings.json"))).toBe(true);
|
|
301
|
-
(0, vitest_1.expect)(fs.existsSync(path.join(tmpDir, ".claude", "skills", "mnotes-store.md"))).toBe(true);
|
|
302
|
-
(0, vitest_1.expect)(fs.existsSync(path.join(tmpDir, ".claude", "skills", "mnotes-recall.md"))).toBe(true);
|
|
302
|
+
(0, vitest_1.expect)(fs.existsSync(path.join(tmpDir, ".claude", "skills", "mnotes-store", "SKILL.md"))).toBe(true);
|
|
303
|
+
(0, vitest_1.expect)(fs.existsSync(path.join(tmpDir, ".claude", "skills", "mnotes-recall", "SKILL.md"))).toBe(true);
|
|
303
304
|
(0, vitest_1.expect)(fs.existsSync(path.join(tmpDir, ".claude", "agents", "knowledge-manager.md"))).toBe(true);
|
|
304
305
|
});
|
|
305
306
|
(0, vitest_1.it)("scaffolds partial selection", () => {
|
|
@@ -386,8 +387,8 @@ const DEFAULT_OPTS = {
|
|
|
386
387
|
(0, vitest_1.expect)(fs.existsSync(path.join(tmpDir, "CLAUDE.md"))).toBe(true);
|
|
387
388
|
// All extras should exist
|
|
388
389
|
(0, vitest_1.expect)(fs.existsSync(path.join(tmpDir, ".claude", "settings.json"))).toBe(true);
|
|
389
|
-
(0, vitest_1.expect)(fs.existsSync(path.join(tmpDir, ".claude", "skills", "mnotes-store.md"))).toBe(true);
|
|
390
|
-
(0, vitest_1.expect)(fs.existsSync(path.join(tmpDir, ".claude", "skills", "mnotes-recall.md"))).toBe(true);
|
|
390
|
+
(0, vitest_1.expect)(fs.existsSync(path.join(tmpDir, ".claude", "skills", "mnotes-store", "SKILL.md"))).toBe(true);
|
|
391
|
+
(0, vitest_1.expect)(fs.existsSync(path.join(tmpDir, ".claude", "skills", "mnotes-recall", "SKILL.md"))).toBe(true);
|
|
391
392
|
(0, vitest_1.expect)(fs.existsSync(path.join(tmpDir, ".claude", "agents", "knowledge-manager.md"))).toBe(true);
|
|
392
393
|
// Output should mention extras
|
|
393
394
|
(0, vitest_1.expect)(output).toContain("Extras installed:");
|
|
@@ -465,7 +466,7 @@ const DEFAULT_OPTS = {
|
|
|
465
466
|
}
|
|
466
467
|
// All extras should exist
|
|
467
468
|
(0, vitest_1.expect)(fs.existsSync(path.join(tmpDir, ".claude", "settings.json"))).toBe(true);
|
|
468
|
-
(0, vitest_1.expect)(fs.existsSync(path.join(tmpDir, ".claude", "skills", "mnotes-store.md"))).toBe(true);
|
|
469
|
+
(0, vitest_1.expect)(fs.existsSync(path.join(tmpDir, ".claude", "skills", "mnotes-store", "SKILL.md"))).toBe(true);
|
|
469
470
|
(0, vitest_1.expect)(fs.existsSync(path.join(tmpDir, ".claude", "agents", "knowledge-manager.md"))).toBe(true);
|
|
470
471
|
});
|
|
471
472
|
});
|
|
@@ -170,8 +170,9 @@ function scaffoldSkills(dir, opts) {
|
|
|
170
170
|
const skills = (0, index_1.generateSkillTemplates)(opts);
|
|
171
171
|
const filesWritten = [];
|
|
172
172
|
for (const skill of skills) {
|
|
173
|
-
const filePath = path.join(skillsDir, skill.
|
|
173
|
+
const filePath = path.join(skillsDir, skill.path);
|
|
174
174
|
if (shouldWriteGeneratedFile(filePath)) {
|
|
175
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
175
176
|
fs.writeFileSync(filePath, skill.content, "utf-8");
|
|
176
177
|
filesWritten.push(filePath);
|
|
177
178
|
}
|
|
@@ -7,30 +7,55 @@ const output_1 = require("../output");
|
|
|
7
7
|
function registerRecallKnowledgeCommand(program) {
|
|
8
8
|
program
|
|
9
9
|
.command("recall_knowledge")
|
|
10
|
-
.description("Query
|
|
11
|
-
.option("--query <text>", "
|
|
12
|
-
.option("--
|
|
13
|
-
.option("--
|
|
14
|
-
.option("--
|
|
15
|
-
.option("--
|
|
10
|
+
.description("Query knowledge entries via semantic search (read-only)")
|
|
11
|
+
.option("--query <text>", "Search query (required for semantic recall)")
|
|
12
|
+
.option("--tags <tags>", "Filter by tags (comma-separated)")
|
|
13
|
+
.option("--limit <n>", "Max results (default 10)", "10")
|
|
14
|
+
.option("--graph", "Query the knowledge graph (GraphNode/GraphEdge) instead of semantic recall")
|
|
15
|
+
.option("--type <type>", "Node type filter (graph mode only): note, tag, concept")
|
|
16
|
+
.option("--neighbors <nodeId>", "Show neighbors of a node (graph mode only)")
|
|
17
|
+
.option("--depth <n>", "Neighbor traversal depth 1-3 (graph mode only)", "1")
|
|
16
18
|
.option("--workspace-id <id>", "Workspace ID")
|
|
17
19
|
.action(async (opts) => {
|
|
18
20
|
const globalOpts = program.opts();
|
|
19
21
|
const config = (0, config_1.resolveConfig)(globalOpts);
|
|
20
22
|
const client = (0, client_1.createClient)(config.baseUrl, config.apiKey);
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
+
const workspaceId = opts.workspaceId || config.workspaceId;
|
|
24
|
+
// Graph mode
|
|
25
|
+
if (opts.graph) {
|
|
26
|
+
const result = await client.queryGraph({
|
|
27
|
+
workspaceId,
|
|
28
|
+
query: opts.query,
|
|
29
|
+
nodeType: opts.type,
|
|
30
|
+
neighbors: opts.neighbors,
|
|
31
|
+
depth: opts.depth ? parseInt(opts.depth, 10) : undefined,
|
|
32
|
+
limit: opts.limit ? parseInt(opts.limit, 10) : undefined,
|
|
33
|
+
});
|
|
34
|
+
if (globalOpts.json) {
|
|
35
|
+
(0, output_1.printJson)(result.data);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
(0, output_1.printGraph)(result.data.nodes, result.data.edges);
|
|
39
|
+
}
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// Semantic recall mode (default)
|
|
43
|
+
if (!opts.query) {
|
|
44
|
+
process.stderr.write("Error: --query is required for semantic recall. Use --graph for graph queries without a query.\n");
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
const tags = opts.tags ? opts.tags.split(",").map((t) => t.trim()) : undefined;
|
|
48
|
+
const result = await client.recallKnowledge({
|
|
23
49
|
query: opts.query,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
depth: opts.depth ? parseInt(opts.depth, 10) : undefined,
|
|
50
|
+
workspaceId,
|
|
51
|
+
tags,
|
|
27
52
|
limit: opts.limit ? parseInt(opts.limit, 10) : undefined,
|
|
28
53
|
});
|
|
29
54
|
if (globalOpts.json) {
|
|
30
|
-
(0, output_1.printJson)(result.data);
|
|
55
|
+
(0, output_1.printJson)(result.data.results);
|
|
31
56
|
}
|
|
32
57
|
else {
|
|
33
|
-
(0, output_1.
|
|
58
|
+
(0, output_1.printKnowledgeResults)(result.data.results);
|
|
34
59
|
}
|
|
35
60
|
});
|
|
36
61
|
}
|
package/dist/output.d.ts
CHANGED
|
@@ -14,6 +14,17 @@ export declare function printSearchResults(results: Array<{
|
|
|
14
14
|
title: string;
|
|
15
15
|
snippet?: string;
|
|
16
16
|
}>): void;
|
|
17
|
+
export declare function printKnowledgeResults(results: Array<{
|
|
18
|
+
id: string;
|
|
19
|
+
title: string;
|
|
20
|
+
key: string | null;
|
|
21
|
+
excerpt: string;
|
|
22
|
+
importance: number | null;
|
|
23
|
+
tags: string[];
|
|
24
|
+
semanticScore: number;
|
|
25
|
+
freshnessScore: number;
|
|
26
|
+
finalScore: number;
|
|
27
|
+
}>): void;
|
|
17
28
|
export declare function printGraph(nodes: Array<{
|
|
18
29
|
id: string;
|
|
19
30
|
noteId: string | null;
|
package/dist/output.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.printJson = printJson;
|
|
|
4
4
|
exports.printNoteList = printNoteList;
|
|
5
5
|
exports.printNote = printNote;
|
|
6
6
|
exports.printSearchResults = printSearchResults;
|
|
7
|
+
exports.printKnowledgeResults = printKnowledgeResults;
|
|
7
8
|
exports.printGraph = printGraph;
|
|
8
9
|
exports.printSuccess = printSuccess;
|
|
9
10
|
function printJson(data) {
|
|
@@ -43,6 +44,28 @@ function printSearchResults(results) {
|
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
}
|
|
47
|
+
function printKnowledgeResults(results) {
|
|
48
|
+
if (results.length === 0) {
|
|
49
|
+
process.stderr.write("No knowledge entries found.\n");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
for (let i = 0; i < results.length; i++) {
|
|
53
|
+
const r = results[i];
|
|
54
|
+
const score = (r.finalScore * 100).toFixed(0);
|
|
55
|
+
const key = r.key ? ` [${r.key}]` : "";
|
|
56
|
+
const tags = r.tags.length > 0 ? ` (${r.tags.join(", ")})` : "";
|
|
57
|
+
const importance = r.importance !== null ? ` imp:${r.importance}` : "";
|
|
58
|
+
console.log(`${i + 1}. ${r.title}${key} ${score}%${importance}${tags}`);
|
|
59
|
+
if (r.excerpt) {
|
|
60
|
+
const lines = r.excerpt.split("\n").slice(0, 3).join("\n ");
|
|
61
|
+
console.log(` ${lines}`);
|
|
62
|
+
}
|
|
63
|
+
if (i < results.length - 1)
|
|
64
|
+
console.log("");
|
|
65
|
+
}
|
|
66
|
+
console.log("");
|
|
67
|
+
console.log(`${results.length} result(s)`);
|
|
68
|
+
}
|
|
46
69
|
function printGraph(nodes, edges) {
|
|
47
70
|
if (nodes.length === 0) {
|
|
48
71
|
process.stderr.write("Knowledge graph is empty.\n");
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Templates for Claude Code skills.
|
|
3
|
-
* Written to `.claude/skills
|
|
3
|
+
* Written to `.claude/skills/<skill-name>/SKILL.md` — Claude Code's skill loader
|
|
4
|
+
* only discovers skills that live in their own folder as `SKILL.md`.
|
|
4
5
|
* Generated by m-notes CLI — do not edit manually.
|
|
5
6
|
*/
|
|
6
7
|
export interface SkillTemplateOpts {
|
|
@@ -8,11 +9,14 @@ export interface SkillTemplateOpts {
|
|
|
8
9
|
workspaceId: string;
|
|
9
10
|
}
|
|
10
11
|
export interface SkillFile {
|
|
11
|
-
|
|
12
|
+
/** Relative path within `.claude/skills/`, e.g. `mnotes-store/SKILL.md`. */
|
|
13
|
+
path: string;
|
|
12
14
|
content: string;
|
|
13
15
|
}
|
|
14
16
|
/**
|
|
15
17
|
* Generates skill files for m-notes integration.
|
|
16
|
-
* Returns an array of {
|
|
18
|
+
* Returns an array of { path, content } pairs. `path` is relative to
|
|
19
|
+
* `.claude/skills/` and always ends in `SKILL.md` so Claude Code's loader
|
|
20
|
+
* discovers the skill.
|
|
17
21
|
*/
|
|
18
22
|
export declare function generateSkillTemplates(opts: SkillTemplateOpts): SkillFile[];
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* Templates for Claude Code skills.
|
|
4
|
-
* Written to `.claude/skills
|
|
4
|
+
* Written to `.claude/skills/<skill-name>/SKILL.md` — Claude Code's skill loader
|
|
5
|
+
* only discovers skills that live in their own folder as `SKILL.md`.
|
|
5
6
|
* Generated by m-notes CLI — do not edit manually.
|
|
6
7
|
*/
|
|
7
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -9,17 +10,18 @@ exports.generateSkillTemplates = generateSkillTemplates;
|
|
|
9
10
|
const GENERATED_HEADER = "<!-- Generated by m-notes CLI. Do not edit manually. -->";
|
|
10
11
|
/**
|
|
11
12
|
* Generates skill files for m-notes integration.
|
|
12
|
-
* Returns an array of {
|
|
13
|
+
* Returns an array of { path, content } pairs. `path` is relative to
|
|
14
|
+
* `.claude/skills/` and always ends in `SKILL.md` so Claude Code's loader
|
|
15
|
+
* discovers the skill.
|
|
13
16
|
*/
|
|
14
17
|
function generateSkillTemplates(opts) {
|
|
15
18
|
return [
|
|
16
19
|
{
|
|
17
|
-
|
|
20
|
+
path: "mnotes-store/SKILL.md",
|
|
18
21
|
content: `${GENERATED_HEADER}
|
|
19
22
|
---
|
|
20
23
|
name: mnotes-store
|
|
21
|
-
description: Store a knowledge entry in m-notes
|
|
22
|
-
trigger: When the user says /store or asks to save/store knowledge, decisions, patterns, or context
|
|
24
|
+
description: Store a knowledge entry in m-notes. Use when the user says /store or asks to save/store knowledge, decisions, patterns, or context.
|
|
23
25
|
---
|
|
24
26
|
|
|
25
27
|
# Store Knowledge in m-notes
|
|
@@ -44,12 +46,11 @@ Use the \`knowledge_store\` MCP tool to save knowledge.
|
|
|
44
46
|
`,
|
|
45
47
|
},
|
|
46
48
|
{
|
|
47
|
-
|
|
49
|
+
path: "mnotes-recall/SKILL.md",
|
|
48
50
|
content: `${GENERATED_HEADER}
|
|
49
51
|
---
|
|
50
52
|
name: mnotes-recall
|
|
51
|
-
description: Recall knowledge from m-notes using semantic search
|
|
52
|
-
trigger: When the user says /recall or asks to find/recall/search knowledge, or needs context about a topic
|
|
53
|
+
description: Recall knowledge from m-notes using semantic search. Use when the user says /recall or asks to find/recall/search knowledge, or needs context about a topic.
|
|
53
54
|
---
|
|
54
55
|
|
|
55
56
|
# Recall Knowledge from m-notes
|