mnotes-cli 1.7.1 → 1.9.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/client.d.ts +25 -0
- package/dist/client.js +17 -0
- package/dist/commands/recall-knowledge.d.ts +2 -0
- package/dist/commands/recall-knowledge.js +36 -0
- package/dist/index.js +2 -0
- package/dist/output.d.ts +13 -0
- package/dist/output.js +29 -0
- package/dist/templates/claude-code.js +50 -0
- package/dist/templates/codex.js +22 -1
- package/dist/templates/openclaw.js +26 -1
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -72,6 +72,31 @@ export declare function createClient(baseUrl: string, apiKey: string): {
|
|
|
72
72
|
isDefault: boolean;
|
|
73
73
|
}>;
|
|
74
74
|
}>;
|
|
75
|
+
queryGraph(opts?: {
|
|
76
|
+
workspaceId?: string;
|
|
77
|
+
query?: string;
|
|
78
|
+
nodeType?: string;
|
|
79
|
+
neighbors?: string;
|
|
80
|
+
depth?: number;
|
|
81
|
+
limit?: number;
|
|
82
|
+
}): Promise<{
|
|
83
|
+
data: {
|
|
84
|
+
nodes: Array<{
|
|
85
|
+
id: string;
|
|
86
|
+
noteId: string | null;
|
|
87
|
+
label: string;
|
|
88
|
+
nodeType: string;
|
|
89
|
+
depth?: number;
|
|
90
|
+
}>;
|
|
91
|
+
edges: Array<{
|
|
92
|
+
id: string;
|
|
93
|
+
sourceId: string;
|
|
94
|
+
targetId: string;
|
|
95
|
+
edgeType: string;
|
|
96
|
+
weight: number;
|
|
97
|
+
}>;
|
|
98
|
+
};
|
|
99
|
+
}>;
|
|
75
100
|
createWorkspace(name: string): Promise<{
|
|
76
101
|
data: {
|
|
77
102
|
id: string;
|
package/dist/client.js
CHANGED
|
@@ -51,6 +51,23 @@ function createClient(baseUrl, apiKey) {
|
|
|
51
51
|
async listWorkspaces() {
|
|
52
52
|
return request("GET", "/api/v1/workspaces");
|
|
53
53
|
},
|
|
54
|
+
async queryGraph(opts) {
|
|
55
|
+
const params = new URLSearchParams();
|
|
56
|
+
if (opts?.workspaceId)
|
|
57
|
+
params.set("workspaceId", opts.workspaceId);
|
|
58
|
+
if (opts?.query)
|
|
59
|
+
params.set("query", opts.query);
|
|
60
|
+
if (opts?.nodeType)
|
|
61
|
+
params.set("nodeType", opts.nodeType);
|
|
62
|
+
if (opts?.neighbors)
|
|
63
|
+
params.set("neighbors", opts.neighbors);
|
|
64
|
+
if (opts?.depth)
|
|
65
|
+
params.set("depth", String(opts.depth));
|
|
66
|
+
if (opts?.limit)
|
|
67
|
+
params.set("limit", String(opts.limit));
|
|
68
|
+
const qs = params.toString();
|
|
69
|
+
return request("GET", `/api/v1/graph${qs ? `?${qs}` : ""}`);
|
|
70
|
+
},
|
|
54
71
|
async createWorkspace(name) {
|
|
55
72
|
return request("POST", "/api/v1/workspaces", { name });
|
|
56
73
|
},
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerRecallKnowledgeCommand = registerRecallKnowledgeCommand;
|
|
4
|
+
const config_1 = require("../config");
|
|
5
|
+
const client_1 = require("../client");
|
|
6
|
+
const output_1 = require("../output");
|
|
7
|
+
function registerRecallKnowledgeCommand(program) {
|
|
8
|
+
program
|
|
9
|
+
.command("recall_knowledge")
|
|
10
|
+
.description("Query the knowledge graph (read-only)")
|
|
11
|
+
.option("--query <text>", "Filter nodes by label (case-insensitive)")
|
|
12
|
+
.option("--type <type>", "Filter by node type: note, tag, concept")
|
|
13
|
+
.option("--neighbors <nodeId>", "Show neighbors of a specific node")
|
|
14
|
+
.option("--depth <n>", "Neighbor traversal depth (1-3, default 1)", "1")
|
|
15
|
+
.option("--limit <n>", "Max nodes to return (default 50)", "50")
|
|
16
|
+
.option("--workspace-id <id>", "Workspace ID")
|
|
17
|
+
.action(async (opts) => {
|
|
18
|
+
const globalOpts = program.opts();
|
|
19
|
+
const config = (0, config_1.resolveConfig)(globalOpts);
|
|
20
|
+
const client = (0, client_1.createClient)(config.baseUrl, config.apiKey);
|
|
21
|
+
const result = await client.queryGraph({
|
|
22
|
+
workspaceId: opts.workspaceId || config.workspaceId,
|
|
23
|
+
query: opts.query,
|
|
24
|
+
nodeType: opts.type,
|
|
25
|
+
neighbors: opts.neighbors,
|
|
26
|
+
depth: opts.depth ? parseInt(opts.depth, 10) : undefined,
|
|
27
|
+
limit: opts.limit ? parseInt(opts.limit, 10) : undefined,
|
|
28
|
+
});
|
|
29
|
+
if (globalOpts.json) {
|
|
30
|
+
(0, output_1.printJson)(result.data);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
(0, output_1.printGraph)(result.data.nodes, result.data.edges);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,7 @@ const delete_1 = require("./commands/delete");
|
|
|
11
11
|
const connect_1 = require("./commands/connect");
|
|
12
12
|
const login_1 = require("./commands/login");
|
|
13
13
|
const workspace_1 = require("./commands/workspace");
|
|
14
|
+
const recall_knowledge_1 = require("./commands/recall-knowledge");
|
|
14
15
|
const program = new commander_1.Command();
|
|
15
16
|
program
|
|
16
17
|
.name("mnotes")
|
|
@@ -28,6 +29,7 @@ program
|
|
|
28
29
|
(0, connect_1.registerConnectCommand)(program);
|
|
29
30
|
(0, login_1.registerLoginCommand)(program);
|
|
30
31
|
(0, workspace_1.registerWorkspaceCommand)(program);
|
|
32
|
+
(0, recall_knowledge_1.registerRecallKnowledgeCommand)(program);
|
|
31
33
|
program.parseAsync(process.argv).catch((err) => {
|
|
32
34
|
process.stderr.write(`Error: ${err.message}\n`);
|
|
33
35
|
process.exit(1);
|
package/dist/output.d.ts
CHANGED
|
@@ -14,4 +14,17 @@ export declare function printSearchResults(results: Array<{
|
|
|
14
14
|
title: string;
|
|
15
15
|
snippet?: string;
|
|
16
16
|
}>): void;
|
|
17
|
+
export declare function printGraph(nodes: Array<{
|
|
18
|
+
id: string;
|
|
19
|
+
noteId: string | null;
|
|
20
|
+
label: string;
|
|
21
|
+
nodeType: string;
|
|
22
|
+
depth?: number;
|
|
23
|
+
}>, edges: Array<{
|
|
24
|
+
id: string;
|
|
25
|
+
sourceId: string;
|
|
26
|
+
targetId: string;
|
|
27
|
+
edgeType: string;
|
|
28
|
+
weight: number;
|
|
29
|
+
}>): void;
|
|
17
30
|
export declare function printSuccess(msg: string): void;
|
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.printGraph = printGraph;
|
|
7
8
|
exports.printSuccess = printSuccess;
|
|
8
9
|
function printJson(data) {
|
|
9
10
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -42,6 +43,34 @@ function printSearchResults(results) {
|
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
}
|
|
46
|
+
function printGraph(nodes, edges) {
|
|
47
|
+
if (nodes.length === 0) {
|
|
48
|
+
process.stderr.write("Knowledge graph is empty.\n");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const idWidth = Math.max(4, ...nodes.map((n) => n.id.length));
|
|
52
|
+
const typeWidth = Math.max(4, ...nodes.map((n) => n.nodeType.length));
|
|
53
|
+
const labelWidth = Math.min(50, Math.max(5, ...nodes.map((n) => n.label.length)));
|
|
54
|
+
console.log(`${"ID".padEnd(idWidth)} ${"TYPE".padEnd(typeWidth)} LABEL`);
|
|
55
|
+
for (const node of nodes) {
|
|
56
|
+
const label = node.label.length > labelWidth
|
|
57
|
+
? node.label.substring(0, labelWidth - 1) + "…"
|
|
58
|
+
: node.label;
|
|
59
|
+
const depthSuffix = node.depth !== undefined && node.depth > 0 ? ` (depth ${node.depth})` : "";
|
|
60
|
+
console.log(`${node.id.padEnd(idWidth)} ${node.nodeType.padEnd(typeWidth)} ${label}${depthSuffix}`);
|
|
61
|
+
}
|
|
62
|
+
if (edges.length > 0) {
|
|
63
|
+
console.log("");
|
|
64
|
+
console.log(`Edges (${edges.length}):`);
|
|
65
|
+
for (const edge of edges) {
|
|
66
|
+
const srcLabel = nodes.find((n) => n.id === edge.sourceId)?.label ?? edge.sourceId;
|
|
67
|
+
const tgtLabel = nodes.find((n) => n.id === edge.targetId)?.label ?? edge.targetId;
|
|
68
|
+
console.log(` ${srcLabel} --[${edge.edgeType}]--> ${tgtLabel}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
console.log("");
|
|
72
|
+
console.log(`${nodes.length} node(s), ${edges.length} edge(s)`);
|
|
73
|
+
}
|
|
45
74
|
function printSuccess(msg) {
|
|
46
75
|
process.stderr.write(`${msg}\n`);
|
|
47
76
|
}
|
|
@@ -65,6 +65,46 @@ m-notes is not just a knowledge base — it's a full note-taking system. **Use n
|
|
|
65
65
|
|
|
66
66
|
**When in doubt, create a note.** Notes are searchable, linkable, and visible in the UI.
|
|
67
67
|
|
|
68
|
+
## Knowledge Graph — Build Structured Memory
|
|
69
|
+
|
|
70
|
+
Beyond flat knowledge entries, you have a **knowledge graph** for structured relationships between concepts. Use it to map how things connect — architecture components, dependencies, decisions, and patterns.
|
|
71
|
+
|
|
72
|
+
### When to Build the Graph
|
|
73
|
+
- **Session start**: If the graph is empty, call \`populate_graph\` to initialize from existing notes and wikilinks.
|
|
74
|
+
- **Architecture decisions**: Create concept nodes for components, link them with "related" or "parent" edges.
|
|
75
|
+
- **Dependency discovery**: Create nodes for packages, link to the components that use them.
|
|
76
|
+
- **Bug investigations**: Link bug nodes to the components and patterns involved.
|
|
77
|
+
- **Any time you see a relationship**: If A relates to B, create an edge. The graph gets more valuable over time.
|
|
78
|
+
|
|
79
|
+
### Graph Tools
|
|
80
|
+
| Tool | When to use |
|
|
81
|
+
|------|------------|
|
|
82
|
+
| \`populate_graph\` | Initialize graph from existing notes (idempotent, safe to re-run) |
|
|
83
|
+
| \`create_node\` | Create a concept, tag, or note-linked node |
|
|
84
|
+
| \`create_edge\` | Link two nodes (types: wikilink, related, parent, tagged, custom) |
|
|
85
|
+
| \`query_graph\` | Search the graph by node type, label, or connectivity |
|
|
86
|
+
| \`get_neighbors\` | Explore nodes connected to a specific node |
|
|
87
|
+
| \`query_note_graph\` | Get the connection subgraph around a note |
|
|
88
|
+
|
|
89
|
+
### Node Types
|
|
90
|
+
- **note** — linked to an existing note (set \`noteId\`)
|
|
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
|
|
102
|
+
\`\`\`
|
|
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: "..." })
|
|
106
|
+
\`\`\`
|
|
107
|
+
|
|
68
108
|
## MCP Tools Reference
|
|
69
109
|
|
|
70
110
|
### Session & Context
|
|
@@ -104,5 +144,15 @@ m-notes is not just a knowledge base — it's a full note-taking system. **Use n
|
|
|
104
144
|
| \`move_note\` | Move note to a different folder |
|
|
105
145
|
| \`context_fetch\` | Search notes by query |
|
|
106
146
|
|
|
147
|
+
### Knowledge Graph
|
|
148
|
+
| Tool | When to use |
|
|
149
|
+
|------|------------|
|
|
150
|
+
| \`populate_graph\` | Initialize graph from notes (run once at start) |
|
|
151
|
+
| \`create_node\` | Add a concept, tag, or note-linked node |
|
|
152
|
+
| \`create_edge\` | Link two nodes with a typed relationship |
|
|
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 |
|
|
156
|
+
|
|
107
157
|
All tools require \`workspaceId: "${opts.workspaceId}"\`.`;
|
|
108
158
|
}
|
package/dist/templates/codex.js
CHANGED
|
@@ -31,6 +31,22 @@ Store discoveries, decisions, and patterns via \`knowledge_store\`:
|
|
|
31
31
|
### Session End
|
|
32
32
|
Call \`session_log\` with workspaceId "${opts.workspaceId}", a summary, decisions, and actions.
|
|
33
33
|
|
|
34
|
+
## Knowledge Graph
|
|
35
|
+
|
|
36
|
+
Build structured relationships between concepts as you work. The graph maps how architecture components, dependencies, decisions, and patterns connect.
|
|
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
|
|
42
|
+
|
|
43
|
+
### Node types: note, tag, concept
|
|
44
|
+
### Edge types: wikilink, related, parent, tagged, custom
|
|
45
|
+
|
|
46
|
+
Example:
|
|
47
|
+
create_node({ label: "Auth Module", nodeType: "concept", workspaceId: "${opts.workspaceId}" })
|
|
48
|
+
create_edge({ sourceId: "...", targetId: "...", edgeType: "related", workspaceId: "${opts.workspaceId}" })
|
|
49
|
+
|
|
34
50
|
## Available MCP Tools
|
|
35
51
|
- project_context_load -- load project context at session start
|
|
36
52
|
- session_context_resume -- resume from previous session
|
|
@@ -39,5 +55,10 @@ Call \`session_log\` with workspaceId "${opts.workspaceId}", a summary, decision
|
|
|
39
55
|
- bulk_knowledge_recall -- recall by tag patterns
|
|
40
56
|
- knowledge_snapshot -- export all knowledge
|
|
41
57
|
- session_log -- log session summary
|
|
42
|
-
- context_fetch -- search notes by query
|
|
58
|
+
- context_fetch -- search notes by query
|
|
59
|
+
- populate_graph -- initialize knowledge graph from notes
|
|
60
|
+
- create_node -- add a concept/tag/note node to the graph
|
|
61
|
+
- create_edge -- link two nodes with a typed relationship
|
|
62
|
+
- query_graph -- search graph by type, label, or connectivity
|
|
63
|
+
- get_neighbors -- explore connections from a node`;
|
|
43
64
|
}
|
|
@@ -31,10 +31,35 @@ Call recall_knowledge with:
|
|
|
31
31
|
- \`bug/{id}\` -- bug investigations
|
|
32
32
|
- \`pattern/{name}\` -- code patterns
|
|
33
33
|
|
|
34
|
+
## Knowledge Graph
|
|
35
|
+
|
|
36
|
+
Build structured relationships as you work:
|
|
37
|
+
\`\`\`
|
|
38
|
+
Call populate_graph with:
|
|
39
|
+
- workspaceId: "${opts.workspaceId}"
|
|
40
|
+
(initializes graph from existing notes — run once)
|
|
41
|
+
|
|
42
|
+
Call create_node with:
|
|
43
|
+
- label: "<concept name>"
|
|
44
|
+
- nodeType: "concept" (or "note", "tag")
|
|
45
|
+
- workspaceId: "${opts.workspaceId}"
|
|
46
|
+
|
|
47
|
+
Call create_edge with:
|
|
48
|
+
- sourceId: "<node id>"
|
|
49
|
+
- targetId: "<node id>"
|
|
50
|
+
- edgeType: "related" (or "parent", "tagged", "custom")
|
|
51
|
+
- workspaceId: "${opts.workspaceId}"
|
|
52
|
+
\`\`\`
|
|
53
|
+
|
|
34
54
|
## Available MCP Tools
|
|
35
55
|
- \`knowledge_store\` -- Store knowledge entries
|
|
36
56
|
- \`recall_knowledge\` -- Semantic search for knowledge
|
|
37
57
|
- \`bulk_knowledge_recall\` -- Recall by tag patterns
|
|
38
58
|
- \`knowledge_snapshot\` -- Export all knowledge
|
|
39
|
-
- \`context_fetch\` -- Search notes by query
|
|
59
|
+
- \`context_fetch\` -- Search notes by query
|
|
60
|
+
- \`populate_graph\` -- Initialize knowledge graph from notes
|
|
61
|
+
- \`create_node\` -- Add concept/tag/note node to the graph
|
|
62
|
+
- \`create_edge\` -- Link two nodes with a typed relationship
|
|
63
|
+
- \`query_graph\` -- Search graph by type, label, or connectivity
|
|
64
|
+
- \`get_neighbors\` -- Explore connections from a node`;
|
|
40
65
|
}
|