mnotes-cli 1.9.2 → 1.10.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/commands/connect/__tests__/connect.test.js +22 -5
- package/dist/commands/connect/__tests__/wizard.test.js +28 -10
- package/dist/commands/connect/wizard.js +14 -3
- package/dist/templates/claude-code/hooks.d.ts +10 -4
- package/dist/templates/claude-code/hooks.js +50 -20
- package/dist/templates/claude-code/index.d.ts +2 -2
- package/dist/templates/claude-code/index.js +2 -1
- package/dist/templates/claude-code.js +125 -106
- package/dist/templates/codex.js +36 -32
- package/dist/templates/openclaw.js +21 -12
- package/package.json +1 -1
|
@@ -380,14 +380,14 @@ function cleanTmpDir(dir) {
|
|
|
380
380
|
(0, vitest_1.expect)(result).toContain("https://notes.example.com");
|
|
381
381
|
(0, vitest_1.expect)(result).toContain("ws-abc-123");
|
|
382
382
|
});
|
|
383
|
-
(0, vitest_1.it)("includes session lifecycle
|
|
383
|
+
(0, vitest_1.it)("includes session lifecycle tools and wiki framing", () => {
|
|
384
384
|
const result = (0, claude_code_1.generateClaudeCodeTemplate)({
|
|
385
385
|
url: "http://localhost:3000",
|
|
386
386
|
workspaceId: "ws-test",
|
|
387
387
|
});
|
|
388
|
-
(0, vitest_1.expect)(result).toContain("
|
|
389
|
-
(0, vitest_1.expect)(result).toContain("
|
|
390
|
-
(0, vitest_1.expect)(result).toContain("
|
|
388
|
+
(0, vitest_1.expect)(result).toContain("living wiki");
|
|
389
|
+
(0, vitest_1.expect)(result).toContain("Ingest Loop");
|
|
390
|
+
(0, vitest_1.expect)(result).toContain("Lint Loop");
|
|
391
391
|
(0, vitest_1.expect)(result).toContain("project_context_load");
|
|
392
392
|
(0, vitest_1.expect)(result).toContain("session_context_resume");
|
|
393
393
|
(0, vitest_1.expect)(result).toContain("knowledge_store");
|
|
@@ -417,13 +417,30 @@ function cleanTmpDir(dir) {
|
|
|
417
417
|
"recall_knowledge",
|
|
418
418
|
"bulk_knowledge_recall",
|
|
419
419
|
"knowledge_snapshot",
|
|
420
|
+
"scan_knowledge_conflicts",
|
|
420
421
|
"session_log",
|
|
421
422
|
"context_fetch",
|
|
423
|
+
"create_note",
|
|
424
|
+
"update_note",
|
|
425
|
+
"append_to_note",
|
|
426
|
+
"search_notes",
|
|
427
|
+
"daily_note",
|
|
428
|
+
"populate_graph",
|
|
429
|
+
"query_note_graph",
|
|
422
430
|
];
|
|
423
431
|
for (const tool of expectedTools) {
|
|
424
432
|
(0, vitest_1.expect)(result).toContain(tool);
|
|
425
433
|
}
|
|
426
434
|
});
|
|
435
|
+
(0, vitest_1.it)("does not reference phantom MCP tools", () => {
|
|
436
|
+
const result = (0, claude_code_1.generateClaudeCodeTemplate)({
|
|
437
|
+
url: "http://localhost:3000",
|
|
438
|
+
workspaceId: "ws-test",
|
|
439
|
+
});
|
|
440
|
+
// These tool names don't exist in the MCP server — guard against regressions.
|
|
441
|
+
(0, vitest_1.expect)(result).not.toMatch(/\bcreate_folder\b/);
|
|
442
|
+
(0, vitest_1.expect)(result).not.toMatch(/\bmove_note\b/);
|
|
443
|
+
});
|
|
427
444
|
});
|
|
428
445
|
// =============================================================
|
|
429
446
|
// Template generation — generateCodexTemplate (AC-6.3)
|
|
@@ -615,7 +632,7 @@ function cleanTmpDir(dir) {
|
|
|
615
632
|
const claudeMd = fs.readFileSync(path.join(tmpDir, "CLAUDE.md"), "utf-8");
|
|
616
633
|
(0, vitest_1.expect)(claudeMd).toContain("<!-- m-notes:start -->");
|
|
617
634
|
(0, vitest_1.expect)(claudeMd).toContain("<!-- m-notes:end -->");
|
|
618
|
-
(0, vitest_1.expect)(claudeMd).toContain("m-notes
|
|
635
|
+
(0, vitest_1.expect)(claudeMd).toContain("m-notes — Your Wiki");
|
|
619
636
|
(0, vitest_1.expect)(claudeMd).toContain("ws-123");
|
|
620
637
|
});
|
|
621
638
|
(0, vitest_1.it)("replaces existing m-notes block on re-run", async () => {
|
|
@@ -55,20 +55,29 @@ const DEFAULT_OPTS = {
|
|
|
55
55
|
// T-1: Template generation — hooks
|
|
56
56
|
// =============================================================
|
|
57
57
|
(0, vitest_1.describe)("hooks template", () => {
|
|
58
|
-
(0, vitest_1.it)("generates SessionStart hook
|
|
58
|
+
(0, vitest_1.it)("generates SessionStart hook referencing bash script", () => {
|
|
59
59
|
const hooks = (0, hooks_1.generateHooksTemplate)(DEFAULT_OPTS);
|
|
60
60
|
(0, vitest_1.expect)(hooks.SessionStart).toBeDefined();
|
|
61
61
|
(0, vitest_1.expect)(hooks.SessionStart).toHaveLength(1);
|
|
62
62
|
(0, vitest_1.expect)(hooks.SessionStart[0].matcher).toBe("");
|
|
63
63
|
(0, vitest_1.expect)(hooks.SessionStart[0].hooks).toHaveLength(1);
|
|
64
64
|
(0, vitest_1.expect)(hooks.SessionStart[0].hooks[0].type).toBe("command");
|
|
65
|
-
(0, vitest_1.expect)(hooks.SessionStart[0].hooks[0].command).
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
(0, vitest_1.expect)(
|
|
65
|
+
(0, vitest_1.expect)(hooks.SessionStart[0].hooks[0].command).toBe(".claude/hooks/mnotes-session-start.sh");
|
|
66
|
+
});
|
|
67
|
+
(0, vitest_1.it)("generates hook scripts with correct URL, workspaceId, and Accept headers", () => {
|
|
68
|
+
const scripts = (0, hooks_1.generateHookScripts)(DEFAULT_OPTS);
|
|
69
|
+
(0, vitest_1.expect)(scripts).toHaveLength(2);
|
|
70
|
+
const startScript = scripts.find((s) => s.filename === "mnotes-session-start.sh");
|
|
71
|
+
(0, vitest_1.expect)(startScript.content).toContain("localhost:3000/api/mcp");
|
|
72
|
+
(0, vitest_1.expect)(startScript.content).toContain("ws-test-123");
|
|
73
|
+
(0, vitest_1.expect)(startScript.content).toContain('Accept: text/event-stream');
|
|
74
|
+
(0, vitest_1.expect)(startScript.content).toContain('Accept: application/json');
|
|
75
|
+
});
|
|
76
|
+
(0, vitest_1.it)("strips trailing slashes from URL in hook scripts", () => {
|
|
77
|
+
const scripts = (0, hooks_1.generateHookScripts)({ url: "http://example.com///", workspaceId: "ws-1" });
|
|
78
|
+
const startScript = scripts.find((s) => s.filename === "mnotes-session-start.sh");
|
|
79
|
+
(0, vitest_1.expect)(startScript.content).toContain("http://example.com/api/mcp");
|
|
80
|
+
(0, vitest_1.expect)(startScript.content).not.toContain("///");
|
|
72
81
|
});
|
|
73
82
|
});
|
|
74
83
|
// =============================================================
|
|
@@ -162,17 +171,26 @@ const DEFAULT_OPTS = {
|
|
|
162
171
|
(0, vitest_1.afterEach)(() => {
|
|
163
172
|
cleanTmpDir(tmpDir);
|
|
164
173
|
});
|
|
165
|
-
(0, vitest_1.it)("creates .claude/settings.json with hooks (AC-4)", () => {
|
|
174
|
+
(0, vitest_1.it)("creates .claude/settings.json with hooks and bash scripts (AC-4)", () => {
|
|
166
175
|
const results = (0, wizard_1.scaffoldItems)(tmpDir, ["hooks"], DEFAULT_OPTS);
|
|
167
176
|
(0, vitest_1.expect)(results).toHaveLength(1);
|
|
168
177
|
(0, vitest_1.expect)(results[0].item).toBe("hooks");
|
|
169
|
-
|
|
178
|
+
// 2 bash scripts + settings.json
|
|
179
|
+
(0, vitest_1.expect)(results[0].filesWritten).toHaveLength(3);
|
|
170
180
|
const settingsPath = path.join(tmpDir, ".claude", "settings.json");
|
|
171
181
|
(0, vitest_1.expect)(fs.existsSync(settingsPath)).toBe(true);
|
|
172
182
|
const settings = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
|
|
173
183
|
(0, vitest_1.expect)(settings.hooks).toBeDefined();
|
|
174
184
|
(0, vitest_1.expect)(settings.hooks.SessionStart).toBeDefined();
|
|
175
185
|
(0, vitest_1.expect)(settings.hooks.SessionStart).toHaveLength(1);
|
|
186
|
+
// Bash scripts exist and are executable
|
|
187
|
+
const startScript = path.join(tmpDir, ".claude", "hooks", "mnotes-session-start.sh");
|
|
188
|
+
const stopScript = path.join(tmpDir, ".claude", "hooks", "mnotes-session-stop.sh");
|
|
189
|
+
(0, vitest_1.expect)(fs.existsSync(startScript)).toBe(true);
|
|
190
|
+
(0, vitest_1.expect)(fs.existsSync(stopScript)).toBe(true);
|
|
191
|
+
const startContent = fs.readFileSync(startScript, "utf-8");
|
|
192
|
+
(0, vitest_1.expect)(startContent).toContain("Accept: text/event-stream");
|
|
193
|
+
(0, vitest_1.expect)(startContent).toContain("Accept: application/json");
|
|
176
194
|
});
|
|
177
195
|
(0, vitest_1.it)("merges hooks into existing settings.json (AC-5)", () => {
|
|
178
196
|
const claudeDir = path.join(tmpDir, ".claude");
|
|
@@ -102,13 +102,23 @@ function scaffoldItems(dir, items, opts) {
|
|
|
102
102
|
return results;
|
|
103
103
|
}
|
|
104
104
|
/**
|
|
105
|
-
* Merges hooks into `.claude/settings.json`.
|
|
105
|
+
* Merges hooks into `.claude/settings.json` and writes bash scripts to `.claude/hooks/`.
|
|
106
106
|
* Preserves all existing settings and hooks.
|
|
107
107
|
*/
|
|
108
108
|
function scaffoldHooks(dir, opts) {
|
|
109
109
|
const settingsPath = path.join(dir, ".claude", "settings.json");
|
|
110
110
|
const claudeDir = path.join(dir, ".claude");
|
|
111
|
-
|
|
111
|
+
const hooksDir = path.join(claudeDir, "hooks");
|
|
112
|
+
fs.mkdirSync(hooksDir, { recursive: true });
|
|
113
|
+
const filesWritten = [];
|
|
114
|
+
// 1. Write bash scripts to .claude/hooks/
|
|
115
|
+
const scripts = (0, index_1.generateHookScripts)(opts);
|
|
116
|
+
for (const script of scripts) {
|
|
117
|
+
const scriptPath = path.join(hooksDir, script.filename);
|
|
118
|
+
fs.writeFileSync(scriptPath, script.content, { mode: 0o755 });
|
|
119
|
+
filesWritten.push(scriptPath);
|
|
120
|
+
}
|
|
121
|
+
// 2. Merge hook entries into settings.json
|
|
112
122
|
let existing = {};
|
|
113
123
|
try {
|
|
114
124
|
const raw = fs.readFileSync(settingsPath, "utf-8");
|
|
@@ -158,7 +168,8 @@ function scaffoldHooks(dir, opts) {
|
|
|
158
168
|
mnotesMetadata.items.push("hooks");
|
|
159
169
|
}
|
|
160
170
|
fs.writeFileSync(settingsPath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
|
|
161
|
-
|
|
171
|
+
filesWritten.push(settingsPath);
|
|
172
|
+
return { item: "hooks", filesWritten };
|
|
162
173
|
}
|
|
163
174
|
/**
|
|
164
175
|
* Writes skill files to `.claude/skills/`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Template for Claude Code session hooks.
|
|
3
|
-
*
|
|
3
|
+
* Generates bash scripts in `.claude/hooks/` and hook entries for `.claude/settings.json`.
|
|
4
4
|
* Generated by m-notes CLI — do not edit manually.
|
|
5
5
|
*/
|
|
6
6
|
export interface HooksTemplateOpts {
|
|
@@ -19,11 +19,17 @@ export interface ClaudeCodeHooks {
|
|
|
19
19
|
SessionStart?: ClaudeCodeHookEntry[];
|
|
20
20
|
[key: string]: ClaudeCodeHookEntry[] | undefined;
|
|
21
21
|
}
|
|
22
|
+
export interface HookScript {
|
|
23
|
+
filename: string;
|
|
24
|
+
content: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Generates bash scripts to be written to `.claude/hooks/`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function generateHookScripts(opts: HooksTemplateOpts): HookScript[];
|
|
22
30
|
/**
|
|
23
31
|
* Generates the hooks object to merge into `.claude/settings.json`.
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* Claude Code hooks format requires: { matcher, hooks[] } wrapper.
|
|
32
|
+
* References bash scripts in `.claude/hooks/` instead of inline commands.
|
|
27
33
|
*/
|
|
28
34
|
export declare function generateHooksTemplate(opts: HooksTemplateOpts): ClaudeCodeHooks;
|
|
29
35
|
/** Header comment for the hooks section, used for identification. */
|
|
@@ -1,31 +1,69 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* Template for Claude Code session hooks.
|
|
4
|
-
*
|
|
4
|
+
* Generates bash scripts in `.claude/hooks/` and hook entries for `.claude/settings.json`.
|
|
5
5
|
* Generated by m-notes CLI — do not edit manually.
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
8
|
exports.HOOKS_HEADER = void 0;
|
|
9
|
+
exports.generateHookScripts = generateHookScripts;
|
|
9
10
|
exports.generateHooksTemplate = generateHooksTemplate;
|
|
10
11
|
/**
|
|
11
|
-
* Generates
|
|
12
|
-
* Currently provides a SessionStart hook that auto-loads project context.
|
|
13
|
-
*
|
|
14
|
-
* Claude Code hooks format requires: { matcher, hooks[] } wrapper.
|
|
12
|
+
* Generates bash scripts to be written to `.claude/hooks/`.
|
|
15
13
|
*/
|
|
16
|
-
function
|
|
14
|
+
function generateHookScripts(opts) {
|
|
17
15
|
const baseUrl = opts.url.replace(/\/+$/, "");
|
|
18
16
|
const mcpUrl = `${baseUrl}/api/mcp`;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const payload = JSON.stringify({
|
|
17
|
+
function mcpPayload(method, args) {
|
|
18
|
+
return JSON.stringify({
|
|
22
19
|
jsonrpc: "2.0",
|
|
23
20
|
method: "tools/call",
|
|
24
21
|
params: { name: method, arguments: args },
|
|
25
22
|
id: 1,
|
|
26
23
|
});
|
|
27
|
-
return `curl -s -H "${authHeader}" "${mcpUrl}" -d '${payload}' -H "Content-Type: application/json" > /dev/null 2>&1 || true`;
|
|
28
24
|
}
|
|
25
|
+
const sessionStartScript = `#!/usr/bin/env bash
|
|
26
|
+
# Generated by m-notes CLI — do not edit manually.
|
|
27
|
+
# Loads project context on Claude Code session start.
|
|
28
|
+
set -euo pipefail
|
|
29
|
+
|
|
30
|
+
MNOTES_URL="${mcpUrl}"
|
|
31
|
+
PAYLOAD='${mcpPayload("project_context_load", { workspaceId: opts.workspaceId, query: "session start" })}'
|
|
32
|
+
|
|
33
|
+
curl -s \\
|
|
34
|
+
-H "Authorization: Bearer $MNOTES_API_KEY" \\
|
|
35
|
+
-H "Content-Type: application/json" \\
|
|
36
|
+
-H "Accept: text/event-stream" \\
|
|
37
|
+
-H "Accept: application/json" \\
|
|
38
|
+
"$MNOTES_URL" \\
|
|
39
|
+
-d "$PAYLOAD" > /dev/null 2>&1 || true
|
|
40
|
+
`;
|
|
41
|
+
const sessionStopScript = `#!/usr/bin/env bash
|
|
42
|
+
# Generated by m-notes CLI — do not edit manually.
|
|
43
|
+
# Logs session end to m-notes.
|
|
44
|
+
set -euo pipefail
|
|
45
|
+
|
|
46
|
+
MNOTES_URL="${mcpUrl}"
|
|
47
|
+
PAYLOAD='${mcpPayload("session_log", { workspaceId: opts.workspaceId, summary: "Session ended", decisions: [], actions: [] })}'
|
|
48
|
+
|
|
49
|
+
curl -s \\
|
|
50
|
+
-H "Authorization: Bearer $MNOTES_API_KEY" \\
|
|
51
|
+
-H "Content-Type: application/json" \\
|
|
52
|
+
-H "Accept: text/event-stream" \\
|
|
53
|
+
-H "Accept: application/json" \\
|
|
54
|
+
"$MNOTES_URL" \\
|
|
55
|
+
-d "$PAYLOAD" > /dev/null 2>&1 || true
|
|
56
|
+
`;
|
|
57
|
+
return [
|
|
58
|
+
{ filename: "mnotes-session-start.sh", content: sessionStartScript },
|
|
59
|
+
{ filename: "mnotes-session-stop.sh", content: sessionStopScript },
|
|
60
|
+
];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Generates the hooks object to merge into `.claude/settings.json`.
|
|
64
|
+
* References bash scripts in `.claude/hooks/` instead of inline commands.
|
|
65
|
+
*/
|
|
66
|
+
function generateHooksTemplate(opts) {
|
|
29
67
|
return {
|
|
30
68
|
SessionStart: [
|
|
31
69
|
{
|
|
@@ -33,10 +71,7 @@ function generateHooksTemplate(opts) {
|
|
|
33
71
|
hooks: [
|
|
34
72
|
{
|
|
35
73
|
type: "command",
|
|
36
|
-
command:
|
|
37
|
-
workspaceId: opts.workspaceId,
|
|
38
|
-
query: "session start",
|
|
39
|
-
}),
|
|
74
|
+
command: ".claude/hooks/mnotes-session-start.sh",
|
|
40
75
|
},
|
|
41
76
|
],
|
|
42
77
|
},
|
|
@@ -47,12 +82,7 @@ function generateHooksTemplate(opts) {
|
|
|
47
82
|
hooks: [
|
|
48
83
|
{
|
|
49
84
|
type: "command",
|
|
50
|
-
command:
|
|
51
|
-
workspaceId: opts.workspaceId,
|
|
52
|
-
summary: "Session ended",
|
|
53
|
-
decisions: [],
|
|
54
|
-
actions: [],
|
|
55
|
-
}),
|
|
85
|
+
command: ".claude/hooks/mnotes-session-stop.sh",
|
|
56
86
|
},
|
|
57
87
|
],
|
|
58
88
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { generateHooksTemplate, HOOKS_HEADER } from "./hooks";
|
|
2
|
-
export type { HooksTemplateOpts, ClaudeCodeHooks, ClaudeCodeHook } from "./hooks";
|
|
1
|
+
export { generateHooksTemplate, generateHookScripts, HOOKS_HEADER } from "./hooks";
|
|
2
|
+
export type { HooksTemplateOpts, ClaudeCodeHooks, ClaudeCodeHook, HookScript } from "./hooks";
|
|
3
3
|
export { generateSkillTemplates } from "./skills";
|
|
4
4
|
export type { SkillTemplateOpts, SkillFile } from "./skills";
|
|
5
5
|
export { generateAgentTemplates } from "./agents";
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateAgentTemplates = exports.generateSkillTemplates = exports.HOOKS_HEADER = exports.generateHooksTemplate = void 0;
|
|
3
|
+
exports.generateAgentTemplates = exports.generateSkillTemplates = exports.HOOKS_HEADER = exports.generateHookScripts = exports.generateHooksTemplate = void 0;
|
|
4
4
|
var hooks_1 = require("./hooks");
|
|
5
5
|
Object.defineProperty(exports, "generateHooksTemplate", { enumerable: true, get: function () { return hooks_1.generateHooksTemplate; } });
|
|
6
|
+
Object.defineProperty(exports, "generateHookScripts", { enumerable: true, get: function () { return hooks_1.generateHookScripts; } });
|
|
6
7
|
Object.defineProperty(exports, "HOOKS_HEADER", { enumerable: true, get: function () { return hooks_1.HOOKS_HEADER; } });
|
|
7
8
|
var skills_1 = require("./skills");
|
|
8
9
|
Object.defineProperty(exports, "generateSkillTemplates", { enumerable: true, get: function () { return skills_1.generateSkillTemplates; } });
|
|
@@ -2,107 +2,131 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateClaudeCodeTemplate = generateClaudeCodeTemplate;
|
|
4
4
|
function generateClaudeCodeTemplate(opts) {
|
|
5
|
-
return
|
|
5
|
+
return `<!-- m-notes instructions v3 -->
|
|
6
|
+
# m-notes — Your Wiki (MANDATORY)
|
|
6
7
|
|
|
7
8
|
**Server**: ${opts.url}
|
|
8
9
|
**Workspace**: ${opts.workspaceId}
|
|
9
10
|
|
|
10
|
-
>
|
|
11
|
+
> You are not a reader of a scratchpad. You are the **author and maintainer of a living wiki**. Every session, three things compound: the wiki grows, links densify, contradictions get resolved. This is your persistent memory — without it you start from zero every conversation.
|
|
12
|
+
|
|
13
|
+
## The Three Layers
|
|
14
|
+
|
|
15
|
+
1. **Raw sources** — user messages, pasted docs, URLs, files. Immutable. You never edit these.
|
|
16
|
+
2. **The wiki** — your notes. You *write* these. They are interlinked with \`[[wikilinks]]\`, tagged for retrieval, and updated whenever sources change.
|
|
17
|
+
3. **Schema pages** — notes tagged \`type:config\` (or in a \`_schema/\` folder). The user's rules for how the wiki is organized. **Read these before editing the wiki.**
|
|
11
18
|
|
|
12
19
|
## Rules (follow strictly)
|
|
13
20
|
|
|
14
|
-
1. **ALWAYS recall before researching.** Before exploring the codebase
|
|
15
|
-
2. **ALWAYS store what you learn.**
|
|
16
|
-
3. **ALWAYS log sessions.**
|
|
17
|
-
4. **ALWAYS load context at session start.** Call \`project_context_load
|
|
21
|
+
1. **ALWAYS recall before researching.** Before exploring the codebase or making assumptions — call \`recall_knowledge\` and \`search_notes\`. Past you already figured things out.
|
|
22
|
+
2. **ALWAYS store what you learn.** Non-obvious discoveries → \`knowledge_store\` immediately. Anything worth re-finding belongs in the wiki.
|
|
23
|
+
3. **ALWAYS log sessions.** Call \`session_log\` before the session ends.
|
|
24
|
+
4. **ALWAYS load context at session start.** Call \`project_context_load\`. Use \`session_context_resume\` if mid-conversation.
|
|
25
|
+
5. **INGEST sources coherently.** When the user drops a URL, long paste, or file: don't just dump it into one note. Run the **ingest loop** (below).
|
|
26
|
+
6. **LINT the wiki periodically.** On session start for large workspaces, and after any ingest, run the **lint loop** (below).
|
|
27
|
+
7. **READ schema before editing.** Before creating or updating notes, call \`search_notes\` for \`type:config\` notes. Follow their conventions. If none exist, offer to create a starter schema note.
|
|
28
|
+
8. **EVERY note must link.** Outbound \`[[wikilinks]]\` are mandatory — an orphan note is invisible.
|
|
29
|
+
|
|
30
|
+
## The Ingest Loop
|
|
31
|
+
|
|
32
|
+
When the user supplies a source (URL, paste, file):
|
|
33
|
+
|
|
34
|
+
1. **Find related pages**: \`search_notes\` + \`query_graph\` to identify 3–15 existing notes affected.
|
|
35
|
+
2. **Plan the edits**: which existing notes need \`append_to_note\` / \`update_note\`, which new notes need \`create_note\`, and what \`[[wikilinks]]\` connect them.
|
|
36
|
+
3. **Apply**: execute the plan. Every touched note gets:
|
|
37
|
+
- A \`source/<slug>\` tag or a "Sources" section listing provenance
|
|
38
|
+
- At least one \`[[wikilink]]\` to another touched note
|
|
39
|
+
4. **Summarize**: tell the user which notes were created vs. updated.
|
|
40
|
+
|
|
41
|
+
A single source should rarely touch fewer than 3 notes — that's a sign you're treating the wiki as a dumping ground.
|
|
42
|
+
|
|
43
|
+
## The Lint Loop
|
|
44
|
+
|
|
45
|
+
Periodically (session start on large workspaces; after ingests):
|
|
46
|
+
|
|
47
|
+
- **Contradictions** → call \`scan_knowledge_conflicts\`. Resolve, don't stack.
|
|
48
|
+
- **Orphans** → \`query_note_graph\` for notes with zero inbound or outbound links. Link them or delete.
|
|
49
|
+
- **Broken wikilinks** → \`[[X]]\` targets that don't exist. Create a stub note or fix the link.
|
|
50
|
+
- **Stale** → notes untouched >90 days referenced by new sources. Update them.
|
|
51
|
+
|
|
52
|
+
Report findings as a short list; ask before bulk-deleting.
|
|
18
53
|
|
|
19
54
|
## When to Store Knowledge
|
|
20
55
|
|
|
21
|
-
Store
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
56
|
+
Store **proactively** — don't wait to be asked. Categories:
|
|
57
|
+
- Architecture decision → \`arch/{component}\`
|
|
58
|
+
- Code pattern or convention → \`pattern/{name}\`
|
|
59
|
+
- Debugged bug → \`bug/{id}\`
|
|
60
|
+
- Dependency quirk → \`dep/{package}\`
|
|
61
|
+
- Product/tech decision → \`decision/{topic}\`
|
|
62
|
+
- Domain understanding → \`context/{area}\`
|
|
63
|
+
- Gotcha or footgun → \`gotcha/{description}\`
|
|
64
|
+
- Completed task → \`task/{id}\`
|
|
65
|
+
|
|
66
|
+
**Promotion rule**: if a knowledge entry is recalled 3+ times, promote it to a full note with \`create_note\` — it has earned a wiki page.
|
|
30
67
|
|
|
31
68
|
## When to Recall Knowledge
|
|
32
69
|
|
|
33
|
-
Recall
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
|
|
41
|
-
## Notes
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
- **Meeting notes** → \`create_note\` after any planning discussion or decision
|
|
47
|
-
- **Investigation logs** → create a note when debugging, append findings as you go with \`append_to_note\`
|
|
48
|
-
- **Design docs** → write architecture or design decisions as full notes, not just knowledge entries
|
|
49
|
-
- **Task summaries** → after completing a story/task, create a note summarizing what was done
|
|
50
|
-
- **Checklists and plans** → create notes with markdown checklists for multi-step work
|
|
51
|
-
- **Daily notes** → use \`daily_note\` to create/get today's note for quick captures
|
|
52
|
-
|
|
53
|
-
### When to Edit Notes
|
|
54
|
-
- **Append progress** → use \`append_to_note\` to add to existing notes as work progresses
|
|
55
|
-
- **Update docs** → when code changes invalidate existing notes, update them with \`update_note\`
|
|
56
|
-
- **Tag and organize** → use \`manage_tags\` and folder tools to keep notes findable
|
|
57
|
-
|
|
58
|
-
### Note vs Knowledge Entry
|
|
59
|
-
| Use a **note** when... | Use **knowledge_store** when... |
|
|
70
|
+
Recall **before acting**:
|
|
71
|
+
- Tech decision → \`arch/*\` + \`decision/*\`
|
|
72
|
+
- Touching a module → relevant \`pattern/*\` + \`context/*\`
|
|
73
|
+
- Debugging → \`bug/*\` for similar past issues
|
|
74
|
+
- Adding a dependency → \`dep/*\`
|
|
75
|
+
- Session start → \`project_context_load\` (automatic via SessionStart hook)
|
|
76
|
+
- User asks about past work → \`session_context_resume\`
|
|
77
|
+
|
|
78
|
+
## Notes vs. Knowledge Entries
|
|
79
|
+
|
|
80
|
+
In the wiki model, **notes are primary**. Knowledge entries are fast-capture for things that haven't earned a page yet.
|
|
81
|
+
|
|
82
|
+
| Use a **note** when... | Use \`knowledge_store\` when... |
|
|
60
83
|
|---|---|
|
|
61
|
-
| Content is long-form
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
| Meeting notes,
|
|
84
|
+
| Content is long-form or evolving | Content is a single fact |
|
|
85
|
+
| Needs \`[[wikilinks]]\` and backlinks | Key/tag retrieval is enough |
|
|
86
|
+
| Subject will be referenced repeatedly | One-shot capture |
|
|
87
|
+
| Meeting notes, investigations, design docs | Architecture decisions, gotchas |
|
|
88
|
+
|
|
89
|
+
**When in doubt, create a note.**
|
|
65
90
|
|
|
66
|
-
|
|
91
|
+
### Note Creation
|
|
92
|
+
- **Meetings / planning** → \`create_note\`
|
|
93
|
+
- **Investigations** → \`create_note\` then \`append_to_note\` as you go
|
|
94
|
+
- **Design / architecture** → full notes, not just knowledge entries
|
|
95
|
+
- **Task summaries** → after completing a story
|
|
96
|
+
- **Daily captures** → \`daily_note\`
|
|
67
97
|
|
|
68
|
-
|
|
98
|
+
### Note Maintenance
|
|
99
|
+
- \`append_to_note\` — add progress
|
|
100
|
+
- \`update_note\` — supersede stale content
|
|
101
|
+
- \`manage_tags\` / folder tools — keep notes findable
|
|
69
102
|
|
|
70
|
-
|
|
103
|
+
## Knowledge Graph — Non-Optional
|
|
71
104
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
- **
|
|
76
|
-
- **
|
|
77
|
-
- **
|
|
105
|
+
The graph is how the wiki stays navigable. **Every note you write or edit must have at least one outbound wikilink.**
|
|
106
|
+
|
|
107
|
+
### When to Build
|
|
108
|
+
- **Session start**: call \`populate_graph\` if the graph is empty (idempotent).
|
|
109
|
+
- **Architecture decisions**: create concept nodes, link with \`related\` / \`parent\`.
|
|
110
|
+
- **Dependency discovery**: create nodes for packages, link to components using them.
|
|
111
|
+
- **Bug investigations**: link bug nodes to affected components/patterns.
|
|
112
|
+
- **Any A↔B relationship**: create the edge. The graph compounds.
|
|
78
113
|
|
|
79
114
|
### Graph Tools
|
|
80
115
|
| Tool | When to use |
|
|
81
116
|
|------|------------|
|
|
82
|
-
| \`populate_graph\` | Initialize
|
|
83
|
-
| \`create_node\` |
|
|
84
|
-
| \`create_edge\` | Link two nodes (
|
|
85
|
-
| \`query_graph\` | Search
|
|
86
|
-
| \`get_neighbors\` | Explore
|
|
87
|
-
| \`query_note_graph\` | Get
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
- **tag** — represents a tag or category
|
|
92
|
-
- **concept** — free-form concept (architecture component, pattern, decision)
|
|
93
|
-
|
|
94
|
-
### Edge Types
|
|
95
|
-
- **wikilink** — note links to another note
|
|
96
|
-
- **related** — general relationship
|
|
97
|
-
- **parent** — hierarchical (component contains sub-component)
|
|
98
|
-
- **tagged** — node is tagged with a category
|
|
99
|
-
- **custom** — any other relationship (describe in metadata)
|
|
100
|
-
|
|
101
|
-
### Example: Mapping Architecture
|
|
117
|
+
| \`populate_graph\` | Initialize from existing notes (idempotent) |
|
|
118
|
+
| \`create_node\` | Add a concept/tag/note-linked node |
|
|
119
|
+
| \`create_edge\` | Link two nodes (wikilink, related, parent, tagged, custom) |
|
|
120
|
+
| \`query_graph\` | Search by type, label, or connectivity |
|
|
121
|
+
| \`get_neighbors\` | Explore connections from a node |
|
|
122
|
+
| \`query_note_graph\` | Get subgraph around a note |
|
|
123
|
+
|
|
124
|
+
Node types: **note**, **tag**, **concept**. Edge types: **wikilink**, **related**, **parent**, **tagged**, **custom**.
|
|
125
|
+
|
|
102
126
|
\`\`\`
|
|
103
|
-
create_node({ label: "Auth Module", nodeType: "concept", workspaceId: "
|
|
104
|
-
create_node({ label: "PostgreSQL", nodeType: "concept", workspaceId: "
|
|
105
|
-
create_edge({ sourceId: authNodeId, targetId: pgNodeId, edgeType: "related", workspaceId: "
|
|
127
|
+
create_node({ label: "Auth Module", nodeType: "concept", workspaceId: "${opts.workspaceId}" })
|
|
128
|
+
create_node({ label: "PostgreSQL", nodeType: "concept", workspaceId: "${opts.workspaceId}" })
|
|
129
|
+
create_edge({ sourceId: authNodeId, targetId: pgNodeId, edgeType: "related", workspaceId: "${opts.workspaceId}" })
|
|
106
130
|
\`\`\`
|
|
107
131
|
|
|
108
132
|
## MCP Tools Reference
|
|
@@ -110,49 +134,44 @@ create_edge({ sourceId: authNodeId, targetId: pgNodeId, edgeType: "related", wor
|
|
|
110
134
|
### Session & Context
|
|
111
135
|
| Tool | When to use |
|
|
112
136
|
|------|------------|
|
|
113
|
-
| \`project_context_load\` | Session start
|
|
114
|
-
| \`session_context_resume\` | Resume
|
|
115
|
-
| \`session_log\` | Log
|
|
137
|
+
| \`project_context_load\` | Session start |
|
|
138
|
+
| \`session_context_resume\` | Resume mid-conversation |
|
|
139
|
+
| \`session_log\` | Log summary at end |
|
|
116
140
|
|
|
117
|
-
### Knowledge (
|
|
141
|
+
### Knowledge (fast capture)
|
|
118
142
|
| Tool | When to use |
|
|
119
143
|
|------|------------|
|
|
120
|
-
| \`knowledge_store\` | Store a
|
|
121
|
-
| \`recall_knowledge\` | Semantic search
|
|
122
|
-
| \`bulk_knowledge_recall\` | Recall by tag
|
|
123
|
-
| \`knowledge_snapshot\` | Export all knowledge
|
|
144
|
+
| \`knowledge_store\` | Store a single fact |
|
|
145
|
+
| \`recall_knowledge\` | Semantic search |
|
|
146
|
+
| \`bulk_knowledge_recall\` | Recall by tag pattern (e.g., \`arch/*\`) |
|
|
147
|
+
| \`knowledge_snapshot\` | Export all knowledge |
|
|
148
|
+
| \`scan_knowledge_conflicts\` | Lint: find contradictions |
|
|
124
149
|
|
|
125
|
-
### Notes (
|
|
150
|
+
### Notes (wiki pages)
|
|
126
151
|
| Tool | When to use |
|
|
127
152
|
|------|------------|
|
|
128
|
-
| \`create_note\` |
|
|
129
|
-
| \`update_note\` | Replace
|
|
130
|
-
| \`append_to_note\` | Add
|
|
131
|
-
| \`get_note\` | Read
|
|
132
|
-
| \`
|
|
133
|
-
| \`
|
|
134
|
-
| \`
|
|
135
|
-
| \`
|
|
136
|
-
| \`
|
|
137
|
-
| \`pin_note\` / \`toggle_star\` | Pin or star important notes |
|
|
153
|
+
| \`create_note\` | New page |
|
|
154
|
+
| \`update_note\` | Replace content |
|
|
155
|
+
| \`append_to_note\` | Add to existing page |
|
|
156
|
+
| \`get_note\` / \`get_note_by_title\` | Read |
|
|
157
|
+
| \`search_notes\` | FTS + semantic search |
|
|
158
|
+
| \`list_notes\` | List by folder |
|
|
159
|
+
| \`daily_note\` | Today's capture note |
|
|
160
|
+
| \`manage_tags\` | Add/remove tags |
|
|
161
|
+
| \`pin_note\` / \`toggle_star\` | Elevate importance |
|
|
138
162
|
|
|
139
163
|
### Organization
|
|
140
164
|
| Tool | When to use |
|
|
141
165
|
|------|------------|
|
|
142
|
-
| \`list_folders\` |
|
|
143
|
-
| \`create_folder\` | Create a new folder |
|
|
144
|
-
| \`move_note\` | Move note to a different folder |
|
|
166
|
+
| \`list_folders\` / \`manage_folders\` / \`move_folder\` / \`bulk_move\` | Folder + note-move ops |
|
|
145
167
|
| \`context_fetch\` | Search notes by query |
|
|
146
168
|
|
|
147
169
|
### Knowledge Graph
|
|
148
170
|
| Tool | When to use |
|
|
149
171
|
|------|------------|
|
|
150
|
-
| \`populate_graph\` | Initialize graph
|
|
151
|
-
| \`create_node\`
|
|
152
|
-
| \`
|
|
153
|
-
| \`query_graph\` | Search graph by type, label, or connectivity |
|
|
154
|
-
| \`get_neighbors\` | Explore connections from a node |
|
|
155
|
-
| \`query_note_graph\` | Get subgraph around a specific note |
|
|
172
|
+
| \`populate_graph\` | Initialize graph |
|
|
173
|
+
| \`create_node\` / \`create_edge\` | Build structure |
|
|
174
|
+
| \`query_graph\` / \`get_neighbors\` / \`query_note_graph\` | Explore |
|
|
156
175
|
|
|
157
176
|
All tools require \`workspaceId: "${opts.workspaceId}"\`.`;
|
|
158
177
|
}
|
package/dist/templates/codex.js
CHANGED
|
@@ -2,63 +2,67 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateCodexTemplate = generateCodexTemplate;
|
|
4
4
|
function generateCodexTemplate(opts) {
|
|
5
|
-
return
|
|
5
|
+
return `<!-- m-notes instructions v3 -->
|
|
6
|
+
# m-notes — Your Wiki
|
|
6
7
|
|
|
7
8
|
Server: ${opts.url}
|
|
8
9
|
Workspace: ${opts.workspaceId}
|
|
9
10
|
|
|
11
|
+
You are the author and maintainer of a living wiki. Raw sources are immutable inputs; your notes are the wiki; notes tagged \`type:config\` are the rules you follow when editing.
|
|
12
|
+
|
|
10
13
|
## Session Lifecycle
|
|
11
14
|
|
|
12
15
|
### Session Start
|
|
13
|
-
Call \`project_context_load\` with workspaceId "${opts.workspaceId}"
|
|
14
|
-
To resume
|
|
16
|
+
- Call \`project_context_load\` with workspaceId "${opts.workspaceId}".
|
|
17
|
+
- To resume, call \`session_context_resume\`.
|
|
18
|
+
- If the graph is empty, call \`populate_graph\` (idempotent).
|
|
19
|
+
- Read any notes tagged \`type:config\` before editing.
|
|
15
20
|
|
|
16
21
|
### During Work
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
- Recall before researching: \`recall_knowledge\`, \`search_notes\`.
|
|
23
|
+
- Store discoveries via \`knowledge_store\` (key: \`<category>/<name>\`, tags: [category]).
|
|
24
|
+
- When the user supplies a source (URL/paste/file), run the **ingest loop**:
|
|
25
|
+
1. \`search_notes\` + \`query_graph\` to find 3–15 related notes
|
|
26
|
+
2. Plan creates/updates with \`[[wikilinks]]\` connecting touched notes
|
|
27
|
+
3. Apply — each touched note gets a \`source/<slug>\` tag
|
|
28
|
+
- Periodically run the **lint loop**: \`scan_knowledge_conflicts\`, find orphans via \`query_note_graph\`, fix broken \`[[wikilinks]]\`, update stale notes.
|
|
29
|
+
- Every new or edited note must have at least one outbound \`[[wikilink]]\`.
|
|
22
30
|
|
|
23
31
|
### Key Naming Conventions
|
|
24
|
-
- arch/{component} -- architecture decisions
|
|
32
|
+
- arch/{component} -- architecture decisions
|
|
25
33
|
- pattern/{name} -- code patterns and idioms
|
|
26
|
-
- bug/{id} -- bug investigations
|
|
27
|
-
- dep/{package} -- dependency notes
|
|
28
|
-
- decision/{topic} -- product/tech decisions
|
|
29
|
-
- context/{area} --
|
|
34
|
+
- bug/{id} -- bug investigations
|
|
35
|
+
- dep/{package} -- dependency notes
|
|
36
|
+
- decision/{topic} -- product/tech decisions
|
|
37
|
+
- context/{area} -- domain knowledge
|
|
30
38
|
|
|
31
39
|
### Session End
|
|
32
|
-
Call \`session_log\` with workspaceId "${opts.workspaceId}",
|
|
40
|
+
- Call \`session_log\` with workspaceId "${opts.workspaceId}", summary, decisions, actions.
|
|
33
41
|
|
|
34
42
|
## Knowledge Graph
|
|
35
43
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
### When to Build
|
|
39
|
-
- Session start: call \`populate_graph\` if graph is empty (idempotent)
|
|
40
|
-
- When you discover relationships between components, patterns, or decisions: create nodes and edges
|
|
41
|
-
- Architecture decisions: create concept nodes, link with "related" or "parent" edges
|
|
44
|
+
Every note belongs to the graph. Build relationships proactively.
|
|
42
45
|
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
- Node types: note, tag, concept
|
|
47
|
+
- Edge types: wikilink, related, parent, tagged, custom
|
|
45
48
|
|
|
46
49
|
Example:
|
|
47
50
|
create_node({ label: "Auth Module", nodeType: "concept", workspaceId: "${opts.workspaceId}" })
|
|
48
51
|
create_edge({ sourceId: "...", targetId: "...", edgeType: "related", workspaceId: "${opts.workspaceId}" })
|
|
49
52
|
|
|
50
53
|
## Available MCP Tools
|
|
51
|
-
- project_context_load -- load
|
|
52
|
-
- session_context_resume -- resume
|
|
53
|
-
- knowledge_store -- store knowledge
|
|
54
|
-
- recall_knowledge -- semantic search
|
|
55
|
-
- bulk_knowledge_recall -- recall by tag
|
|
54
|
+
- project_context_load -- load context at session start
|
|
55
|
+
- session_context_resume -- resume previous session
|
|
56
|
+
- knowledge_store -- store knowledge entry
|
|
57
|
+
- recall_knowledge -- semantic search
|
|
58
|
+
- bulk_knowledge_recall -- recall by tag pattern
|
|
56
59
|
- knowledge_snapshot -- export all knowledge
|
|
60
|
+
- scan_knowledge_conflicts -- lint for contradictions
|
|
57
61
|
- session_log -- log session summary
|
|
62
|
+
- create_note / update_note / append_to_note -- note authoring
|
|
63
|
+
- search_notes / get_note / list_notes -- note retrieval
|
|
58
64
|
- context_fetch -- search notes by query
|
|
59
|
-
- populate_graph -- initialize
|
|
60
|
-
- create_node
|
|
61
|
-
-
|
|
62
|
-
- query_graph -- search graph by type, label, or connectivity
|
|
63
|
-
- get_neighbors -- explore connections from a node`;
|
|
65
|
+
- populate_graph -- initialize graph (idempotent)
|
|
66
|
+
- create_node / create_edge -- build graph structure
|
|
67
|
+
- query_graph / get_neighbors / query_note_graph -- explore graph`;
|
|
64
68
|
}
|
|
@@ -2,11 +2,20 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateOpenClawTemplate = generateOpenClawTemplate;
|
|
4
4
|
function generateOpenClawTemplate(opts) {
|
|
5
|
-
return
|
|
5
|
+
return `<!-- m-notes instructions v3 -->
|
|
6
|
+
# m-notes — Your Wiki
|
|
6
7
|
|
|
7
8
|
**Server**: ${opts.url}
|
|
8
9
|
**Workspace**: ${opts.workspaceId}
|
|
9
10
|
|
|
11
|
+
You are the author of a living wiki. Notes are interlinked with \`[[wikilinks]]\`. Sources are immutable; your writing is the wiki.
|
|
12
|
+
|
|
13
|
+
## Core Loops
|
|
14
|
+
|
|
15
|
+
**Ingest** — when given a source (URL/paste): find 3+ related notes via \`recall_knowledge\`, update or create, link them with \`[[wikilinks]]\`, tag each with \`source/<slug>\`.
|
|
16
|
+
|
|
17
|
+
**Lint** — periodically check for contradictions, orphan notes, broken wikilinks, stale entries.
|
|
18
|
+
|
|
10
19
|
## Quick Reference
|
|
11
20
|
|
|
12
21
|
Store knowledge:
|
|
@@ -33,11 +42,11 @@ Call recall_knowledge with:
|
|
|
33
42
|
|
|
34
43
|
## Knowledge Graph
|
|
35
44
|
|
|
36
|
-
|
|
45
|
+
Every note should link to at least one other. Build the graph proactively:
|
|
37
46
|
\`\`\`
|
|
38
47
|
Call populate_graph with:
|
|
39
48
|
- workspaceId: "${opts.workspaceId}"
|
|
40
|
-
(initializes
|
|
49
|
+
(initializes from existing notes — idempotent)
|
|
41
50
|
|
|
42
51
|
Call create_node with:
|
|
43
52
|
- label: "<concept name>"
|
|
@@ -52,14 +61,14 @@ Call create_edge with:
|
|
|
52
61
|
\`\`\`
|
|
53
62
|
|
|
54
63
|
## Available MCP Tools
|
|
55
|
-
- \`knowledge_store\` -- Store knowledge
|
|
56
|
-
- \`recall_knowledge\` -- Semantic search
|
|
57
|
-
- \`bulk_knowledge_recall\` -- Recall by tag
|
|
64
|
+
- \`knowledge_store\` -- Store knowledge
|
|
65
|
+
- \`recall_knowledge\` -- Semantic search
|
|
66
|
+
- \`bulk_knowledge_recall\` -- Recall by tag pattern
|
|
58
67
|
- \`knowledge_snapshot\` -- Export all knowledge
|
|
59
|
-
- \`
|
|
60
|
-
- \`
|
|
61
|
-
- \`
|
|
62
|
-
- \`
|
|
63
|
-
- \`
|
|
64
|
-
- \`get_neighbors\` -- Explore
|
|
68
|
+
- \`scan_knowledge_conflicts\` -- Lint: find contradictions
|
|
69
|
+
- \`context_fetch\` / \`search_notes\` -- Search notes
|
|
70
|
+
- \`create_note\` / \`update_note\` / \`append_to_note\` -- Note authoring
|
|
71
|
+
- \`populate_graph\` -- Initialize graph
|
|
72
|
+
- \`create_node\` / \`create_edge\` -- Build graph structure
|
|
73
|
+
- \`query_graph\` / \`get_neighbors\` / \`query_note_graph\` -- Explore graph`;
|
|
65
74
|
}
|