@weavelogic/knowledge-graph-agent 0.1.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 +264 -0
- package/dist/cli/bin.d.ts +8 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +20 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/commands/claude.d.ts +11 -0
- package/dist/cli/commands/claude.d.ts.map +1 -0
- package/dist/cli/commands/claude.js +102 -0
- package/dist/cli/commands/claude.js.map +1 -0
- package/dist/cli/commands/docs.d.ts +11 -0
- package/dist/cli/commands/docs.d.ts.map +1 -0
- package/dist/cli/commands/docs.js +108 -0
- package/dist/cli/commands/docs.js.map +1 -0
- package/dist/cli/commands/graph.d.ts +11 -0
- package/dist/cli/commands/graph.d.ts.map +1 -0
- package/dist/cli/commands/graph.js +122 -0
- package/dist/cli/commands/graph.js.map +1 -0
- package/dist/cli/commands/init.d.ts +11 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +80 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/search.d.ts +11 -0
- package/dist/cli/commands/search.d.ts.map +1 -0
- package/dist/cli/commands/search.js +80 -0
- package/dist/cli/commands/search.js.map +1 -0
- package/dist/cli/commands/stats.d.ts +11 -0
- package/dist/cli/commands/stats.d.ts.map +1 -0
- package/dist/cli/commands/stats.js +84 -0
- package/dist/cli/commands/stats.js.map +1 -0
- package/dist/cli/commands/sync.d.ts +11 -0
- package/dist/cli/commands/sync.d.ts.map +1 -0
- package/dist/cli/commands/sync.js +76 -0
- package/dist/cli/commands/sync.js.map +1 -0
- package/dist/cli/index.d.ts +11 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +45 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/database.d.ts +121 -0
- package/dist/core/database.d.ts.map +1 -0
- package/dist/core/database.js +470 -0
- package/dist/core/database.js.map +1 -0
- package/dist/core/graph.d.ts +109 -0
- package/dist/core/graph.d.ts.map +1 -0
- package/dist/core/graph.js +343 -0
- package/dist/core/graph.js.map +1 -0
- package/dist/core/security.d.ts +62 -0
- package/dist/core/security.d.ts.map +1 -0
- package/dist/core/security.js +31 -0
- package/dist/core/security.js.map +1 -0
- package/dist/core/types.d.ts +232 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +37 -0
- package/dist/core/types.js.map +1 -0
- package/dist/generators/claude-md.d.ts +33 -0
- package/dist/generators/claude-md.d.ts.map +1 -0
- package/dist/generators/claude-md.js +410 -0
- package/dist/generators/claude-md.js.map +1 -0
- package/dist/generators/docs-init.d.ts +20 -0
- package/dist/generators/docs-init.d.ts.map +1 -0
- package/dist/generators/docs-init.js +625 -0
- package/dist/generators/docs-init.js.map +1 -0
- package/dist/generators/graph-generator.d.ts +41 -0
- package/dist/generators/graph-generator.d.ts.map +1 -0
- package/dist/generators/graph-generator.js +266 -0
- package/dist/generators/graph-generator.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +99 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/claude-flow.d.ts +62 -0
- package/dist/integrations/claude-flow.d.ts.map +1 -0
- package/dist/integrations/claude-flow.js +243 -0
- package/dist/integrations/claude-flow.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge Graph Generator
|
|
3
|
+
*
|
|
4
|
+
* Scans documentation and generates a knowledge graph from markdown files.
|
|
5
|
+
*/
|
|
6
|
+
import type { GeneratorOptions } from '../core/types.js';
|
|
7
|
+
import { KnowledgeGraphManager } from '../core/graph.js';
|
|
8
|
+
/**
|
|
9
|
+
* Generate knowledge graph from docs directory
|
|
10
|
+
*/
|
|
11
|
+
export declare function generateGraph(options: GeneratorOptions): Promise<{
|
|
12
|
+
graph: KnowledgeGraphManager;
|
|
13
|
+
stats: {
|
|
14
|
+
filesScanned: number;
|
|
15
|
+
nodesCreated: number;
|
|
16
|
+
edgesCreated: number;
|
|
17
|
+
errors: string[];
|
|
18
|
+
};
|
|
19
|
+
}>;
|
|
20
|
+
/**
|
|
21
|
+
* Generate graph and save to database
|
|
22
|
+
*/
|
|
23
|
+
export declare function generateAndSave(options: GeneratorOptions, dbPath: string): Promise<{
|
|
24
|
+
success: boolean;
|
|
25
|
+
stats: {
|
|
26
|
+
filesScanned: number;
|
|
27
|
+
nodesCreated: number;
|
|
28
|
+
edgesCreated: number;
|
|
29
|
+
errors: string[];
|
|
30
|
+
};
|
|
31
|
+
}>;
|
|
32
|
+
/**
|
|
33
|
+
* Generate graph from existing database (incremental update)
|
|
34
|
+
*/
|
|
35
|
+
export declare function updateGraph(dbPath: string, docsRoot: string): Promise<{
|
|
36
|
+
added: number;
|
|
37
|
+
updated: number;
|
|
38
|
+
removed: number;
|
|
39
|
+
errors: string[];
|
|
40
|
+
}>;
|
|
41
|
+
//# sourceMappingURL=graph-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-generator.d.ts","sourceRoot":"","sources":["../../src/generators/graph-generator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAMV,gBAAgB,EAEjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AASzD;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC;IACtE,KAAK,EAAE,qBAAqB,CAAC;IAC7B,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;CACH,CAAC,CAwED;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;CACH,CAAC,CA6BD;AAgND;;GAEG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC,CA4DD"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { readFileSync, statSync } from "fs";
|
|
2
|
+
import { join, basename, relative } from "path";
|
|
3
|
+
import fg from "fast-glob";
|
|
4
|
+
import matter from "gray-matter";
|
|
5
|
+
import { KnowledgeGraphManager } from "../core/graph.js";
|
|
6
|
+
import { KnowledgeGraphDatabase } from "../core/database.js";
|
|
7
|
+
const WIKILINK_PATTERN = /\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g;
|
|
8
|
+
const MARKDOWN_LINK_PATTERN = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
9
|
+
async function generateGraph(options) {
|
|
10
|
+
const { projectRoot, outputPath } = options;
|
|
11
|
+
const stats = {
|
|
12
|
+
filesScanned: 0,
|
|
13
|
+
nodesCreated: 0,
|
|
14
|
+
edgesCreated: 0,
|
|
15
|
+
errors: []
|
|
16
|
+
};
|
|
17
|
+
const graph = new KnowledgeGraphManager(
|
|
18
|
+
basename(projectRoot),
|
|
19
|
+
projectRoot
|
|
20
|
+
);
|
|
21
|
+
const files = await fg("**/*.md", {
|
|
22
|
+
cwd: outputPath,
|
|
23
|
+
ignore: ["node_modules/**", ".git/**", "_templates/**"],
|
|
24
|
+
absolute: true
|
|
25
|
+
});
|
|
26
|
+
stats.filesScanned = files.length;
|
|
27
|
+
const nodeMap = /* @__PURE__ */ new Map();
|
|
28
|
+
for (const filePath of files) {
|
|
29
|
+
try {
|
|
30
|
+
const node = await parseMarkdownFile(filePath, outputPath);
|
|
31
|
+
nodeMap.set(node.id, node);
|
|
32
|
+
stats.nodesCreated++;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
stats.errors.push(`Failed to parse ${filePath}: ${error}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
for (const node of nodeMap.values()) {
|
|
38
|
+
const resolvedLinks = [];
|
|
39
|
+
for (const link of node.outgoingLinks) {
|
|
40
|
+
const targetId = resolveLink(link.target, node.path, nodeMap);
|
|
41
|
+
if (targetId) {
|
|
42
|
+
resolvedLinks.push({
|
|
43
|
+
...link,
|
|
44
|
+
target: targetId
|
|
45
|
+
});
|
|
46
|
+
const targetNode = nodeMap.get(targetId);
|
|
47
|
+
if (targetNode) {
|
|
48
|
+
targetNode.incomingLinks.push({
|
|
49
|
+
target: node.id,
|
|
50
|
+
type: "backlink",
|
|
51
|
+
text: node.title
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
stats.edgesCreated++;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
node.outgoingLinks = resolvedLinks;
|
|
58
|
+
graph.addNode(node);
|
|
59
|
+
}
|
|
60
|
+
return { graph, stats };
|
|
61
|
+
}
|
|
62
|
+
async function generateAndSave(options, dbPath) {
|
|
63
|
+
const { graph, stats } = await generateGraph(options);
|
|
64
|
+
const db = new KnowledgeGraphDatabase(dbPath);
|
|
65
|
+
try {
|
|
66
|
+
const nodes = graph.getAllNodes();
|
|
67
|
+
const edges = graph.getAllEdges();
|
|
68
|
+
for (const node of nodes) {
|
|
69
|
+
db.upsertNode(node);
|
|
70
|
+
}
|
|
71
|
+
for (const edge of edges) {
|
|
72
|
+
db.addEdge(edge);
|
|
73
|
+
}
|
|
74
|
+
db.setMetadata("lastGenerated", (/* @__PURE__ */ new Date()).toISOString());
|
|
75
|
+
db.setMetadata("nodeCount", String(stats.nodesCreated));
|
|
76
|
+
db.setMetadata("edgeCount", String(stats.edgesCreated));
|
|
77
|
+
return { success: true, stats };
|
|
78
|
+
} catch (error) {
|
|
79
|
+
stats.errors.push(`Database error: ${error}`);
|
|
80
|
+
return { success: false, stats };
|
|
81
|
+
} finally {
|
|
82
|
+
db.close();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async function parseMarkdownFile(filePath, docsRoot) {
|
|
86
|
+
const content = readFileSync(filePath, "utf-8");
|
|
87
|
+
const stat = statSync(filePath);
|
|
88
|
+
const { data, content: body } = matter(content);
|
|
89
|
+
const filename = basename(filePath, ".md");
|
|
90
|
+
const relativePath = relative(docsRoot, filePath);
|
|
91
|
+
const id = relativePath.replace(/\.md$/, "").replace(/\\/g, "/").replace(/[^a-z0-9/]+/gi, "-").toLowerCase();
|
|
92
|
+
const outgoingLinks = extractLinks(body);
|
|
93
|
+
const type = inferNodeType(data.type, relativePath);
|
|
94
|
+
const status = data.status || "active";
|
|
95
|
+
const frontmatter = {
|
|
96
|
+
title: data.title || formatTitle(filename),
|
|
97
|
+
type,
|
|
98
|
+
status,
|
|
99
|
+
tags: Array.isArray(data.tags) ? data.tags : [],
|
|
100
|
+
category: data.category,
|
|
101
|
+
description: data.description,
|
|
102
|
+
created: data.created || stat.birthtime.toISOString().split("T")[0],
|
|
103
|
+
updated: data.updated || stat.mtime.toISOString().split("T")[0],
|
|
104
|
+
aliases: data.aliases,
|
|
105
|
+
related: data.related,
|
|
106
|
+
...data
|
|
107
|
+
};
|
|
108
|
+
const wordCount = body.replace(/[#*`\[\]()]/g, "").split(/\s+/).filter(Boolean).length;
|
|
109
|
+
return {
|
|
110
|
+
id,
|
|
111
|
+
path: relativePath,
|
|
112
|
+
filename,
|
|
113
|
+
title: frontmatter.title || formatTitle(filename),
|
|
114
|
+
type,
|
|
115
|
+
status,
|
|
116
|
+
content: body,
|
|
117
|
+
frontmatter,
|
|
118
|
+
tags: frontmatter.tags || [],
|
|
119
|
+
outgoingLinks,
|
|
120
|
+
incomingLinks: [],
|
|
121
|
+
// Will be filled in second pass
|
|
122
|
+
wordCount,
|
|
123
|
+
lastModified: stat.mtime
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function extractLinks(content) {
|
|
127
|
+
const links = [];
|
|
128
|
+
const seen = /* @__PURE__ */ new Set();
|
|
129
|
+
let match;
|
|
130
|
+
while ((match = WIKILINK_PATTERN.exec(content)) !== null) {
|
|
131
|
+
const target = match[1].trim();
|
|
132
|
+
const text = match[2]?.trim();
|
|
133
|
+
if (!seen.has(target)) {
|
|
134
|
+
seen.add(target);
|
|
135
|
+
links.push({
|
|
136
|
+
target,
|
|
137
|
+
type: "wikilink",
|
|
138
|
+
text
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
while ((match = MARKDOWN_LINK_PATTERN.exec(content)) !== null) {
|
|
143
|
+
const text = match[1].trim();
|
|
144
|
+
const target = match[2].trim();
|
|
145
|
+
if (target.startsWith("http://") || target.startsWith("https://")) {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (!seen.has(target)) {
|
|
149
|
+
seen.add(target);
|
|
150
|
+
links.push({
|
|
151
|
+
target,
|
|
152
|
+
type: "markdown",
|
|
153
|
+
text
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return links;
|
|
158
|
+
}
|
|
159
|
+
function resolveLink(target, currentPath, nodeMap) {
|
|
160
|
+
const cleanTarget = target.replace(/\.md$/, "").replace(/^\.\//, "").toLowerCase();
|
|
161
|
+
for (const [id, node] of nodeMap) {
|
|
162
|
+
if (id === cleanTarget) {
|
|
163
|
+
return id;
|
|
164
|
+
}
|
|
165
|
+
if (node.filename.toLowerCase() === cleanTarget) {
|
|
166
|
+
return id;
|
|
167
|
+
}
|
|
168
|
+
if (node.title.toLowerCase() === cleanTarget) {
|
|
169
|
+
return id;
|
|
170
|
+
}
|
|
171
|
+
if (node.frontmatter.aliases?.some(
|
|
172
|
+
(a) => a.toLowerCase() === cleanTarget
|
|
173
|
+
)) {
|
|
174
|
+
return id;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
const currentDir = currentPath.replace(/[^/]+$/, "");
|
|
178
|
+
const relativePath = join(currentDir, cleanTarget).replace(/\\/g, "/").replace(/^\//, "");
|
|
179
|
+
for (const [id, node] of nodeMap) {
|
|
180
|
+
if (id === relativePath || node.path.replace(/\.md$/, "") === relativePath) {
|
|
181
|
+
return id;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
function inferNodeType(declaredType, path) {
|
|
187
|
+
const validTypes = [
|
|
188
|
+
"concept",
|
|
189
|
+
"technical",
|
|
190
|
+
"feature",
|
|
191
|
+
"primitive",
|
|
192
|
+
"service",
|
|
193
|
+
"guide",
|
|
194
|
+
"standard",
|
|
195
|
+
"integration"
|
|
196
|
+
];
|
|
197
|
+
if (typeof declaredType === "string" && validTypes.includes(declaredType)) {
|
|
198
|
+
return declaredType;
|
|
199
|
+
}
|
|
200
|
+
const pathLower = path.toLowerCase();
|
|
201
|
+
if (pathLower.includes("concept")) return "concept";
|
|
202
|
+
if (pathLower.includes("component") || pathLower.includes("technical")) return "technical";
|
|
203
|
+
if (pathLower.includes("feature")) return "feature";
|
|
204
|
+
if (pathLower.includes("primitive") || pathLower.includes("integration")) return "primitive";
|
|
205
|
+
if (pathLower.includes("service") || pathLower.includes("api")) return "service";
|
|
206
|
+
if (pathLower.includes("guide") || pathLower.includes("tutorial")) return "guide";
|
|
207
|
+
if (pathLower.includes("standard")) return "standard";
|
|
208
|
+
if (pathLower.includes("reference")) return "technical";
|
|
209
|
+
return "concept";
|
|
210
|
+
}
|
|
211
|
+
function formatTitle(filename) {
|
|
212
|
+
return filename.replace(/-/g, " ").replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
213
|
+
}
|
|
214
|
+
async function updateGraph(dbPath, docsRoot) {
|
|
215
|
+
const result = {
|
|
216
|
+
added: 0,
|
|
217
|
+
updated: 0,
|
|
218
|
+
removed: 0,
|
|
219
|
+
errors: []
|
|
220
|
+
};
|
|
221
|
+
const db = new KnowledgeGraphDatabase(dbPath);
|
|
222
|
+
try {
|
|
223
|
+
const existingNodes = db.getAllNodes();
|
|
224
|
+
const existingPaths = new Set(existingNodes.map((n) => n.path));
|
|
225
|
+
const currentFiles = await fg("**/*.md", {
|
|
226
|
+
cwd: docsRoot,
|
|
227
|
+
ignore: ["node_modules/**", ".git/**", "_templates/**"]
|
|
228
|
+
});
|
|
229
|
+
const currentPaths = new Set(currentFiles);
|
|
230
|
+
for (const node of existingNodes) {
|
|
231
|
+
if (!currentPaths.has(node.path)) {
|
|
232
|
+
db.deleteNode(node.id);
|
|
233
|
+
result.removed++;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
for (const filePath of currentFiles) {
|
|
237
|
+
const fullPath = join(docsRoot, filePath);
|
|
238
|
+
try {
|
|
239
|
+
const node = await parseMarkdownFile(fullPath, docsRoot);
|
|
240
|
+
if (existingPaths.has(filePath)) {
|
|
241
|
+
const existing = existingNodes.find((n) => n.path === filePath);
|
|
242
|
+
if (existing && node.lastModified > existing.lastModified) {
|
|
243
|
+
db.deleteNodeEdges(node.id);
|
|
244
|
+
db.upsertNode(node);
|
|
245
|
+
result.updated++;
|
|
246
|
+
}
|
|
247
|
+
} else {
|
|
248
|
+
db.upsertNode(node);
|
|
249
|
+
result.added++;
|
|
250
|
+
}
|
|
251
|
+
} catch (error) {
|
|
252
|
+
result.errors.push(`Failed to process ${filePath}: ${error}`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
db.setMetadata("lastUpdated", (/* @__PURE__ */ new Date()).toISOString());
|
|
256
|
+
} finally {
|
|
257
|
+
db.close();
|
|
258
|
+
}
|
|
259
|
+
return result;
|
|
260
|
+
}
|
|
261
|
+
export {
|
|
262
|
+
generateAndSave,
|
|
263
|
+
generateGraph,
|
|
264
|
+
updateGraph
|
|
265
|
+
};
|
|
266
|
+
//# sourceMappingURL=graph-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-generator.js","sources":["../../src/generators/graph-generator.ts"],"sourcesContent":["/**\n * Knowledge Graph Generator\n *\n * Scans documentation and generates a knowledge graph from markdown files.\n */\n\nimport { readFileSync, statSync } from 'fs';\nimport { join, basename, relative, extname } from 'path';\nimport fg from 'fast-glob';\nimport matter from 'gray-matter';\nimport type {\n KnowledgeNode,\n NodeType,\n NodeStatus,\n NodeLink,\n NodeFrontmatter,\n GeneratorOptions,\n GeneratedDocument,\n} from '../core/types.js';\nimport { KnowledgeGraphManager } from '../core/graph.js';\nimport { KnowledgeGraphDatabase } from '../core/database.js';\n\n/**\n * Link extraction patterns\n */\nconst WIKILINK_PATTERN = /\\[\\[([^\\]|]+)(?:\\|([^\\]]+))?\\]\\]/g;\nconst MARKDOWN_LINK_PATTERN = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n\n/**\n * Generate knowledge graph from docs directory\n */\nexport async function generateGraph(options: GeneratorOptions): Promise<{\n graph: KnowledgeGraphManager;\n stats: {\n filesScanned: number;\n nodesCreated: number;\n edgesCreated: number;\n errors: string[];\n };\n}> {\n const { projectRoot, outputPath } = options;\n\n const stats = {\n filesScanned: 0,\n nodesCreated: 0,\n edgesCreated: 0,\n errors: [] as string[],\n };\n\n // Create graph manager\n const graph = new KnowledgeGraphManager(\n basename(projectRoot),\n projectRoot\n );\n\n // Find all markdown files\n const files = await fg('**/*.md', {\n cwd: outputPath,\n ignore: ['node_modules/**', '.git/**', '_templates/**'],\n absolute: true,\n });\n\n stats.filesScanned = files.length;\n\n // First pass: Create all nodes\n const nodeMap = new Map<string, KnowledgeNode>();\n\n for (const filePath of files) {\n try {\n const node = await parseMarkdownFile(filePath, outputPath);\n nodeMap.set(node.id, node);\n stats.nodesCreated++;\n } catch (error) {\n stats.errors.push(`Failed to parse ${filePath}: ${error}`);\n }\n }\n\n // Second pass: Resolve links and add to graph\n for (const node of nodeMap.values()) {\n // Resolve outgoing links\n const resolvedLinks: NodeLink[] = [];\n\n for (const link of node.outgoingLinks) {\n // Try to resolve the link target\n const targetId = resolveLink(link.target, node.path, nodeMap);\n\n if (targetId) {\n resolvedLinks.push({\n ...link,\n target: targetId,\n });\n\n // Create backlink in target node\n const targetNode = nodeMap.get(targetId);\n if (targetNode) {\n targetNode.incomingLinks.push({\n target: node.id,\n type: 'backlink',\n text: node.title,\n });\n }\n\n stats.edgesCreated++;\n }\n }\n\n node.outgoingLinks = resolvedLinks;\n graph.addNode(node);\n }\n\n return { graph, stats };\n}\n\n/**\n * Generate graph and save to database\n */\nexport async function generateAndSave(\n options: GeneratorOptions,\n dbPath: string\n): Promise<{\n success: boolean;\n stats: {\n filesScanned: number;\n nodesCreated: number;\n edgesCreated: number;\n errors: string[];\n };\n}> {\n const { graph, stats } = await generateGraph(options);\n\n // Save to database\n const db = new KnowledgeGraphDatabase(dbPath);\n\n try {\n const nodes = graph.getAllNodes();\n const edges = graph.getAllEdges();\n\n for (const node of nodes) {\n db.upsertNode(node);\n }\n\n for (const edge of edges) {\n db.addEdge(edge);\n }\n\n db.setMetadata('lastGenerated', new Date().toISOString());\n db.setMetadata('nodeCount', String(stats.nodesCreated));\n db.setMetadata('edgeCount', String(stats.edgesCreated));\n\n return { success: true, stats };\n } catch (error) {\n stats.errors.push(`Database error: ${error}`);\n return { success: false, stats };\n } finally {\n db.close();\n }\n}\n\n/**\n * Parse a markdown file into a knowledge node\n */\nasync function parseMarkdownFile(\n filePath: string,\n docsRoot: string\n): Promise<KnowledgeNode> {\n const content = readFileSync(filePath, 'utf-8');\n const stat = statSync(filePath);\n const { data, content: body } = matter(content);\n\n // Extract filename and path\n const filename = basename(filePath, '.md');\n const relativePath = relative(docsRoot, filePath);\n\n // Generate ID from relative path\n const id = relativePath\n .replace(/\\.md$/, '')\n .replace(/\\\\/g, '/')\n .replace(/[^a-z0-9/]+/gi, '-')\n .toLowerCase();\n\n // Extract links from content\n const outgoingLinks = extractLinks(body);\n\n // Determine node type from frontmatter or path\n const type = inferNodeType(data.type, relativePath);\n const status = (data.status as NodeStatus) || 'active';\n\n // Build frontmatter\n const frontmatter: NodeFrontmatter = {\n title: data.title || formatTitle(filename),\n type,\n status,\n tags: Array.isArray(data.tags) ? data.tags : [],\n category: data.category,\n description: data.description,\n created: data.created || stat.birthtime.toISOString().split('T')[0],\n updated: data.updated || stat.mtime.toISOString().split('T')[0],\n aliases: data.aliases,\n related: data.related,\n ...data,\n };\n\n // Calculate word count\n const wordCount = body\n .replace(/[#*`\\[\\]()]/g, '')\n .split(/\\s+/)\n .filter(Boolean).length;\n\n return {\n id,\n path: relativePath,\n filename,\n title: frontmatter.title || formatTitle(filename),\n type,\n status,\n content: body,\n frontmatter,\n tags: frontmatter.tags || [],\n outgoingLinks,\n incomingLinks: [], // Will be filled in second pass\n wordCount,\n lastModified: stat.mtime,\n };\n}\n\n/**\n * Extract links from markdown content\n */\nfunction extractLinks(content: string): NodeLink[] {\n const links: NodeLink[] = [];\n const seen = new Set<string>();\n\n // Extract wikilinks\n let match: RegExpExecArray | null;\n while ((match = WIKILINK_PATTERN.exec(content)) !== null) {\n const target = match[1].trim();\n const text = match[2]?.trim();\n\n if (!seen.has(target)) {\n seen.add(target);\n links.push({\n target,\n type: 'wikilink',\n text,\n });\n }\n }\n\n // Extract markdown links (only internal ones)\n while ((match = MARKDOWN_LINK_PATTERN.exec(content)) !== null) {\n const text = match[1].trim();\n const target = match[2].trim();\n\n // Skip external URLs\n if (target.startsWith('http://') || target.startsWith('https://')) {\n continue;\n }\n\n if (!seen.has(target)) {\n seen.add(target);\n links.push({\n target,\n type: 'markdown',\n text,\n });\n }\n }\n\n return links;\n}\n\n/**\n * Resolve a link target to a node ID\n */\nfunction resolveLink(\n target: string,\n currentPath: string,\n nodeMap: Map<string, KnowledgeNode>\n): string | null {\n // Clean target\n const cleanTarget = target\n .replace(/\\.md$/, '')\n .replace(/^\\.\\//, '')\n .toLowerCase();\n\n // Try direct match\n for (const [id, node] of nodeMap) {\n // Match by ID\n if (id === cleanTarget) {\n return id;\n }\n\n // Match by filename\n if (node.filename.toLowerCase() === cleanTarget) {\n return id;\n }\n\n // Match by title\n if (node.title.toLowerCase() === cleanTarget) {\n return id;\n }\n\n // Match by alias\n if (node.frontmatter.aliases?.some(\n a => a.toLowerCase() === cleanTarget\n )) {\n return id;\n }\n }\n\n // Try relative path resolution\n const currentDir = currentPath.replace(/[^/]+$/, '');\n const relativePath = join(currentDir, cleanTarget)\n .replace(/\\\\/g, '/')\n .replace(/^\\//, '');\n\n for (const [id, node] of nodeMap) {\n if (id === relativePath || node.path.replace(/\\.md$/, '') === relativePath) {\n return id;\n }\n }\n\n return null;\n}\n\n/**\n * Infer node type from frontmatter or path\n */\nfunction inferNodeType(declaredType: unknown, path: string): NodeType {\n // Use declared type if valid\n const validTypes: NodeType[] = [\n 'concept', 'technical', 'feature', 'primitive',\n 'service', 'guide', 'standard', 'integration',\n ];\n\n if (typeof declaredType === 'string' && validTypes.includes(declaredType as NodeType)) {\n return declaredType as NodeType;\n }\n\n // Infer from path\n const pathLower = path.toLowerCase();\n\n if (pathLower.includes('concept')) return 'concept';\n if (pathLower.includes('component') || pathLower.includes('technical')) return 'technical';\n if (pathLower.includes('feature')) return 'feature';\n if (pathLower.includes('primitive') || pathLower.includes('integration')) return 'primitive';\n if (pathLower.includes('service') || pathLower.includes('api')) return 'service';\n if (pathLower.includes('guide') || pathLower.includes('tutorial')) return 'guide';\n if (pathLower.includes('standard')) return 'standard';\n if (pathLower.includes('reference')) return 'technical';\n\n return 'concept'; // Default\n}\n\n/**\n * Format filename as title\n */\nfunction formatTitle(filename: string): string {\n return filename\n .replace(/-/g, ' ')\n .replace(/_/g, ' ')\n .replace(/\\b\\w/g, c => c.toUpperCase());\n}\n\n/**\n * Generate graph from existing database (incremental update)\n */\nexport async function updateGraph(\n dbPath: string,\n docsRoot: string\n): Promise<{\n added: number;\n updated: number;\n removed: number;\n errors: string[];\n}> {\n const result = {\n added: 0,\n updated: 0,\n removed: 0,\n errors: [] as string[],\n };\n\n const db = new KnowledgeGraphDatabase(dbPath);\n\n try {\n // Get existing nodes\n const existingNodes = db.getAllNodes();\n const existingPaths = new Set(existingNodes.map(n => n.path));\n\n // Find current files\n const currentFiles = await fg('**/*.md', {\n cwd: docsRoot,\n ignore: ['node_modules/**', '.git/**', '_templates/**'],\n });\n const currentPaths = new Set(currentFiles);\n\n // Find removed files\n for (const node of existingNodes) {\n if (!currentPaths.has(node.path)) {\n db.deleteNode(node.id);\n result.removed++;\n }\n }\n\n // Process current files\n for (const filePath of currentFiles) {\n const fullPath = join(docsRoot, filePath);\n\n try {\n const node = await parseMarkdownFile(fullPath, docsRoot);\n\n if (existingPaths.has(filePath)) {\n // Check if file was modified\n const existing = existingNodes.find(n => n.path === filePath);\n if (existing && node.lastModified > existing.lastModified) {\n db.deleteNodeEdges(node.id);\n db.upsertNode(node);\n result.updated++;\n }\n } else {\n db.upsertNode(node);\n result.added++;\n }\n } catch (error) {\n result.errors.push(`Failed to process ${filePath}: ${error}`);\n }\n }\n\n db.setMetadata('lastUpdated', new Date().toISOString());\n } finally {\n db.close();\n }\n\n return result;\n}\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge Graph Agent
|
|
3
|
+
*
|
|
4
|
+
* NPM library for creating and managing knowledge graphs for Claude Code.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
export { KnowledgeGraphManager, createKnowledgeGraph, } from './core/graph.js';
|
|
9
|
+
export { KnowledgeGraphDatabase, createDatabase, } from './core/database.js';
|
|
10
|
+
export type { NodeType, NodeStatus, NodeLink, NodeFrontmatter, KnowledgeNode, GraphEdge, GraphMetadata, GraphStats, KnowledgeGraph, KGConfig, ConfigSchema, GeneratorOptions, GeneratedDocument, DocsInitOptions, DocsInitResult, MemoryEntry, SyncResult, ClaudeMdSection, ClaudeMdTemplate, ClaudeMdGeneratorOptions, } from './core/types.js';
|
|
11
|
+
export { generateGraph, generateAndSave, updateGraph, } from './generators/graph-generator.js';
|
|
12
|
+
export { initDocs, docsExist, getDocsPath, } from './generators/docs-init.js';
|
|
13
|
+
export { generateClaudeMd, updateClaudeMd, addSection, getSectionTemplate, listSectionTemplates, } from './generators/claude-md.js';
|
|
14
|
+
export { ClaudeFlowIntegration, createClaudeFlowIntegration, generateMcpConfig, } from './integrations/claude-flow.js';
|
|
15
|
+
export { createCLI } from './cli/index.js';
|
|
16
|
+
/**
|
|
17
|
+
* Quick start function for programmatic usage
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { quickInit } from '@weave-nn/knowledge-graph-agent';
|
|
22
|
+
*
|
|
23
|
+
* await quickInit({
|
|
24
|
+
* projectRoot: '/path/to/project',
|
|
25
|
+
* docsPath: 'docs',
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function quickInit(options: {
|
|
30
|
+
projectRoot: string;
|
|
31
|
+
docsPath?: string;
|
|
32
|
+
generateGraph?: boolean;
|
|
33
|
+
updateClaudeMd?: boolean;
|
|
34
|
+
}): Promise<{
|
|
35
|
+
success: boolean;
|
|
36
|
+
docsCreated: boolean;
|
|
37
|
+
graphGenerated: boolean;
|
|
38
|
+
claudeMdUpdated: boolean;
|
|
39
|
+
errors: string[];
|
|
40
|
+
}>;
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,EACL,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,sBAAsB,EACtB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EAEV,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,eAAe,EACf,aAAa,EAGb,SAAS,EACT,aAAa,EACb,UAAU,EACV,cAAc,EAGd,QAAQ,EACR,YAAY,EAGZ,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,cAAc,EAGd,WAAW,EACX,UAAU,EAGV,eAAe,EACf,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,aAAa,EACb,eAAe,EACf,WAAW,GACZ,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,QAAQ,EACR,SAAS,EACT,WAAW,GACZ,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,qBAAqB,EACrB,2BAA2B,EAC3B,iBAAiB,GAClB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C;;;;;;;;;;;;GAYG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAAC;IACV,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC,CAgFD"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { createDatabase } from "./core/database.js";
|
|
2
|
+
import { KnowledgeGraphDatabase } from "./core/database.js";
|
|
3
|
+
import { docsExist, initDocs } from "./generators/docs-init.js";
|
|
4
|
+
import { getDocsPath } from "./generators/docs-init.js";
|
|
5
|
+
import { generateAndSave } from "./generators/graph-generator.js";
|
|
6
|
+
import { generateGraph, updateGraph } from "./generators/graph-generator.js";
|
|
7
|
+
import { updateClaudeMd } from "./generators/claude-md.js";
|
|
8
|
+
import { addSection, generateClaudeMd, getSectionTemplate, listSectionTemplates } from "./generators/claude-md.js";
|
|
9
|
+
import { KnowledgeGraphManager, createKnowledgeGraph } from "./core/graph.js";
|
|
10
|
+
import { ClaudeFlowIntegration, createClaudeFlowIntegration, generateMcpConfig } from "./integrations/claude-flow.js";
|
|
11
|
+
import { createCLI } from "./cli/index.js";
|
|
12
|
+
async function quickInit(options) {
|
|
13
|
+
const {
|
|
14
|
+
projectRoot,
|
|
15
|
+
docsPath = "docs",
|
|
16
|
+
generateGraph: genGraph = true,
|
|
17
|
+
updateClaudeMd: updateClaude = true
|
|
18
|
+
} = options;
|
|
19
|
+
const result = {
|
|
20
|
+
success: true,
|
|
21
|
+
docsCreated: false,
|
|
22
|
+
graphGenerated: false,
|
|
23
|
+
claudeMdUpdated: false,
|
|
24
|
+
errors: []
|
|
25
|
+
};
|
|
26
|
+
try {
|
|
27
|
+
const { existsSync, mkdirSync, writeFileSync } = await import("fs");
|
|
28
|
+
const { join } = await import("path");
|
|
29
|
+
const kgDir = join(projectRoot, ".kg");
|
|
30
|
+
if (!existsSync(kgDir)) {
|
|
31
|
+
mkdirSync(kgDir, { recursive: true });
|
|
32
|
+
}
|
|
33
|
+
const dbPath = join(kgDir, "knowledge.db");
|
|
34
|
+
const db = createDatabase(dbPath);
|
|
35
|
+
db.setMetadata("initialized", (/* @__PURE__ */ new Date()).toISOString());
|
|
36
|
+
if (!docsExist(projectRoot, docsPath)) {
|
|
37
|
+
const docsResult = await initDocs({
|
|
38
|
+
projectRoot,
|
|
39
|
+
docsPath,
|
|
40
|
+
includeExamples: true,
|
|
41
|
+
detectFramework: true
|
|
42
|
+
});
|
|
43
|
+
result.docsCreated = docsResult.success;
|
|
44
|
+
if (!docsResult.success) {
|
|
45
|
+
result.errors.push(...docsResult.errors);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (genGraph && docsExist(projectRoot, docsPath)) {
|
|
49
|
+
const graphResult = await generateAndSave(
|
|
50
|
+
{
|
|
51
|
+
projectRoot,
|
|
52
|
+
outputPath: join(projectRoot, docsPath)
|
|
53
|
+
},
|
|
54
|
+
dbPath
|
|
55
|
+
);
|
|
56
|
+
result.graphGenerated = graphResult.success;
|
|
57
|
+
if (!graphResult.success) {
|
|
58
|
+
result.errors.push(...graphResult.stats.errors);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (updateClaude) {
|
|
62
|
+
const claudeResult = await updateClaudeMd({
|
|
63
|
+
projectRoot,
|
|
64
|
+
includeKnowledgeGraph: true,
|
|
65
|
+
includeClaudeFlow: true
|
|
66
|
+
});
|
|
67
|
+
result.claudeMdUpdated = claudeResult.created || claudeResult.updated;
|
|
68
|
+
}
|
|
69
|
+
db.close();
|
|
70
|
+
result.success = result.errors.length === 0;
|
|
71
|
+
} catch (error) {
|
|
72
|
+
result.success = false;
|
|
73
|
+
result.errors.push(String(error));
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
export {
|
|
78
|
+
ClaudeFlowIntegration,
|
|
79
|
+
KnowledgeGraphDatabase,
|
|
80
|
+
KnowledgeGraphManager,
|
|
81
|
+
addSection,
|
|
82
|
+
createCLI,
|
|
83
|
+
createClaudeFlowIntegration,
|
|
84
|
+
createDatabase,
|
|
85
|
+
createKnowledgeGraph,
|
|
86
|
+
docsExist,
|
|
87
|
+
generateAndSave,
|
|
88
|
+
generateClaudeMd,
|
|
89
|
+
generateGraph,
|
|
90
|
+
generateMcpConfig,
|
|
91
|
+
getDocsPath,
|
|
92
|
+
getSectionTemplate,
|
|
93
|
+
initDocs,
|
|
94
|
+
listSectionTemplates,
|
|
95
|
+
quickInit,
|
|
96
|
+
updateClaudeMd,
|
|
97
|
+
updateGraph
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * Knowledge Graph Agent\n *\n * NPM library for creating and managing knowledge graphs for Claude Code.\n *\n * @packageDocumentation\n */\n\n// Internal imports for quickInit\nimport { createDatabase as _createDatabase } from './core/database.js';\nimport { initDocs as _initDocs, docsExist as _docsExist } from './generators/docs-init.js';\nimport { generateAndSave as _generateAndSave } from './generators/graph-generator.js';\nimport { updateClaudeMd as _updateClaudeMd } from './generators/claude-md.js';\n\n// Core exports\nexport {\n KnowledgeGraphManager,\n createKnowledgeGraph,\n} from './core/graph.js';\n\nexport {\n KnowledgeGraphDatabase,\n createDatabase,\n} from './core/database.js';\n\nexport type {\n // Node types\n NodeType,\n NodeStatus,\n NodeLink,\n NodeFrontmatter,\n KnowledgeNode,\n\n // Graph types\n GraphEdge,\n GraphMetadata,\n GraphStats,\n KnowledgeGraph,\n\n // Configuration\n KGConfig,\n ConfigSchema,\n\n // Generator types\n GeneratorOptions,\n GeneratedDocument,\n DocsInitOptions,\n DocsInitResult,\n\n // Integration types\n MemoryEntry,\n SyncResult,\n\n // CLAUDE.md types\n ClaudeMdSection,\n ClaudeMdTemplate,\n ClaudeMdGeneratorOptions,\n} from './core/types.js';\n\n// Generator exports\nexport {\n generateGraph,\n generateAndSave,\n updateGraph,\n} from './generators/graph-generator.js';\n\nexport {\n initDocs,\n docsExist,\n getDocsPath,\n} from './generators/docs-init.js';\n\nexport {\n generateClaudeMd,\n updateClaudeMd,\n addSection,\n getSectionTemplate,\n listSectionTemplates,\n} from './generators/claude-md.js';\n\n// Integration exports\nexport {\n ClaudeFlowIntegration,\n createClaudeFlowIntegration,\n generateMcpConfig,\n} from './integrations/claude-flow.js';\n\n// CLI export\nexport { createCLI } from './cli/index.js';\n\n/**\n * Quick start function for programmatic usage\n *\n * @example\n * ```typescript\n * import { quickInit } from '@weave-nn/knowledge-graph-agent';\n *\n * await quickInit({\n * projectRoot: '/path/to/project',\n * docsPath: 'docs',\n * });\n * ```\n */\nexport async function quickInit(options: {\n projectRoot: string;\n docsPath?: string;\n generateGraph?: boolean;\n updateClaudeMd?: boolean;\n}): Promise<{\n success: boolean;\n docsCreated: boolean;\n graphGenerated: boolean;\n claudeMdUpdated: boolean;\n errors: string[];\n}> {\n const {\n projectRoot,\n docsPath = 'docs',\n generateGraph: genGraph = true,\n updateClaudeMd: updateClaude = true,\n } = options;\n\n const result = {\n success: true,\n docsCreated: false,\n graphGenerated: false,\n claudeMdUpdated: false,\n errors: [] as string[],\n };\n\n try {\n // Initialize docs if needed\n const { existsSync, mkdirSync, writeFileSync } = await import('fs');\n const { join } = await import('path');\n\n // Create .kg directory\n const kgDir = join(projectRoot, '.kg');\n if (!existsSync(kgDir)) {\n mkdirSync(kgDir, { recursive: true });\n }\n\n // Initialize database\n const dbPath = join(kgDir, 'knowledge.db');\n const db = _createDatabase(dbPath);\n db.setMetadata('initialized', new Date().toISOString());\n\n // Initialize docs\n if (!_docsExist(projectRoot, docsPath)) {\n const docsResult = await _initDocs({\n projectRoot,\n docsPath,\n includeExamples: true,\n detectFramework: true,\n });\n result.docsCreated = docsResult.success;\n if (!docsResult.success) {\n result.errors.push(...docsResult.errors);\n }\n }\n\n // Generate graph\n if (genGraph && _docsExist(projectRoot, docsPath)) {\n const graphResult = await _generateAndSave(\n {\n projectRoot,\n outputPath: join(projectRoot, docsPath),\n },\n dbPath\n );\n result.graphGenerated = graphResult.success;\n if (!graphResult.success) {\n result.errors.push(...graphResult.stats.errors);\n }\n }\n\n // Update CLAUDE.md\n if (updateClaude) {\n const claudeResult = await _updateClaudeMd({\n projectRoot,\n includeKnowledgeGraph: true,\n includeClaudeFlow: true,\n });\n result.claudeMdUpdated = claudeResult.created || claudeResult.updated;\n }\n\n db.close();\n result.success = result.errors.length === 0;\n\n } catch (error) {\n result.success = false;\n result.errors.push(String(error));\n }\n\n return result;\n}\n"],"names":["_createDatabase","_docsExist","_initDocs","_generateAndSave","_updateClaudeMd"],"mappings":";;;;;;;;;;;AAuGA,eAAsB,UAAU,SAW7B;AACD,QAAM;AAAA,IACJ;AAAA,IACA,WAAW;AAAA,IACX,eAAe,WAAW;AAAA,IAC1B,gBAAgB,eAAe;AAAA,EAAA,IAC7B;AAEJ,QAAM,SAAS;AAAA,IACb,SAAS;AAAA,IACT,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,QAAQ,CAAA;AAAA,EAAC;AAGX,MAAI;AAEF,UAAM,EAAE,YAAY,WAAW,kBAAkB,MAAM,OAAO,IAAI;AAClE,UAAM,EAAE,KAAA,IAAS,MAAM,OAAO,MAAM;AAGpC,UAAM,QAAQ,KAAK,aAAa,KAAK;AACrC,QAAI,CAAC,WAAW,KAAK,GAAG;AACtB,gBAAU,OAAO,EAAE,WAAW,KAAA,CAAM;AAAA,IACtC;AAGA,UAAM,SAAS,KAAK,OAAO,cAAc;AACzC,UAAM,KAAKA,eAAgB,MAAM;AACjC,OAAG,YAAY,gBAAe,oBAAI,KAAA,GAAO,aAAa;AAGtD,QAAI,CAACC,UAAW,aAAa,QAAQ,GAAG;AACtC,YAAM,aAAa,MAAMC,SAAU;AAAA,QACjC;AAAA,QACA;AAAA,QACA,iBAAiB;AAAA,QACjB,iBAAiB;AAAA,MAAA,CAClB;AACD,aAAO,cAAc,WAAW;AAChC,UAAI,CAAC,WAAW,SAAS;AACvB,eAAO,OAAO,KAAK,GAAG,WAAW,MAAM;AAAA,MACzC;AAAA,IACF;AAGA,QAAI,YAAYD,UAAW,aAAa,QAAQ,GAAG;AACjD,YAAM,cAAc,MAAME;AAAAA,QACxB;AAAA,UACE;AAAA,UACA,YAAY,KAAK,aAAa,QAAQ;AAAA,QAAA;AAAA,QAExC;AAAA,MAAA;AAEF,aAAO,iBAAiB,YAAY;AACpC,UAAI,CAAC,YAAY,SAAS;AACxB,eAAO,OAAO,KAAK,GAAG,YAAY,MAAM,MAAM;AAAA,MAChD;AAAA,IACF;AAGA,QAAI,cAAc;AAChB,YAAM,eAAe,MAAMC,eAAgB;AAAA,QACzC;AAAA,QACA,uBAAuB;AAAA,QACvB,mBAAmB;AAAA,MAAA,CACpB;AACD,aAAO,kBAAkB,aAAa,WAAW,aAAa;AAAA,IAChE;AAEA,OAAG,MAAA;AACH,WAAO,UAAU,OAAO,OAAO,WAAW;AAAA,EAE5C,SAAS,OAAO;AACd,WAAO,UAAU;AACjB,WAAO,OAAO,KAAK,OAAO,KAAK,CAAC;AAAA,EAClC;AAEA,SAAO;AACT;"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude-Flow Integration
|
|
3
|
+
*
|
|
4
|
+
* Integrates knowledge graph with claude-flow memory and coordination.
|
|
5
|
+
*/
|
|
6
|
+
import type { KnowledgeNode, SyncResult } from '../core/types.js';
|
|
7
|
+
import { KnowledgeGraphDatabase } from '../core/database.js';
|
|
8
|
+
/**
|
|
9
|
+
* Claude-Flow client configuration
|
|
10
|
+
*/
|
|
11
|
+
export interface ClaudeFlowConfig {
|
|
12
|
+
namespace: string;
|
|
13
|
+
defaultTTL?: number;
|
|
14
|
+
syncOnChange?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Claude-Flow Knowledge Graph Integration
|
|
18
|
+
*
|
|
19
|
+
* Syncs knowledge graph data with claude-flow memory for
|
|
20
|
+
* cross-session persistence and agent coordination.
|
|
21
|
+
*/
|
|
22
|
+
export declare class ClaudeFlowIntegration {
|
|
23
|
+
private config;
|
|
24
|
+
constructor(config: ClaudeFlowConfig);
|
|
25
|
+
/**
|
|
26
|
+
* Sync all nodes to claude-flow memory
|
|
27
|
+
*/
|
|
28
|
+
syncToMemory(db: KnowledgeGraphDatabase): Promise<SyncResult>;
|
|
29
|
+
/**
|
|
30
|
+
* Sync a single node to memory
|
|
31
|
+
*/
|
|
32
|
+
syncNode(node: KnowledgeNode): Promise<boolean>;
|
|
33
|
+
/**
|
|
34
|
+
* Generate memory retrieval commands
|
|
35
|
+
*/
|
|
36
|
+
generateRetrievalCommands(): string[];
|
|
37
|
+
/**
|
|
38
|
+
* Generate hook commands for automatic sync
|
|
39
|
+
*/
|
|
40
|
+
generateHookCommands(): string[];
|
|
41
|
+
/**
|
|
42
|
+
* Convert node to memory entry format
|
|
43
|
+
*/
|
|
44
|
+
private nodeToMemoryEntry;
|
|
45
|
+
/**
|
|
46
|
+
* Extract summary from content
|
|
47
|
+
*/
|
|
48
|
+
private extractSummary;
|
|
49
|
+
/**
|
|
50
|
+
* Build tag index from nodes
|
|
51
|
+
*/
|
|
52
|
+
private buildTagIndex;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Create claude-flow integration instance
|
|
56
|
+
*/
|
|
57
|
+
export declare function createClaudeFlowIntegration(config: ClaudeFlowConfig): ClaudeFlowIntegration;
|
|
58
|
+
/**
|
|
59
|
+
* Generate MCP configuration for CLAUDE.md
|
|
60
|
+
*/
|
|
61
|
+
export declare function generateMcpConfig(namespace: string): string;
|
|
62
|
+
//# sourceMappingURL=claude-flow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-flow.d.ts","sourceRoot":"","sources":["../../src/integrations/claude-flow.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,aAAa,EAGb,UAAU,EACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAE7D;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAkBD;;;;;GAKG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAA6B;gBAE/B,MAAM,EAAE,gBAAgB;IAQpC;;OAEG;IACG,YAAY,CAAC,EAAE,EAAE,sBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC;IAsFnE;;OAEG;IACG,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IAoBrD;;OAEG;IACH,yBAAyB,IAAI,MAAM,EAAE;IAgBrC;;OAEG;IACH,oBAAoB,IAAI,MAAM,EAAE;IAahC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAkBzB;;OAEG;IACH,OAAO,CAAC,cAAc;IA8BtB;;OAEG;IACH,OAAO,CAAC,aAAa;CActB;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,gBAAgB,GACvB,qBAAqB,CAEvB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA4C3D"}
|