@weavelogic/knowledge-graph-agent 0.8.1 → 0.8.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/graph.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CA6J5C"}
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/graph.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAkM5C"}
@@ -7,15 +7,36 @@ import { updateGraph, generateAndSave } from "../../generators/graph-generator.j
7
7
  import { validateProjectRoot, validateDocsPath } from "../../core/security.js";
8
8
  function createGraphCommand() {
9
9
  const command = new Command("graph");
10
- command.description("Generate or update knowledge graph from documentation").option("-p, --path <path>", "Project root path", ".").option("-d, --docs <path>", "Docs directory path", "docs").option("-u, --update", "Incremental update instead of full regeneration").option("-v, --verbose", "Show detailed output").action(async (options) => {
10
+ command.description("Generate or update knowledge graph from documentation").option("-p, --path <path>", "Project root path", ".").option("-d, --docs <path>", "Docs directory path", "docs").option("-i, --include <paths>", "Additional paths to include (comma-separated)").option("-a, --all", "Scan entire project for markdown files").option("-u, --update", "Incremental update instead of full regeneration").option("-v, --verbose", "Show detailed output").action(async (options) => {
11
11
  const spinner = ora("Generating knowledge graph...").start();
12
12
  try {
13
13
  const projectRoot = validateProjectRoot(options.path);
14
- const docsPath = validateDocsPath(projectRoot, options.docs);
15
14
  const dbPath = join(projectRoot, ".kg", "knowledge.db");
16
- if (!existsSync(docsPath)) {
17
- spinner.fail(`Docs directory not found: ${docsPath}`);
18
- console.log(chalk.gray(" Run ") + chalk.cyan("kg docs init") + chalk.gray(" to create it"));
15
+ const sourcePaths = [];
16
+ if (options.all) {
17
+ sourcePaths.push(projectRoot);
18
+ } else {
19
+ const docsPath = validateDocsPath(projectRoot, options.docs);
20
+ if (existsSync(docsPath)) {
21
+ sourcePaths.push(docsPath);
22
+ }
23
+ if (options.include) {
24
+ const additionalPaths = options.include.split(",").map((p) => p.trim());
25
+ for (const relPath of additionalPaths) {
26
+ const fullPath = join(projectRoot, relPath);
27
+ if (existsSync(fullPath)) {
28
+ sourcePaths.push(fullPath);
29
+ } else if (options.verbose) {
30
+ console.log(chalk.yellow(` Skipping non-existent path: ${relPath}`));
31
+ }
32
+ }
33
+ }
34
+ }
35
+ if (sourcePaths.length === 0) {
36
+ spinner.fail("No documentation directories found");
37
+ console.log(chalk.gray(" Run ") + chalk.cyan("kg docs init") + chalk.gray(" to create docs/"));
38
+ console.log(chalk.gray(" Or use ") + chalk.cyan("--include <paths>") + chalk.gray(" to specify paths"));
39
+ console.log(chalk.gray(" Or use ") + chalk.cyan("--all") + chalk.gray(" to scan entire project"));
19
40
  process.exit(1);
20
41
  }
21
42
  if (!existsSync(join(projectRoot, ".kg"))) {
@@ -23,10 +44,13 @@ function createGraphCommand() {
23
44
  console.log(chalk.gray(" Run ") + chalk.cyan("kg init") + chalk.gray(" first"));
24
45
  process.exit(1);
25
46
  }
47
+ if (options.verbose) {
48
+ console.log(chalk.gray(` Scanning paths: ${sourcePaths.join(", ")}`));
49
+ }
26
50
  let result;
27
51
  if (options.update && existsSync(dbPath)) {
28
52
  spinner.text = "Updating knowledge graph...";
29
- result = await updateGraph(dbPath, docsPath);
53
+ result = await updateGraph(dbPath, sourcePaths[0], sourcePaths);
30
54
  spinner.succeed("Knowledge graph updated!");
31
55
  console.log();
32
56
  console.log(chalk.white(" Changes:"));
@@ -34,11 +58,13 @@ function createGraphCommand() {
34
58
  console.log(chalk.blue(` Updated: ${result.updated}`));
35
59
  console.log(chalk.yellow(` Removed: ${result.removed}`));
36
60
  } else {
37
- spinner.text = "Scanning documentation...";
61
+ spinner.text = options.all ? "Scanning entire project..." : "Scanning documentation...";
38
62
  result = await generateAndSave(
39
63
  {
40
64
  projectRoot,
41
- outputPath: docsPath
65
+ outputPath: sourcePaths[0],
66
+ additionalPaths: sourcePaths.slice(1),
67
+ scanAll: options.all
42
68
  },
43
69
  dbPath
44
70
  );
@@ -49,6 +75,7 @@ function createGraphCommand() {
49
75
  }
50
76
  console.log();
51
77
  console.log(chalk.white(" Statistics:"));
78
+ console.log(chalk.gray(` Paths scanned: ${sourcePaths.length}`));
52
79
  console.log(chalk.gray(` Files scanned: ${result.stats.filesScanned}`));
53
80
  console.log(chalk.green(` Nodes created: ${result.stats.nodesCreated}`));
54
81
  console.log(chalk.blue(` Edges created: ${result.stats.edgesCreated}`));
@@ -1 +1 @@
1
- {"version":3,"file":"graph.js","sources":["../../../src/cli/commands/graph.ts"],"sourcesContent":["/**\n * Graph Command\n *\n * Generate and update knowledge graph from documentation.\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport { generateAndSave, updateGraph } from '../../generators/graph-generator.js';\nimport { validateProjectRoot, validateDocsPath } from '../../core/security.js';\n\n/**\n * Create graph command\n */\nexport function createGraphCommand(): Command {\n const command = new Command('graph');\n\n command\n .description('Generate or update knowledge graph from documentation')\n .option('-p, --path <path>', 'Project root path', '.')\n .option('-d, --docs <path>', 'Docs directory path', 'docs')\n .option('-u, --update', 'Incremental update instead of full regeneration')\n .option('-v, --verbose', 'Show detailed output')\n .action(async (options) => {\n const spinner = ora('Generating knowledge graph...').start();\n\n try {\n // Validate paths to prevent traversal attacks\n const projectRoot = validateProjectRoot(options.path);\n const docsPath = validateDocsPath(projectRoot, options.docs);\n const dbPath = join(projectRoot, '.kg', 'knowledge.db');\n\n // Check if docs exist\n if (!existsSync(docsPath)) {\n spinner.fail(`Docs directory not found: ${docsPath}`);\n console.log(chalk.gray(' Run ') + chalk.cyan('kg docs init') + chalk.gray(' to create it'));\n process.exit(1);\n }\n\n // Check if KG is initialized\n if (!existsSync(join(projectRoot, '.kg'))) {\n spinner.fail('Knowledge graph not initialized');\n console.log(chalk.gray(' Run ') + chalk.cyan('kg init') + chalk.gray(' first'));\n process.exit(1);\n }\n\n let result;\n\n if (options.update && existsSync(dbPath)) {\n // Incremental update\n spinner.text = 'Updating knowledge graph...';\n result = await updateGraph(dbPath, docsPath);\n\n spinner.succeed('Knowledge graph updated!');\n\n console.log();\n console.log(chalk.white(' Changes:'));\n console.log(chalk.green(` Added: ${result.added}`));\n console.log(chalk.blue(` Updated: ${result.updated}`));\n console.log(chalk.yellow(` Removed: ${result.removed}`));\n\n } else {\n // Full generation\n spinner.text = 'Scanning documentation...';\n\n result = await generateAndSave(\n {\n projectRoot,\n outputPath: docsPath,\n },\n dbPath\n );\n\n if (result.success) {\n spinner.succeed('Knowledge graph generated!');\n } else {\n spinner.warn('Knowledge graph generated with errors');\n }\n\n console.log();\n console.log(chalk.white(' Statistics:'));\n console.log(chalk.gray(` Files scanned: ${result.stats.filesScanned}`));\n console.log(chalk.green(` Nodes created: ${result.stats.nodesCreated}`));\n console.log(chalk.blue(` Edges created: ${result.stats.edgesCreated}`));\n }\n\n // Show errors if any\n const errors = 'errors' in result ? result.errors : result.stats?.errors;\n if (errors && errors.length > 0) {\n console.log();\n console.log(chalk.yellow(' Warnings:'));\n errors.slice(0, 5).forEach((err: string) => {\n console.log(chalk.gray(` - ${err}`));\n });\n if (errors.length > 5) {\n console.log(chalk.gray(` ... and ${errors.length - 5} more`));\n }\n }\n\n console.log();\n console.log(chalk.cyan('Next: ') + chalk.white('kg stats') + chalk.gray(' to view graph statistics'));\n console.log();\n\n } catch (error) {\n spinner.fail('Failed to generate knowledge graph');\n console.error(chalk.red(String(error)));\n process.exit(1);\n }\n });\n\n // Add subcommands\n command\n .command('analyze')\n .description('Analyze graph structure and suggest improvements')\n .option('-p, --path <path>', 'Project root path', '.')\n .action(async (options) => {\n const spinner = ora('Analyzing graph...').start();\n\n try {\n const projectRoot = validateProjectRoot(options.path);\n const dbPath = join(projectRoot, '.kg', 'knowledge.db');\n\n if (!existsSync(dbPath)) {\n spinner.fail('Knowledge graph not found. Run \"kg graph\" first.');\n process.exit(1);\n }\n\n const { createDatabase } = await import('../../core/database.js');\n const db = createDatabase(dbPath);\n\n const stats = db.getStats();\n spinner.succeed('Graph analysis complete!');\n\n console.log();\n console.log(chalk.white(' Graph Health:'));\n\n // Orphan analysis\n if (stats.orphanNodes > 0) {\n console.log(chalk.yellow(` ⚠ ${stats.orphanNodes} orphan nodes (no links)`));\n } else {\n console.log(chalk.green(' ✓ No orphan nodes'));\n }\n\n // Connection density\n const density = stats.avgLinksPerNode;\n if (density < 1) {\n console.log(chalk.yellow(` ⚠ Low link density (${density} avg links/node)`));\n } else {\n console.log(chalk.green(` ✓ Good link density (${density} avg links/node)`));\n }\n\n // Most connected nodes\n if (stats.mostConnected.length > 0) {\n console.log();\n console.log(chalk.white(' Most Connected:'));\n stats.mostConnected.forEach(({ id, connections }) => {\n console.log(chalk.gray(` ${id}: ${connections} connections`));\n });\n }\n\n db.close();\n console.log();\n\n } catch (error) {\n spinner.fail('Analysis failed');\n console.error(chalk.red(String(error)));\n process.exit(1);\n }\n });\n\n return command;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"graph.js","sources":["../../../src/cli/commands/graph.ts"],"sourcesContent":["/**\n * Graph Command\n *\n * Generate and update knowledge graph from documentation.\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport { generateAndSave, updateGraph } from '../../generators/graph-generator.js';\nimport { validateProjectRoot, validateDocsPath } from '../../core/security.js';\n\n/**\n * Create graph command\n */\nexport function createGraphCommand(): Command {\n const command = new Command('graph');\n\n command\n .description('Generate or update knowledge graph from documentation')\n .option('-p, --path <path>', 'Project root path', '.')\n .option('-d, --docs <path>', 'Docs directory path', 'docs')\n .option('-i, --include <paths>', 'Additional paths to include (comma-separated)')\n .option('-a, --all', 'Scan entire project for markdown files')\n .option('-u, --update', 'Incremental update instead of full regeneration')\n .option('-v, --verbose', 'Show detailed output')\n .action(async (options) => {\n const spinner = ora('Generating knowledge graph...').start();\n\n try {\n // Validate paths to prevent traversal attacks\n const projectRoot = validateProjectRoot(options.path);\n const dbPath = join(projectRoot, '.kg', 'knowledge.db');\n\n // Build list of source paths\n const sourcePaths: string[] = [];\n\n if (options.all) {\n // Scan entire project\n sourcePaths.push(projectRoot);\n } else {\n // Add main docs path\n const docsPath = validateDocsPath(projectRoot, options.docs);\n if (existsSync(docsPath)) {\n sourcePaths.push(docsPath);\n }\n\n // Add additional include paths\n if (options.include) {\n const additionalPaths = options.include.split(',').map((p: string) => p.trim());\n for (const relPath of additionalPaths) {\n const fullPath = join(projectRoot, relPath);\n if (existsSync(fullPath)) {\n sourcePaths.push(fullPath);\n } else if (options.verbose) {\n console.log(chalk.yellow(` Skipping non-existent path: ${relPath}`));\n }\n }\n }\n }\n\n // Check if any source paths exist\n if (sourcePaths.length === 0) {\n spinner.fail('No documentation directories found');\n console.log(chalk.gray(' Run ') + chalk.cyan('kg docs init') + chalk.gray(' to create docs/'));\n console.log(chalk.gray(' Or use ') + chalk.cyan('--include <paths>') + chalk.gray(' to specify paths'));\n console.log(chalk.gray(' Or use ') + chalk.cyan('--all') + chalk.gray(' to scan entire project'));\n process.exit(1);\n }\n\n // Check if KG is initialized\n if (!existsSync(join(projectRoot, '.kg'))) {\n spinner.fail('Knowledge graph not initialized');\n console.log(chalk.gray(' Run ') + chalk.cyan('kg init') + chalk.gray(' first'));\n process.exit(1);\n }\n\n if (options.verbose) {\n console.log(chalk.gray(` Scanning paths: ${sourcePaths.join(', ')}`));\n }\n\n let result;\n\n if (options.update && existsSync(dbPath)) {\n // Incremental update\n spinner.text = 'Updating knowledge graph...';\n result = await updateGraph(dbPath, sourcePaths[0], sourcePaths);\n\n spinner.succeed('Knowledge graph updated!');\n\n console.log();\n console.log(chalk.white(' Changes:'));\n console.log(chalk.green(` Added: ${result.added}`));\n console.log(chalk.blue(` Updated: ${result.updated}`));\n console.log(chalk.yellow(` Removed: ${result.removed}`));\n\n } else {\n // Full generation\n spinner.text = options.all ? 'Scanning entire project...' : 'Scanning documentation...';\n\n result = await generateAndSave(\n {\n projectRoot,\n outputPath: sourcePaths[0],\n additionalPaths: sourcePaths.slice(1),\n scanAll: options.all,\n },\n dbPath\n );\n\n if (result.success) {\n spinner.succeed('Knowledge graph generated!');\n } else {\n spinner.warn('Knowledge graph generated with errors');\n }\n\n console.log();\n console.log(chalk.white(' Statistics:'));\n console.log(chalk.gray(` Paths scanned: ${sourcePaths.length}`));\n console.log(chalk.gray(` Files scanned: ${result.stats.filesScanned}`));\n console.log(chalk.green(` Nodes created: ${result.stats.nodesCreated}`));\n console.log(chalk.blue(` Edges created: ${result.stats.edgesCreated}`));\n }\n\n // Show errors if any\n const errors = 'errors' in result ? result.errors : result.stats?.errors;\n if (errors && errors.length > 0) {\n console.log();\n console.log(chalk.yellow(' Warnings:'));\n errors.slice(0, 5).forEach((err: string) => {\n console.log(chalk.gray(` - ${err}`));\n });\n if (errors.length > 5) {\n console.log(chalk.gray(` ... and ${errors.length - 5} more`));\n }\n }\n\n console.log();\n console.log(chalk.cyan('Next: ') + chalk.white('kg stats') + chalk.gray(' to view graph statistics'));\n console.log();\n\n } catch (error) {\n spinner.fail('Failed to generate knowledge graph');\n console.error(chalk.red(String(error)));\n process.exit(1);\n }\n });\n\n // Add subcommands\n command\n .command('analyze')\n .description('Analyze graph structure and suggest improvements')\n .option('-p, --path <path>', 'Project root path', '.')\n .action(async (options) => {\n const spinner = ora('Analyzing graph...').start();\n\n try {\n const projectRoot = validateProjectRoot(options.path);\n const dbPath = join(projectRoot, '.kg', 'knowledge.db');\n\n if (!existsSync(dbPath)) {\n spinner.fail('Knowledge graph not found. Run \"kg graph\" first.');\n process.exit(1);\n }\n\n const { createDatabase } = await import('../../core/database.js');\n const db = createDatabase(dbPath);\n\n const stats = db.getStats();\n spinner.succeed('Graph analysis complete!');\n\n console.log();\n console.log(chalk.white(' Graph Health:'));\n\n // Orphan analysis\n if (stats.orphanNodes > 0) {\n console.log(chalk.yellow(` ⚠ ${stats.orphanNodes} orphan nodes (no links)`));\n } else {\n console.log(chalk.green(' ✓ No orphan nodes'));\n }\n\n // Connection density\n const density = stats.avgLinksPerNode;\n if (density < 1) {\n console.log(chalk.yellow(` ⚠ Low link density (${density} avg links/node)`));\n } else {\n console.log(chalk.green(` ✓ Good link density (${density} avg links/node)`));\n }\n\n // Most connected nodes\n if (stats.mostConnected.length > 0) {\n console.log();\n console.log(chalk.white(' Most Connected:'));\n stats.mostConnected.forEach(({ id, connections }) => {\n console.log(chalk.gray(` ${id}: ${connections} connections`));\n });\n }\n\n db.close();\n console.log();\n\n } catch (error) {\n spinner.fail('Analysis failed');\n console.error(chalk.red(String(error)));\n process.exit(1);\n }\n });\n\n return command;\n}\n"],"names":[],"mappings":"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"}
@@ -54,6 +54,10 @@ export declare class KnowledgeGraphDatabase {
54
54
  * Delete node
55
55
  */
56
56
  deleteNode(id: string): boolean;
57
+ /**
58
+ * Clear all nodes and edges (for full regeneration)
59
+ */
60
+ clearAll(): void;
57
61
  /**
58
62
  * Update tags for a node
59
63
  */
@@ -1 +1 @@
1
- {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/core/database.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAGtC,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,UAAU,EACV,QAAQ,EACR,UAAU,EACX,MAAM,YAAY,CAAC;AAuGpB;;GAEG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM;IAuB1B;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAgCrC;;OAEG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAOzC;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAOjD;;OAEG;IACH,WAAW,IAAI,aAAa,EAAE;IAM9B;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,aAAa,EAAE;IAM/C;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,aAAa,EAAE;IAMrD;;OAEG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,EAAE;IAY3C;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAiBxB;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,aAAa,EAAE;IAsBvD;;OAEG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAU/B;;OAEG;IACH,OAAO,CAAC,cAAc;IAqBtB;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAWrC;;OAEG;IACH,UAAU,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAepD;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAQ9B;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE;IAM7C;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE;IAM7C;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQrC;;OAEG;IACH,QAAQ,IAAI,UAAU;IA2DtB;;OAEG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAMvC;;OAEG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAY7C;;OAEG;IACH,OAAO,CAAC,SAAS;IA8BjB;;OAEG;IACH,OAAO,CAAC,SAAS;IAUjB;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,WAAW,IAAI,QAAQ,CAAC,QAAQ;CAGjC;AA2BD;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,sBAAsB,CAErE"}
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/core/database.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAGtC,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,UAAU,EACV,QAAQ,EACR,UAAU,EACX,MAAM,YAAY,CAAC;AAuGpB;;GAEG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM;IAuB1B;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAgCrC;;OAEG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAOzC;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAOjD;;OAEG;IACH,WAAW,IAAI,aAAa,EAAE;IAM9B;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,aAAa,EAAE;IAM/C;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,aAAa,EAAE;IAMrD;;OAEG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,EAAE;IAY3C;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAiBxB;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,aAAa,EAAE;IAsBvD;;OAEG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAM/B;;OAEG;IACH,QAAQ,IAAI,IAAI;IAUhB;;OAEG;IACH,OAAO,CAAC,cAAc;IAqBtB;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAWrC;;OAEG;IACH,UAAU,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAepD;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAQ9B;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE;IAM7C;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE;IAM7C;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQrC;;OAEG;IACH,QAAQ,IAAI,UAAU;IA2DtB;;OAEG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAMvC;;OAEG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAY7C;;OAEG;IACH,OAAO,CAAC,SAAS;IA8BjB;;OAEG;IACH,OAAO,CAAC,SAAS;IAUjB;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,WAAW,IAAI,QAAQ,CAAC,QAAQ;CAGjC;AA2BD;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,sBAAsB,CAErE"}
@@ -237,6 +237,14 @@ class KnowledgeGraphDatabase {
237
237
  const result = stmt.run(id);
238
238
  return result.changes > 0;
239
239
  }
240
+ /**
241
+ * Clear all nodes and edges (for full regeneration)
242
+ */
243
+ clearAll() {
244
+ this.db.exec("DELETE FROM edges");
245
+ this.db.exec("DELETE FROM node_tags");
246
+ this.db.exec("DELETE FROM nodes");
247
+ }
240
248
  // ========================================================================
241
249
  // Tag Operations
242
250
  // ========================================================================
@@ -1 +1 @@
1
- {"version":3,"file":"database.js","sources":["../../src/core/database.ts"],"sourcesContent":["/**\n * Knowledge Graph Database\n *\n * SQLite database for persistent storage of knowledge graph data.\n * Compatible with claude-flow database patterns.\n */\n\nimport Database from 'better-sqlite3';\nimport { existsSync, mkdirSync } from 'fs';\nimport { dirname } from 'path';\nimport type {\n KnowledgeNode,\n GraphEdge,\n GraphStats,\n NodeType,\n NodeStatus,\n} from './types.js';\n\n/**\n * Safely parse JSON with fallback\n * Prevents error leakage from malformed JSON\n */\nfunction safeJsonParse<T>(str: string | null | undefined, fallback: T): T {\n if (!str) return fallback;\n try {\n return JSON.parse(str) as T;\n } catch {\n return fallback;\n }\n}\n\nconst SCHEMA_SQL = `\n-- Knowledge Graph Schema v1.0\n\n-- Nodes table\nCREATE TABLE IF NOT EXISTS nodes (\n id TEXT PRIMARY KEY,\n path TEXT NOT NULL UNIQUE,\n filename TEXT NOT NULL,\n title TEXT NOT NULL,\n type TEXT NOT NULL CHECK(type IN ('concept', 'technical', 'feature', 'primitive', 'service', 'guide', 'standard', 'integration')),\n status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('draft', 'active', 'deprecated', 'archived')),\n content TEXT,\n frontmatter TEXT,\n word_count INTEGER DEFAULT 0,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Tags table\nCREATE TABLE IF NOT EXISTS tags (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL UNIQUE\n);\n\n-- Node-Tags junction table\nCREATE TABLE IF NOT EXISTS node_tags (\n node_id TEXT NOT NULL,\n tag_id INTEGER NOT NULL,\n PRIMARY KEY (node_id, tag_id),\n FOREIGN KEY (node_id) REFERENCES nodes(id) ON DELETE CASCADE,\n FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE\n);\n\n-- Edges table\nCREATE TABLE IF NOT EXISTS edges (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n source_id TEXT NOT NULL,\n target_id TEXT NOT NULL,\n type TEXT NOT NULL CHECK(type IN ('link', 'reference', 'parent', 'related')),\n weight REAL DEFAULT 1.0,\n context TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n FOREIGN KEY (source_id) REFERENCES nodes(id) ON DELETE CASCADE\n);\n\n-- Metadata table\nCREATE TABLE IF NOT EXISTS metadata (\n key TEXT PRIMARY KEY,\n value TEXT,\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Indexes for performance\nCREATE INDEX IF NOT EXISTS idx_nodes_type ON nodes(type);\nCREATE INDEX IF NOT EXISTS idx_nodes_status ON nodes(status);\nCREATE INDEX IF NOT EXISTS idx_nodes_path ON nodes(path);\nCREATE INDEX IF NOT EXISTS idx_edges_source ON edges(source_id);\nCREATE INDEX IF NOT EXISTS idx_edges_target ON edges(target_id);\nCREATE INDEX IF NOT EXISTS idx_node_tags_node ON node_tags(node_id);\nCREATE INDEX IF NOT EXISTS idx_node_tags_tag ON node_tags(tag_id);\n\n-- Full-text search\nCREATE VIRTUAL TABLE IF NOT EXISTS nodes_fts USING fts5(\n title,\n content,\n content='nodes',\n content_rowid='rowid'\n);\n\n-- Triggers for FTS sync\nCREATE TRIGGER IF NOT EXISTS nodes_ai AFTER INSERT ON nodes BEGIN\n INSERT INTO nodes_fts(rowid, title, content) VALUES (NEW.rowid, NEW.title, NEW.content);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS nodes_ad AFTER DELETE ON nodes BEGIN\n INSERT INTO nodes_fts(nodes_fts, rowid, title, content) VALUES('delete', OLD.rowid, OLD.title, OLD.content);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS nodes_au AFTER UPDATE ON nodes BEGIN\n INSERT INTO nodes_fts(nodes_fts, rowid, title, content) VALUES('delete', OLD.rowid, OLD.title, OLD.content);\n INSERT INTO nodes_fts(rowid, title, content) VALUES (NEW.rowid, NEW.title, NEW.content);\nEND;\n\n-- Initialize metadata\nINSERT OR IGNORE INTO metadata (key, value) VALUES ('version', '1.0.0');\nINSERT OR IGNORE INTO metadata (key, value) VALUES ('created', datetime('now'));\n`;\n\n/**\n * Knowledge Graph Database\n */\nexport class KnowledgeGraphDatabase {\n private db: Database.Database;\n private dbPath: string;\n\n constructor(dbPath: string) {\n this.dbPath = dbPath;\n\n // Ensure directory exists\n const dir = dirname(dbPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // Open database\n this.db = new Database(dbPath);\n this.db.pragma('journal_mode = WAL');\n this.db.pragma('foreign_keys = ON');\n this.db.pragma('busy_timeout = 5000');\n\n // Initialize schema\n this.db.exec(SCHEMA_SQL);\n }\n\n // ========================================================================\n // Node Operations\n // ========================================================================\n\n /**\n * Insert or update a node\n */\n upsertNode(node: KnowledgeNode): void {\n const stmt = this.db.prepare(`\n INSERT INTO nodes (id, path, filename, title, type, status, content, frontmatter, word_count, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'))\n ON CONFLICT(id) DO UPDATE SET\n path = excluded.path,\n filename = excluded.filename,\n title = excluded.title,\n type = excluded.type,\n status = excluded.status,\n content = excluded.content,\n frontmatter = excluded.frontmatter,\n word_count = excluded.word_count,\n updated_at = datetime('now')\n `);\n\n stmt.run(\n node.id,\n node.path,\n node.filename,\n node.title,\n node.type,\n node.status,\n node.content,\n JSON.stringify(node.frontmatter),\n node.wordCount\n );\n\n // Update tags\n this.updateNodeTags(node.id, node.tags);\n }\n\n /**\n * Get node by ID\n */\n getNode(id: string): KnowledgeNode | null {\n const stmt = this.db.prepare('SELECT * FROM nodes WHERE id = ?');\n const row = stmt.get(id) as NodeRow | undefined;\n if (!row) return null;\n return this.rowToNode(row);\n }\n\n /**\n * Get node by path\n */\n getNodeByPath(path: string): KnowledgeNode | null {\n const stmt = this.db.prepare('SELECT * FROM nodes WHERE path = ?');\n const row = stmt.get(path) as NodeRow | undefined;\n if (!row) return null;\n return this.rowToNode(row);\n }\n\n /**\n * Get all nodes\n */\n getAllNodes(): KnowledgeNode[] {\n const stmt = this.db.prepare('SELECT * FROM nodes ORDER BY title');\n const rows = stmt.all() as NodeRow[];\n return rows.map(row => this.rowToNode(row));\n }\n\n /**\n * Get nodes by type\n */\n getNodesByType(type: NodeType): KnowledgeNode[] {\n const stmt = this.db.prepare('SELECT * FROM nodes WHERE type = ? ORDER BY title');\n const rows = stmt.all(type) as NodeRow[];\n return rows.map(row => this.rowToNode(row));\n }\n\n /**\n * Get nodes by status\n */\n getNodesByStatus(status: NodeStatus): KnowledgeNode[] {\n const stmt = this.db.prepare('SELECT * FROM nodes WHERE status = ? ORDER BY title');\n const rows = stmt.all(status) as NodeRow[];\n return rows.map(row => this.rowToNode(row));\n }\n\n /**\n * Get nodes by tag\n */\n getNodesByTag(tag: string): KnowledgeNode[] {\n const stmt = this.db.prepare(`\n SELECT n.* FROM nodes n\n JOIN node_tags nt ON n.id = nt.node_id\n JOIN tags t ON nt.tag_id = t.id\n WHERE t.name = ?\n ORDER BY n.title\n `);\n const rows = stmt.all(tag) as NodeRow[];\n return rows.map(row => this.rowToNode(row));\n }\n\n /**\n * Sanitize FTS5 query to prevent query injection\n * Escapes special FTS5 operators and quotes terms\n */\n private sanitizeFtsQuery(query: string): string {\n if (!query || typeof query !== 'string') return '';\n\n // Remove FTS5 special operators: * \" ( ) : ^ - AND OR NOT NEAR\n const sanitized = query\n .replace(/[*\"():^\\-]/g, ' ') // Remove special chars\n .replace(/\\b(AND|OR|NOT|NEAR)\\b/gi, '') // Remove boolean operators\n .trim()\n .split(/\\s+/)\n .filter(term => term.length > 0 && term.length < 100) // Limit term length\n .slice(0, 20) // Limit number of terms\n .map(term => `\"${term.replace(/\"/g, '')}\"`) // Quote each term safely\n .join(' ');\n\n return sanitized;\n }\n\n /**\n * Search nodes by title or content\n */\n searchNodes(query: string, limit = 50): KnowledgeNode[] {\n const sanitizedQuery = this.sanitizeFtsQuery(query);\n\n // Return empty if no valid search terms\n if (!sanitizedQuery) {\n return [];\n }\n\n // Enforce reasonable limit\n const safeLimit = Math.min(Math.max(1, limit), 100);\n\n const stmt = this.db.prepare(`\n SELECT n.* FROM nodes n\n JOIN nodes_fts fts ON n.rowid = fts.rowid\n WHERE nodes_fts MATCH ?\n ORDER BY rank\n LIMIT ?\n `);\n const rows = stmt.all(sanitizedQuery, safeLimit) as NodeRow[];\n return rows.map(row => this.rowToNode(row));\n }\n\n /**\n * Delete node\n */\n deleteNode(id: string): boolean {\n const stmt = this.db.prepare('DELETE FROM nodes WHERE id = ?');\n const result = stmt.run(id);\n return result.changes > 0;\n }\n\n // ========================================================================\n // Tag Operations\n // ========================================================================\n\n /**\n * Update tags for a node\n */\n private updateNodeTags(nodeId: string, tags: string[]): void {\n // Remove existing tags\n this.db.prepare('DELETE FROM node_tags WHERE node_id = ?').run(nodeId);\n\n // Insert new tags\n const getOrCreateTag = this.db.prepare(`\n INSERT INTO tags (name) VALUES (?)\n ON CONFLICT(name) DO UPDATE SET name = excluded.name\n RETURNING id\n `);\n\n const insertNodeTag = this.db.prepare(\n 'INSERT OR IGNORE INTO node_tags (node_id, tag_id) VALUES (?, ?)'\n );\n\n for (const tag of tags) {\n const result = getOrCreateTag.get(tag) as { id: number };\n insertNodeTag.run(nodeId, result.id);\n }\n }\n\n /**\n * Get tags for a node\n */\n getNodeTags(nodeId: string): string[] {\n const stmt = this.db.prepare(`\n SELECT t.name FROM tags t\n JOIN node_tags nt ON t.id = nt.tag_id\n WHERE nt.node_id = ?\n ORDER BY t.name\n `);\n const rows = stmt.all(nodeId) as Array<{ name: string }>;\n return rows.map(r => r.name);\n }\n\n /**\n * Get all tags with counts\n */\n getAllTags(): Array<{ name: string; count: number }> {\n const stmt = this.db.prepare(`\n SELECT t.name, COUNT(nt.node_id) as count\n FROM tags t\n LEFT JOIN node_tags nt ON t.id = nt.tag_id\n GROUP BY t.id\n ORDER BY count DESC, t.name\n `);\n return stmt.all() as Array<{ name: string; count: number }>;\n }\n\n // ========================================================================\n // Edge Operations\n // ========================================================================\n\n /**\n * Add edge\n */\n addEdge(edge: GraphEdge): void {\n const stmt = this.db.prepare(`\n INSERT INTO edges (source_id, target_id, type, weight, context)\n VALUES (?, ?, ?, ?, ?)\n `);\n stmt.run(edge.source, edge.target, edge.type, edge.weight, edge.context);\n }\n\n /**\n * Get outgoing edges for a node\n */\n getOutgoingEdges(nodeId: string): GraphEdge[] {\n const stmt = this.db.prepare('SELECT * FROM edges WHERE source_id = ?');\n const rows = stmt.all(nodeId) as EdgeRow[];\n return rows.map(row => this.rowToEdge(row));\n }\n\n /**\n * Get incoming edges for a node\n */\n getIncomingEdges(nodeId: string): GraphEdge[] {\n const stmt = this.db.prepare('SELECT * FROM edges WHERE target_id = ?');\n const rows = stmt.all(nodeId) as EdgeRow[];\n return rows.map(row => this.rowToEdge(row));\n }\n\n /**\n * Delete edges for a node\n */\n deleteNodeEdges(nodeId: string): void {\n this.db.prepare('DELETE FROM edges WHERE source_id = ?').run(nodeId);\n }\n\n // ========================================================================\n // Statistics\n // ========================================================================\n\n /**\n * Get graph statistics\n */\n getStats(): GraphStats {\n const totalNodes = (this.db.prepare('SELECT COUNT(*) as count FROM nodes').get() as { count: number }).count;\n const totalEdges = (this.db.prepare('SELECT COUNT(*) as count FROM edges').get() as { count: number }).count;\n\n const typeStats = this.db.prepare(`\n SELECT type, COUNT(*) as count FROM nodes GROUP BY type\n `).all() as Array<{ type: NodeType; count: number }>;\n\n const statusStats = this.db.prepare(`\n SELECT status, COUNT(*) as count FROM nodes GROUP BY status\n `).all() as Array<{ status: NodeStatus; count: number }>;\n\n const nodesByType: Record<NodeType, number> = {\n concept: 0, technical: 0, feature: 0, primitive: 0,\n service: 0, guide: 0, standard: 0, integration: 0,\n };\n for (const { type, count } of typeStats) {\n nodesByType[type] = count;\n }\n\n const nodesByStatus: Record<NodeStatus, number> = {\n draft: 0, active: 0, deprecated: 0, archived: 0,\n };\n for (const { status, count } of statusStats) {\n nodesByStatus[status] = count;\n }\n\n const orphanNodes = (this.db.prepare(`\n SELECT COUNT(*) as count FROM nodes n\n WHERE NOT EXISTS (SELECT 1 FROM edges e WHERE e.source_id = n.id OR e.target_id = n.id)\n `).get() as { count: number }).count;\n\n const avgLinksPerNode = totalNodes > 0 ? totalEdges / totalNodes : 0;\n\n const mostConnected = this.db.prepare(`\n SELECT n.id, (\n (SELECT COUNT(*) FROM edges WHERE source_id = n.id) +\n (SELECT COUNT(*) FROM edges WHERE target_id = n.id)\n ) as connections\n FROM nodes n\n ORDER BY connections DESC\n LIMIT 5\n `).all() as Array<{ id: string; connections: number }>;\n\n return {\n totalNodes,\n totalEdges,\n nodesByType,\n nodesByStatus,\n orphanNodes,\n avgLinksPerNode: Math.round(avgLinksPerNode * 100) / 100,\n mostConnected,\n };\n }\n\n // ========================================================================\n // Metadata Operations\n // ========================================================================\n\n /**\n * Get metadata value\n */\n getMetadata(key: string): string | null {\n const stmt = this.db.prepare('SELECT value FROM metadata WHERE key = ?');\n const row = stmt.get(key) as { value: string } | undefined;\n return row?.value ?? null;\n }\n\n /**\n * Set metadata value\n */\n setMetadata(key: string, value: string): void {\n const stmt = this.db.prepare(`\n INSERT INTO metadata (key, value, updated_at) VALUES (?, ?, datetime('now'))\n ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = datetime('now')\n `);\n stmt.run(key, value);\n }\n\n // ========================================================================\n // Utilities\n // ========================================================================\n\n /**\n * Convert database row to KnowledgeNode\n */\n private rowToNode(row: NodeRow): KnowledgeNode {\n const tags = this.getNodeTags(row.id);\n const outgoingEdges = this.getOutgoingEdges(row.id);\n const incomingEdges = this.getIncomingEdges(row.id);\n\n return {\n id: row.id,\n path: row.path,\n filename: row.filename,\n title: row.title,\n type: row.type as NodeType,\n status: row.status as NodeStatus,\n content: row.content || '',\n frontmatter: safeJsonParse(row.frontmatter, {}),\n tags,\n outgoingLinks: outgoingEdges.map(e => ({\n target: e.target,\n type: 'wikilink' as const,\n context: e.context,\n })),\n incomingLinks: incomingEdges.map(e => ({\n target: e.source,\n type: 'backlink' as const,\n context: e.context,\n })),\n wordCount: row.word_count,\n lastModified: new Date(row.updated_at),\n };\n }\n\n /**\n * Convert database row to GraphEdge\n */\n private rowToEdge(row: EdgeRow): GraphEdge {\n return {\n source: row.source_id,\n target: row.target_id,\n type: row.type as GraphEdge['type'],\n weight: row.weight,\n context: row.context ?? undefined,\n };\n }\n\n /**\n * Close database connection\n */\n close(): void {\n this.db.close();\n }\n\n /**\n * Get raw database instance\n */\n getDatabase(): Database.Database {\n return this.db;\n }\n}\n\n// Row types for database queries\ninterface NodeRow {\n id: string;\n path: string;\n filename: string;\n title: string;\n type: string;\n status: string;\n content: string | null;\n frontmatter: string | null;\n word_count: number;\n created_at: string;\n updated_at: string;\n}\n\ninterface EdgeRow {\n id: number;\n source_id: string;\n target_id: string;\n type: string;\n weight: number;\n context: string | null;\n created_at: string;\n}\n\n/**\n * Create knowledge graph database instance\n */\nexport function createDatabase(dbPath: string): KnowledgeGraphDatabase {\n return new KnowledgeGraphDatabase(dbPath);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"database.js","sources":["../../src/core/database.ts"],"sourcesContent":["/**\n * Knowledge Graph Database\n *\n * SQLite database for persistent storage of knowledge graph data.\n * Compatible with claude-flow database patterns.\n */\n\nimport Database from 'better-sqlite3';\nimport { existsSync, mkdirSync } from 'fs';\nimport { dirname } from 'path';\nimport type {\n KnowledgeNode,\n GraphEdge,\n GraphStats,\n NodeType,\n NodeStatus,\n} from './types.js';\n\n/**\n * Safely parse JSON with fallback\n * Prevents error leakage from malformed JSON\n */\nfunction safeJsonParse<T>(str: string | null | undefined, fallback: T): T {\n if (!str) return fallback;\n try {\n return JSON.parse(str) as T;\n } catch {\n return fallback;\n }\n}\n\nconst SCHEMA_SQL = `\n-- Knowledge Graph Schema v1.0\n\n-- Nodes table\nCREATE TABLE IF NOT EXISTS nodes (\n id TEXT PRIMARY KEY,\n path TEXT NOT NULL UNIQUE,\n filename TEXT NOT NULL,\n title TEXT NOT NULL,\n type TEXT NOT NULL CHECK(type IN ('concept', 'technical', 'feature', 'primitive', 'service', 'guide', 'standard', 'integration')),\n status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('draft', 'active', 'deprecated', 'archived')),\n content TEXT,\n frontmatter TEXT,\n word_count INTEGER DEFAULT 0,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Tags table\nCREATE TABLE IF NOT EXISTS tags (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL UNIQUE\n);\n\n-- Node-Tags junction table\nCREATE TABLE IF NOT EXISTS node_tags (\n node_id TEXT NOT NULL,\n tag_id INTEGER NOT NULL,\n PRIMARY KEY (node_id, tag_id),\n FOREIGN KEY (node_id) REFERENCES nodes(id) ON DELETE CASCADE,\n FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE\n);\n\n-- Edges table\nCREATE TABLE IF NOT EXISTS edges (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n source_id TEXT NOT NULL,\n target_id TEXT NOT NULL,\n type TEXT NOT NULL CHECK(type IN ('link', 'reference', 'parent', 'related')),\n weight REAL DEFAULT 1.0,\n context TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n FOREIGN KEY (source_id) REFERENCES nodes(id) ON DELETE CASCADE\n);\n\n-- Metadata table\nCREATE TABLE IF NOT EXISTS metadata (\n key TEXT PRIMARY KEY,\n value TEXT,\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Indexes for performance\nCREATE INDEX IF NOT EXISTS idx_nodes_type ON nodes(type);\nCREATE INDEX IF NOT EXISTS idx_nodes_status ON nodes(status);\nCREATE INDEX IF NOT EXISTS idx_nodes_path ON nodes(path);\nCREATE INDEX IF NOT EXISTS idx_edges_source ON edges(source_id);\nCREATE INDEX IF NOT EXISTS idx_edges_target ON edges(target_id);\nCREATE INDEX IF NOT EXISTS idx_node_tags_node ON node_tags(node_id);\nCREATE INDEX IF NOT EXISTS idx_node_tags_tag ON node_tags(tag_id);\n\n-- Full-text search\nCREATE VIRTUAL TABLE IF NOT EXISTS nodes_fts USING fts5(\n title,\n content,\n content='nodes',\n content_rowid='rowid'\n);\n\n-- Triggers for FTS sync\nCREATE TRIGGER IF NOT EXISTS nodes_ai AFTER INSERT ON nodes BEGIN\n INSERT INTO nodes_fts(rowid, title, content) VALUES (NEW.rowid, NEW.title, NEW.content);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS nodes_ad AFTER DELETE ON nodes BEGIN\n INSERT INTO nodes_fts(nodes_fts, rowid, title, content) VALUES('delete', OLD.rowid, OLD.title, OLD.content);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS nodes_au AFTER UPDATE ON nodes BEGIN\n INSERT INTO nodes_fts(nodes_fts, rowid, title, content) VALUES('delete', OLD.rowid, OLD.title, OLD.content);\n INSERT INTO nodes_fts(rowid, title, content) VALUES (NEW.rowid, NEW.title, NEW.content);\nEND;\n\n-- Initialize metadata\nINSERT OR IGNORE INTO metadata (key, value) VALUES ('version', '1.0.0');\nINSERT OR IGNORE INTO metadata (key, value) VALUES ('created', datetime('now'));\n`;\n\n/**\n * Knowledge Graph Database\n */\nexport class KnowledgeGraphDatabase {\n private db: Database.Database;\n private dbPath: string;\n\n constructor(dbPath: string) {\n this.dbPath = dbPath;\n\n // Ensure directory exists\n const dir = dirname(dbPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // Open database\n this.db = new Database(dbPath);\n this.db.pragma('journal_mode = WAL');\n this.db.pragma('foreign_keys = ON');\n this.db.pragma('busy_timeout = 5000');\n\n // Initialize schema\n this.db.exec(SCHEMA_SQL);\n }\n\n // ========================================================================\n // Node Operations\n // ========================================================================\n\n /**\n * Insert or update a node\n */\n upsertNode(node: KnowledgeNode): void {\n const stmt = this.db.prepare(`\n INSERT INTO nodes (id, path, filename, title, type, status, content, frontmatter, word_count, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'))\n ON CONFLICT(id) DO UPDATE SET\n path = excluded.path,\n filename = excluded.filename,\n title = excluded.title,\n type = excluded.type,\n status = excluded.status,\n content = excluded.content,\n frontmatter = excluded.frontmatter,\n word_count = excluded.word_count,\n updated_at = datetime('now')\n `);\n\n stmt.run(\n node.id,\n node.path,\n node.filename,\n node.title,\n node.type,\n node.status,\n node.content,\n JSON.stringify(node.frontmatter),\n node.wordCount\n );\n\n // Update tags\n this.updateNodeTags(node.id, node.tags);\n }\n\n /**\n * Get node by ID\n */\n getNode(id: string): KnowledgeNode | null {\n const stmt = this.db.prepare('SELECT * FROM nodes WHERE id = ?');\n const row = stmt.get(id) as NodeRow | undefined;\n if (!row) return null;\n return this.rowToNode(row);\n }\n\n /**\n * Get node by path\n */\n getNodeByPath(path: string): KnowledgeNode | null {\n const stmt = this.db.prepare('SELECT * FROM nodes WHERE path = ?');\n const row = stmt.get(path) as NodeRow | undefined;\n if (!row) return null;\n return this.rowToNode(row);\n }\n\n /**\n * Get all nodes\n */\n getAllNodes(): KnowledgeNode[] {\n const stmt = this.db.prepare('SELECT * FROM nodes ORDER BY title');\n const rows = stmt.all() as NodeRow[];\n return rows.map(row => this.rowToNode(row));\n }\n\n /**\n * Get nodes by type\n */\n getNodesByType(type: NodeType): KnowledgeNode[] {\n const stmt = this.db.prepare('SELECT * FROM nodes WHERE type = ? ORDER BY title');\n const rows = stmt.all(type) as NodeRow[];\n return rows.map(row => this.rowToNode(row));\n }\n\n /**\n * Get nodes by status\n */\n getNodesByStatus(status: NodeStatus): KnowledgeNode[] {\n const stmt = this.db.prepare('SELECT * FROM nodes WHERE status = ? ORDER BY title');\n const rows = stmt.all(status) as NodeRow[];\n return rows.map(row => this.rowToNode(row));\n }\n\n /**\n * Get nodes by tag\n */\n getNodesByTag(tag: string): KnowledgeNode[] {\n const stmt = this.db.prepare(`\n SELECT n.* FROM nodes n\n JOIN node_tags nt ON n.id = nt.node_id\n JOIN tags t ON nt.tag_id = t.id\n WHERE t.name = ?\n ORDER BY n.title\n `);\n const rows = stmt.all(tag) as NodeRow[];\n return rows.map(row => this.rowToNode(row));\n }\n\n /**\n * Sanitize FTS5 query to prevent query injection\n * Escapes special FTS5 operators and quotes terms\n */\n private sanitizeFtsQuery(query: string): string {\n if (!query || typeof query !== 'string') return '';\n\n // Remove FTS5 special operators: * \" ( ) : ^ - AND OR NOT NEAR\n const sanitized = query\n .replace(/[*\"():^\\-]/g, ' ') // Remove special chars\n .replace(/\\b(AND|OR|NOT|NEAR)\\b/gi, '') // Remove boolean operators\n .trim()\n .split(/\\s+/)\n .filter(term => term.length > 0 && term.length < 100) // Limit term length\n .slice(0, 20) // Limit number of terms\n .map(term => `\"${term.replace(/\"/g, '')}\"`) // Quote each term safely\n .join(' ');\n\n return sanitized;\n }\n\n /**\n * Search nodes by title or content\n */\n searchNodes(query: string, limit = 50): KnowledgeNode[] {\n const sanitizedQuery = this.sanitizeFtsQuery(query);\n\n // Return empty if no valid search terms\n if (!sanitizedQuery) {\n return [];\n }\n\n // Enforce reasonable limit\n const safeLimit = Math.min(Math.max(1, limit), 100);\n\n const stmt = this.db.prepare(`\n SELECT n.* FROM nodes n\n JOIN nodes_fts fts ON n.rowid = fts.rowid\n WHERE nodes_fts MATCH ?\n ORDER BY rank\n LIMIT ?\n `);\n const rows = stmt.all(sanitizedQuery, safeLimit) as NodeRow[];\n return rows.map(row => this.rowToNode(row));\n }\n\n /**\n * Delete node\n */\n deleteNode(id: string): boolean {\n const stmt = this.db.prepare('DELETE FROM nodes WHERE id = ?');\n const result = stmt.run(id);\n return result.changes > 0;\n }\n\n /**\n * Clear all nodes and edges (for full regeneration)\n */\n clearAll(): void {\n this.db.exec('DELETE FROM edges');\n this.db.exec('DELETE FROM node_tags');\n this.db.exec('DELETE FROM nodes');\n }\n\n // ========================================================================\n // Tag Operations\n // ========================================================================\n\n /**\n * Update tags for a node\n */\n private updateNodeTags(nodeId: string, tags: string[]): void {\n // Remove existing tags\n this.db.prepare('DELETE FROM node_tags WHERE node_id = ?').run(nodeId);\n\n // Insert new tags\n const getOrCreateTag = this.db.prepare(`\n INSERT INTO tags (name) VALUES (?)\n ON CONFLICT(name) DO UPDATE SET name = excluded.name\n RETURNING id\n `);\n\n const insertNodeTag = this.db.prepare(\n 'INSERT OR IGNORE INTO node_tags (node_id, tag_id) VALUES (?, ?)'\n );\n\n for (const tag of tags) {\n const result = getOrCreateTag.get(tag) as { id: number };\n insertNodeTag.run(nodeId, result.id);\n }\n }\n\n /**\n * Get tags for a node\n */\n getNodeTags(nodeId: string): string[] {\n const stmt = this.db.prepare(`\n SELECT t.name FROM tags t\n JOIN node_tags nt ON t.id = nt.tag_id\n WHERE nt.node_id = ?\n ORDER BY t.name\n `);\n const rows = stmt.all(nodeId) as Array<{ name: string }>;\n return rows.map(r => r.name);\n }\n\n /**\n * Get all tags with counts\n */\n getAllTags(): Array<{ name: string; count: number }> {\n const stmt = this.db.prepare(`\n SELECT t.name, COUNT(nt.node_id) as count\n FROM tags t\n LEFT JOIN node_tags nt ON t.id = nt.tag_id\n GROUP BY t.id\n ORDER BY count DESC, t.name\n `);\n return stmt.all() as Array<{ name: string; count: number }>;\n }\n\n // ========================================================================\n // Edge Operations\n // ========================================================================\n\n /**\n * Add edge\n */\n addEdge(edge: GraphEdge): void {\n const stmt = this.db.prepare(`\n INSERT INTO edges (source_id, target_id, type, weight, context)\n VALUES (?, ?, ?, ?, ?)\n `);\n stmt.run(edge.source, edge.target, edge.type, edge.weight, edge.context);\n }\n\n /**\n * Get outgoing edges for a node\n */\n getOutgoingEdges(nodeId: string): GraphEdge[] {\n const stmt = this.db.prepare('SELECT * FROM edges WHERE source_id = ?');\n const rows = stmt.all(nodeId) as EdgeRow[];\n return rows.map(row => this.rowToEdge(row));\n }\n\n /**\n * Get incoming edges for a node\n */\n getIncomingEdges(nodeId: string): GraphEdge[] {\n const stmt = this.db.prepare('SELECT * FROM edges WHERE target_id = ?');\n const rows = stmt.all(nodeId) as EdgeRow[];\n return rows.map(row => this.rowToEdge(row));\n }\n\n /**\n * Delete edges for a node\n */\n deleteNodeEdges(nodeId: string): void {\n this.db.prepare('DELETE FROM edges WHERE source_id = ?').run(nodeId);\n }\n\n // ========================================================================\n // Statistics\n // ========================================================================\n\n /**\n * Get graph statistics\n */\n getStats(): GraphStats {\n const totalNodes = (this.db.prepare('SELECT COUNT(*) as count FROM nodes').get() as { count: number }).count;\n const totalEdges = (this.db.prepare('SELECT COUNT(*) as count FROM edges').get() as { count: number }).count;\n\n const typeStats = this.db.prepare(`\n SELECT type, COUNT(*) as count FROM nodes GROUP BY type\n `).all() as Array<{ type: NodeType; count: number }>;\n\n const statusStats = this.db.prepare(`\n SELECT status, COUNT(*) as count FROM nodes GROUP BY status\n `).all() as Array<{ status: NodeStatus; count: number }>;\n\n const nodesByType: Record<NodeType, number> = {\n concept: 0, technical: 0, feature: 0, primitive: 0,\n service: 0, guide: 0, standard: 0, integration: 0,\n };\n for (const { type, count } of typeStats) {\n nodesByType[type] = count;\n }\n\n const nodesByStatus: Record<NodeStatus, number> = {\n draft: 0, active: 0, deprecated: 0, archived: 0,\n };\n for (const { status, count } of statusStats) {\n nodesByStatus[status] = count;\n }\n\n const orphanNodes = (this.db.prepare(`\n SELECT COUNT(*) as count FROM nodes n\n WHERE NOT EXISTS (SELECT 1 FROM edges e WHERE e.source_id = n.id OR e.target_id = n.id)\n `).get() as { count: number }).count;\n\n const avgLinksPerNode = totalNodes > 0 ? totalEdges / totalNodes : 0;\n\n const mostConnected = this.db.prepare(`\n SELECT n.id, (\n (SELECT COUNT(*) FROM edges WHERE source_id = n.id) +\n (SELECT COUNT(*) FROM edges WHERE target_id = n.id)\n ) as connections\n FROM nodes n\n ORDER BY connections DESC\n LIMIT 5\n `).all() as Array<{ id: string; connections: number }>;\n\n return {\n totalNodes,\n totalEdges,\n nodesByType,\n nodesByStatus,\n orphanNodes,\n avgLinksPerNode: Math.round(avgLinksPerNode * 100) / 100,\n mostConnected,\n };\n }\n\n // ========================================================================\n // Metadata Operations\n // ========================================================================\n\n /**\n * Get metadata value\n */\n getMetadata(key: string): string | null {\n const stmt = this.db.prepare('SELECT value FROM metadata WHERE key = ?');\n const row = stmt.get(key) as { value: string } | undefined;\n return row?.value ?? null;\n }\n\n /**\n * Set metadata value\n */\n setMetadata(key: string, value: string): void {\n const stmt = this.db.prepare(`\n INSERT INTO metadata (key, value, updated_at) VALUES (?, ?, datetime('now'))\n ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = datetime('now')\n `);\n stmt.run(key, value);\n }\n\n // ========================================================================\n // Utilities\n // ========================================================================\n\n /**\n * Convert database row to KnowledgeNode\n */\n private rowToNode(row: NodeRow): KnowledgeNode {\n const tags = this.getNodeTags(row.id);\n const outgoingEdges = this.getOutgoingEdges(row.id);\n const incomingEdges = this.getIncomingEdges(row.id);\n\n return {\n id: row.id,\n path: row.path,\n filename: row.filename,\n title: row.title,\n type: row.type as NodeType,\n status: row.status as NodeStatus,\n content: row.content || '',\n frontmatter: safeJsonParse(row.frontmatter, {}),\n tags,\n outgoingLinks: outgoingEdges.map(e => ({\n target: e.target,\n type: 'wikilink' as const,\n context: e.context,\n })),\n incomingLinks: incomingEdges.map(e => ({\n target: e.source,\n type: 'backlink' as const,\n context: e.context,\n })),\n wordCount: row.word_count,\n lastModified: new Date(row.updated_at),\n };\n }\n\n /**\n * Convert database row to GraphEdge\n */\n private rowToEdge(row: EdgeRow): GraphEdge {\n return {\n source: row.source_id,\n target: row.target_id,\n type: row.type as GraphEdge['type'],\n weight: row.weight,\n context: row.context ?? undefined,\n };\n }\n\n /**\n * Close database connection\n */\n close(): void {\n this.db.close();\n }\n\n /**\n * Get raw database instance\n */\n getDatabase(): Database.Database {\n return this.db;\n }\n}\n\n// Row types for database queries\ninterface NodeRow {\n id: string;\n path: string;\n filename: string;\n title: string;\n type: string;\n status: string;\n content: string | null;\n frontmatter: string | null;\n word_count: number;\n created_at: string;\n updated_at: string;\n}\n\ninterface EdgeRow {\n id: number;\n source_id: string;\n target_id: string;\n type: string;\n weight: number;\n context: string | null;\n created_at: string;\n}\n\n/**\n * Create knowledge graph database instance\n */\nexport function createDatabase(dbPath: string): KnowledgeGraphDatabase {\n return new KnowledgeGraphDatabase(dbPath);\n}\n"],"names":[],"mappings":"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"}
@@ -174,6 +174,8 @@ export interface GeneratorOptions {
174
174
  outputPath: string;
175
175
  includeExamples?: boolean;
176
176
  force?: boolean;
177
+ additionalPaths?: string[];
178
+ scanAll?: boolean;
177
179
  }
178
180
  export interface GeneratedDocument {
179
181
  path: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sources":["../../src/core/types.ts"],"sourcesContent":["/**\n * Knowledge Graph Agent - Core Types\n *\n * Type definitions for the knowledge graph system.\n */\n\nimport { z } from 'zod';\n\n// ============================================================================\n// Node Types\n// ============================================================================\n\nexport type NodeType =\n | 'concept' // Abstract concepts and ideas\n | 'technical' // Technical components and implementations\n | 'feature' // Product features and capabilities\n | 'primitive' // Base technology primitives (frameworks, libraries)\n | 'service' // Backend services and APIs\n | 'guide' // How-to guides and tutorials\n | 'standard' // Coding standards and conventions\n | 'integration'; // External integrations\n\nexport type NodeStatus = 'draft' | 'active' | 'deprecated' | 'archived';\n\nexport interface NodeLink {\n target: string; // Target node filename or path\n type: 'wikilink' | 'markdown' | 'backlink';\n text?: string; // Display text for the link\n context?: string; // Context in which link appears\n}\n\nexport interface NodeFrontmatter {\n title?: string;\n type?: NodeType;\n status?: NodeStatus;\n tags?: string[];\n category?: string;\n description?: string;\n created?: string;\n updated?: string;\n aliases?: string[];\n related?: string[];\n [key: string]: unknown;\n}\n\nexport interface KnowledgeNode {\n id: string;\n path: string;\n filename: string;\n title: string;\n type: NodeType;\n status: NodeStatus;\n content: string;\n frontmatter: NodeFrontmatter;\n tags: string[];\n outgoingLinks: NodeLink[];\n incomingLinks: NodeLink[];\n wordCount: number;\n lastModified: Date;\n}\n\n// ============================================================================\n// Graph Types\n// ============================================================================\n\nexport interface GraphEdge {\n source: string; // Source node ID\n target: string; // Target node ID\n type: 'link' | 'reference' | 'parent' | 'related';\n weight: number; // Relationship strength 0-1\n context?: string;\n}\n\nexport interface KnowledgeGraph {\n nodes: Map<string, KnowledgeNode>;\n edges: GraphEdge[];\n metadata: GraphMetadata;\n}\n\nexport interface GraphMetadata {\n name: string;\n version: string;\n created: string;\n updated: string;\n nodeCount: number;\n edgeCount: number;\n rootPath: string;\n}\n\nexport interface GraphStats {\n totalNodes: number;\n totalEdges: number;\n nodesByType: Record<NodeType, number>;\n nodesByStatus: Record<NodeStatus, number>;\n orphanNodes: number;\n avgLinksPerNode: number;\n mostConnected: Array<{ id: string; connections: number }>;\n}\n\n// ============================================================================\n// Configuration Types\n// ============================================================================\n\nexport const ConfigSchema = z.object({\n // Project settings\n projectRoot: z.string().default('.'),\n docsRoot: z.string().default('./docs'),\n vaultName: z.string().optional(),\n\n // Graph settings\n graph: z.object({\n includePatterns: z.array(z.string()).default(['**/*.md']),\n excludePatterns: z.array(z.string()).default([\n 'node_modules/**',\n 'dist/**',\n '.git/**',\n ]),\n maxDepth: z.number().default(10),\n }).default({}),\n\n // Database settings\n database: z.object({\n path: z.string().default('./.kg/knowledge.db'),\n enableWAL: z.boolean().default(true),\n }).default({}),\n\n // Claude-Flow integration\n claudeFlow: z.object({\n enabled: z.boolean().default(true),\n namespace: z.string().default('knowledge-graph'),\n syncOnChange: z.boolean().default(true),\n }).default({}),\n\n // Templates\n templates: z.object({\n customPath: z.string().optional(),\n defaultType: z.enum(['concept', 'technical', 'feature', 'primitive', 'service', 'guide', 'standard', 'integration']).default('concept'),\n }).default({}),\n});\n\nexport type KGConfig = z.infer<typeof ConfigSchema>;\n\n// ============================================================================\n// Generator Types\n// ============================================================================\n\nexport interface GeneratorOptions {\n projectRoot: string;\n outputPath: string;\n includeExamples?: boolean;\n force?: boolean;\n}\n\nexport interface GeneratedDocument {\n path: string;\n title: string;\n type: NodeType;\n content: string;\n frontmatter: NodeFrontmatter;\n}\n\nexport interface DocsInitOptions {\n projectRoot: string;\n docsPath?: string;\n template?: string;\n includeExamples?: boolean;\n detectFramework?: boolean;\n}\n\nexport interface DocsInitResult {\n success: boolean;\n docsPath: string;\n filesCreated: string[];\n errors: string[];\n}\n\n// ============================================================================\n// Claude-Flow Integration Types\n// ============================================================================\n\nexport interface MemoryEntry {\n key: string;\n value: unknown;\n namespace?: string;\n ttl?: number;\n metadata?: Record<string, unknown>;\n}\n\nexport interface SyncResult {\n synced: number;\n failed: number;\n errors: Array<{ key: string; error: string }>;\n}\n\n// ============================================================================\n// CLAUDE.md Template Types\n// ============================================================================\n\nexport interface ClaudeMdSection {\n title: string;\n content: string;\n order: number;\n}\n\nexport interface ClaudeMdTemplate {\n name: string;\n description: string;\n sections: ClaudeMdSection[];\n variables: Record<string, string>;\n}\n\nexport interface ClaudeMdGeneratorOptions {\n projectRoot: string;\n outputPath?: string;\n template?: string;\n includeKnowledgeGraph?: boolean;\n includeClaudeFlow?: boolean;\n customSections?: ClaudeMdSection[];\n}\n"],"names":[],"mappings":";AAuGO,MAAM,eAAe,EAAE,OAAO;AAAA;AAAA,EAEnC,aAAa,EAAE,SAAS,QAAQ,GAAG;AAAA,EACnC,UAAU,EAAE,SAAS,QAAQ,QAAQ;AAAA,EACrC,WAAW,EAAE,OAAA,EAAS,SAAA;AAAA;AAAA,EAGtB,OAAO,EAAE,OAAO;AAAA,IACd,iBAAiB,EAAE,MAAM,EAAE,OAAA,CAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC;AAAA,IACxD,iBAAiB,EAAE,MAAM,EAAE,OAAA,CAAQ,EAAE,QAAQ;AAAA,MAC3C;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AAAA,IACD,UAAU,EAAE,OAAA,EAAS,QAAQ,EAAE;AAAA,EAAA,CAChC,EAAE,QAAQ,EAAE;AAAA;AAAA,EAGb,UAAU,EAAE,OAAO;AAAA,IACjB,MAAM,EAAE,SAAS,QAAQ,oBAAoB;AAAA,IAC7C,WAAW,EAAE,QAAA,EAAU,QAAQ,IAAI;AAAA,EAAA,CACpC,EAAE,QAAQ,EAAE;AAAA;AAAA,EAGb,YAAY,EAAE,OAAO;AAAA,IACnB,SAAS,EAAE,UAAU,QAAQ,IAAI;AAAA,IACjC,WAAW,EAAE,SAAS,QAAQ,iBAAiB;AAAA,IAC/C,cAAc,EAAE,QAAA,EAAU,QAAQ,IAAI;AAAA,EAAA,CACvC,EAAE,QAAQ,EAAE;AAAA;AAAA,EAGb,WAAW,EAAE,OAAO;AAAA,IAClB,YAAY,EAAE,OAAA,EAAS,SAAA;AAAA,IACvB,aAAa,EAAE,KAAK,CAAC,WAAW,aAAa,WAAW,aAAa,WAAW,SAAS,YAAY,aAAa,CAAC,EAAE,QAAQ,SAAS;AAAA,EAAA,CACvI,EAAE,QAAQ,CAAA,CAAE;AACf,CAAC;"}
1
+ {"version":3,"file":"types.js","sources":["../../src/core/types.ts"],"sourcesContent":["/**\n * Knowledge Graph Agent - Core Types\n *\n * Type definitions for the knowledge graph system.\n */\n\nimport { z } from 'zod';\n\n// ============================================================================\n// Node Types\n// ============================================================================\n\nexport type NodeType =\n | 'concept' // Abstract concepts and ideas\n | 'technical' // Technical components and implementations\n | 'feature' // Product features and capabilities\n | 'primitive' // Base technology primitives (frameworks, libraries)\n | 'service' // Backend services and APIs\n | 'guide' // How-to guides and tutorials\n | 'standard' // Coding standards and conventions\n | 'integration'; // External integrations\n\nexport type NodeStatus = 'draft' | 'active' | 'deprecated' | 'archived';\n\nexport interface NodeLink {\n target: string; // Target node filename or path\n type: 'wikilink' | 'markdown' | 'backlink';\n text?: string; // Display text for the link\n context?: string; // Context in which link appears\n}\n\nexport interface NodeFrontmatter {\n title?: string;\n type?: NodeType;\n status?: NodeStatus;\n tags?: string[];\n category?: string;\n description?: string;\n created?: string;\n updated?: string;\n aliases?: string[];\n related?: string[];\n [key: string]: unknown;\n}\n\nexport interface KnowledgeNode {\n id: string;\n path: string;\n filename: string;\n title: string;\n type: NodeType;\n status: NodeStatus;\n content: string;\n frontmatter: NodeFrontmatter;\n tags: string[];\n outgoingLinks: NodeLink[];\n incomingLinks: NodeLink[];\n wordCount: number;\n lastModified: Date;\n}\n\n// ============================================================================\n// Graph Types\n// ============================================================================\n\nexport interface GraphEdge {\n source: string; // Source node ID\n target: string; // Target node ID\n type: 'link' | 'reference' | 'parent' | 'related';\n weight: number; // Relationship strength 0-1\n context?: string;\n}\n\nexport interface KnowledgeGraph {\n nodes: Map<string, KnowledgeNode>;\n edges: GraphEdge[];\n metadata: GraphMetadata;\n}\n\nexport interface GraphMetadata {\n name: string;\n version: string;\n created: string;\n updated: string;\n nodeCount: number;\n edgeCount: number;\n rootPath: string;\n}\n\nexport interface GraphStats {\n totalNodes: number;\n totalEdges: number;\n nodesByType: Record<NodeType, number>;\n nodesByStatus: Record<NodeStatus, number>;\n orphanNodes: number;\n avgLinksPerNode: number;\n mostConnected: Array<{ id: string; connections: number }>;\n}\n\n// ============================================================================\n// Configuration Types\n// ============================================================================\n\nexport const ConfigSchema = z.object({\n // Project settings\n projectRoot: z.string().default('.'),\n docsRoot: z.string().default('./docs'),\n vaultName: z.string().optional(),\n\n // Graph settings\n graph: z.object({\n includePatterns: z.array(z.string()).default(['**/*.md']),\n excludePatterns: z.array(z.string()).default([\n 'node_modules/**',\n 'dist/**',\n '.git/**',\n ]),\n maxDepth: z.number().default(10),\n }).default({}),\n\n // Database settings\n database: z.object({\n path: z.string().default('./.kg/knowledge.db'),\n enableWAL: z.boolean().default(true),\n }).default({}),\n\n // Claude-Flow integration\n claudeFlow: z.object({\n enabled: z.boolean().default(true),\n namespace: z.string().default('knowledge-graph'),\n syncOnChange: z.boolean().default(true),\n }).default({}),\n\n // Templates\n templates: z.object({\n customPath: z.string().optional(),\n defaultType: z.enum(['concept', 'technical', 'feature', 'primitive', 'service', 'guide', 'standard', 'integration']).default('concept'),\n }).default({}),\n});\n\nexport type KGConfig = z.infer<typeof ConfigSchema>;\n\n// ============================================================================\n// Generator Types\n// ============================================================================\n\nexport interface GeneratorOptions {\n projectRoot: string;\n outputPath: string;\n includeExamples?: boolean;\n force?: boolean;\n additionalPaths?: string[];\n scanAll?: boolean;\n}\n\nexport interface GeneratedDocument {\n path: string;\n title: string;\n type: NodeType;\n content: string;\n frontmatter: NodeFrontmatter;\n}\n\nexport interface DocsInitOptions {\n projectRoot: string;\n docsPath?: string;\n template?: string;\n includeExamples?: boolean;\n detectFramework?: boolean;\n}\n\nexport interface DocsInitResult {\n success: boolean;\n docsPath: string;\n filesCreated: string[];\n errors: string[];\n}\n\n// ============================================================================\n// Claude-Flow Integration Types\n// ============================================================================\n\nexport interface MemoryEntry {\n key: string;\n value: unknown;\n namespace?: string;\n ttl?: number;\n metadata?: Record<string, unknown>;\n}\n\nexport interface SyncResult {\n synced: number;\n failed: number;\n errors: Array<{ key: string; error: string }>;\n}\n\n// ============================================================================\n// CLAUDE.md Template Types\n// ============================================================================\n\nexport interface ClaudeMdSection {\n title: string;\n content: string;\n order: number;\n}\n\nexport interface ClaudeMdTemplate {\n name: string;\n description: string;\n sections: ClaudeMdSection[];\n variables: Record<string, string>;\n}\n\nexport interface ClaudeMdGeneratorOptions {\n projectRoot: string;\n outputPath?: string;\n template?: string;\n includeKnowledgeGraph?: boolean;\n includeClaudeFlow?: boolean;\n customSections?: ClaudeMdSection[];\n}\n"],"names":[],"mappings":";AAuGO,MAAM,eAAe,EAAE,OAAO;AAAA;AAAA,EAEnC,aAAa,EAAE,SAAS,QAAQ,GAAG;AAAA,EACnC,UAAU,EAAE,SAAS,QAAQ,QAAQ;AAAA,EACrC,WAAW,EAAE,OAAA,EAAS,SAAA;AAAA;AAAA,EAGtB,OAAO,EAAE,OAAO;AAAA,IACd,iBAAiB,EAAE,MAAM,EAAE,OAAA,CAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC;AAAA,IACxD,iBAAiB,EAAE,MAAM,EAAE,OAAA,CAAQ,EAAE,QAAQ;AAAA,MAC3C;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AAAA,IACD,UAAU,EAAE,OAAA,EAAS,QAAQ,EAAE;AAAA,EAAA,CAChC,EAAE,QAAQ,EAAE;AAAA;AAAA,EAGb,UAAU,EAAE,OAAO;AAAA,IACjB,MAAM,EAAE,SAAS,QAAQ,oBAAoB;AAAA,IAC7C,WAAW,EAAE,QAAA,EAAU,QAAQ,IAAI;AAAA,EAAA,CACpC,EAAE,QAAQ,EAAE;AAAA;AAAA,EAGb,YAAY,EAAE,OAAO;AAAA,IACnB,SAAS,EAAE,UAAU,QAAQ,IAAI;AAAA,IACjC,WAAW,EAAE,SAAS,QAAQ,iBAAiB;AAAA,IAC/C,cAAc,EAAE,QAAA,EAAU,QAAQ,IAAI;AAAA,EAAA,CACvC,EAAE,QAAQ,EAAE;AAAA;AAAA,EAGb,WAAW,EAAE,OAAO;AAAA,IAClB,YAAY,EAAE,OAAA,EAAS,SAAA;AAAA,IACvB,aAAa,EAAE,KAAK,CAAC,WAAW,aAAa,WAAW,aAAa,WAAW,SAAS,YAAY,aAAa,CAAC,EAAE,QAAQ,SAAS;AAAA,EAAA,CACvI,EAAE,QAAQ,CAAA,CAAE;AACf,CAAC;"}
@@ -6,7 +6,7 @@
6
6
  import type { GeneratorOptions } from '../core/types.js';
7
7
  import { KnowledgeGraphManager } from '../core/graph.js';
8
8
  /**
9
- * Generate knowledge graph from docs directory
9
+ * Generate knowledge graph from docs directory (or multiple directories)
10
10
  */
11
11
  export declare function generateGraph(options: GeneratorOptions): Promise<{
12
12
  graph: KnowledgeGraphManager;
@@ -32,7 +32,7 @@ export declare function generateAndSave(options: GeneratorOptions, dbPath: strin
32
32
  /**
33
33
  * Generate graph from existing database (incremental update)
34
34
  */
35
- export declare function updateGraph(dbPath: string, docsRoot: string): Promise<{
35
+ export declare function updateGraph(dbPath: string, docsRoot: string, allPaths?: string[]): Promise<{
36
36
  added: number;
37
37
  updated: number;
38
38
  removed: number;
@@ -1 +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"}
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,CAgGD;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,CAgCD;AAgND;;GAEG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,EAAE,GAClB,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,CAgFD"}
@@ -7,7 +7,7 @@ import { KnowledgeGraphDatabase } from "../core/database.js";
7
7
  const WIKILINK_PATTERN = /\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g;
8
8
  const MARKDOWN_LINK_PATTERN = /\[([^\]]+)\]\(([^)]+)\)/g;
9
9
  async function generateGraph(options) {
10
- const { projectRoot, outputPath } = options;
10
+ const { projectRoot, outputPath, additionalPaths = [], scanAll } = options;
11
11
  const stats = {
12
12
  filesScanned: 0,
13
13
  nodesCreated: 0,
@@ -18,18 +18,39 @@ async function generateGraph(options) {
18
18
  basename(projectRoot),
19
19
  projectRoot
20
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;
21
+ const pathsToScan = scanAll ? [projectRoot] : [outputPath, ...additionalPaths];
22
+ const allFiles = [];
23
+ for (const scanPath of pathsToScan) {
24
+ const files = await fg("**/*.md", {
25
+ cwd: scanPath,
26
+ ignore: [
27
+ "node_modules/**",
28
+ ".git/**",
29
+ "**/_templates/**",
30
+ // Templates anywhere in tree
31
+ "**/dist/**",
32
+ "**/build/**",
33
+ "**/.hive-mind/**"
34
+ // Hive mind internal files
35
+ ],
36
+ absolute: true,
37
+ dot: true
38
+ // Include hidden directories like .claude/
39
+ });
40
+ for (const filePath of files) {
41
+ allFiles.push({ filePath, baseDir: projectRoot });
42
+ }
43
+ }
44
+ stats.filesScanned = allFiles.length;
27
45
  const nodeMap = /* @__PURE__ */ new Map();
28
- for (const filePath of files) {
46
+ for (const { filePath, baseDir } of allFiles) {
29
47
  try {
30
- const node = await parseMarkdownFile(filePath, outputPath);
31
- nodeMap.set(node.id, node);
32
- stats.nodesCreated++;
48
+ const node = await parseMarkdownFile(filePath, baseDir);
49
+ const uniqueId = scanAll ? node.id : node.id;
50
+ if (!nodeMap.has(uniqueId)) {
51
+ nodeMap.set(uniqueId, node);
52
+ stats.nodesCreated++;
53
+ }
33
54
  } catch (error) {
34
55
  stats.errors.push(`Failed to parse ${filePath}: ${error}`);
35
56
  }
@@ -63,6 +84,7 @@ async function generateAndSave(options, dbPath) {
63
84
  const { graph, stats } = await generateGraph(options);
64
85
  const db = new KnowledgeGraphDatabase(dbPath);
65
86
  try {
87
+ db.clearAll();
66
88
  const nodes = graph.getAllNodes();
67
89
  const edges = graph.getAllEdges();
68
90
  for (const node of nodes) {
@@ -211,7 +233,7 @@ function inferNodeType(declaredType, path) {
211
233
  function formatTitle(filename) {
212
234
  return filename.replace(/-/g, " ").replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
213
235
  }
214
- async function updateGraph(dbPath, docsRoot) {
236
+ async function updateGraph(dbPath, docsRoot, allPaths) {
215
237
  const result = {
216
238
  added: 0,
217
239
  updated: 0,
@@ -222,23 +244,41 @@ async function updateGraph(dbPath, docsRoot) {
222
244
  try {
223
245
  const existingNodes = db.getAllNodes();
224
246
  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);
247
+ const pathsToScan = allPaths || [docsRoot];
248
+ const allCurrentFiles = [];
249
+ for (const scanPath of pathsToScan) {
250
+ const files = await fg("**/*.md", {
251
+ cwd: scanPath,
252
+ ignore: [
253
+ "node_modules/**",
254
+ ".git/**",
255
+ "**/_templates/**",
256
+ // Templates anywhere in tree
257
+ "**/dist/**",
258
+ "**/build/**",
259
+ "**/.hive-mind/**"
260
+ // Hive mind internal files
261
+ ],
262
+ dot: true
263
+ // Include hidden directories like .claude/
264
+ });
265
+ for (const file of files) {
266
+ allCurrentFiles.push({ filePath: file, baseDir: scanPath });
267
+ }
268
+ }
269
+ const currentPaths = new Set(allCurrentFiles.map((f) => f.filePath));
230
270
  for (const node of existingNodes) {
231
271
  if (!currentPaths.has(node.path)) {
232
272
  db.deleteNode(node.id);
233
273
  result.removed++;
234
274
  }
235
275
  }
236
- for (const filePath of currentFiles) {
237
- const fullPath = join(docsRoot, filePath);
276
+ for (const { filePath, baseDir } of allCurrentFiles) {
277
+ const fullPath = join(baseDir, filePath);
238
278
  try {
239
- const node = await parseMarkdownFile(fullPath, docsRoot);
240
- if (existingPaths.has(filePath)) {
241
- const existing = existingNodes.find((n) => n.path === filePath);
279
+ const node = await parseMarkdownFile(fullPath, baseDir);
280
+ if (existingPaths.has(node.path)) {
281
+ const existing = existingNodes.find((n) => n.path === node.path);
242
282
  if (existing && node.lastModified > existing.lastModified) {
243
283
  db.deleteNodeEdges(node.id);
244
284
  db.upsertNode(node);
@@ -1 +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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"}
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 (or multiple directories)\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, additionalPaths = [], scanAll } = 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 // Build list of all paths to scan\n const pathsToScan = scanAll ? [projectRoot] : [outputPath, ...additionalPaths];\n\n // Find all markdown files from all paths\n const allFiles: Array<{ filePath: string; baseDir: string }> = [];\n\n for (const scanPath of pathsToScan) {\n const files = await fg('**/*.md', {\n cwd: scanPath,\n ignore: [\n 'node_modules/**',\n '.git/**',\n '**/_templates/**', // Templates anywhere in tree\n '**/dist/**',\n '**/build/**',\n '**/.hive-mind/**', // Hive mind internal files\n ],\n absolute: true,\n dot: true, // Include hidden directories like .claude/\n });\n\n for (const filePath of files) {\n // Always use project root as base for consistent IDs\n allFiles.push({ filePath, baseDir: projectRoot });\n }\n }\n\n stats.filesScanned = allFiles.length;\n\n // First pass: Create all nodes\n const nodeMap = new Map<string, KnowledgeNode>();\n\n for (const { filePath, baseDir } of allFiles) {\n try {\n const node = await parseMarkdownFile(filePath, baseDir);\n // Avoid duplicate IDs by using full relative path from project root\n const uniqueId = scanAll ? node.id : node.id;\n if (!nodeMap.has(uniqueId)) {\n nodeMap.set(uniqueId, node);\n stats.nodesCreated++;\n }\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 // Clear existing data before full regeneration to prevent duplicates\n db.clearAll();\n\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 allPaths?: 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 // Paths to scan\n const pathsToScan = allPaths || [docsRoot];\n\n // Find current files from all paths\n const allCurrentFiles: Array<{ filePath: string; baseDir: string }> = [];\n\n for (const scanPath of pathsToScan) {\n const files = await fg('**/*.md', {\n cwd: scanPath,\n ignore: [\n 'node_modules/**',\n '.git/**',\n '**/_templates/**', // Templates anywhere in tree\n '**/dist/**',\n '**/build/**',\n '**/.hive-mind/**', // Hive mind internal files\n ],\n dot: true, // Include hidden directories like .claude/\n });\n\n for (const file of files) {\n allCurrentFiles.push({ filePath: file, baseDir: scanPath });\n }\n }\n\n const currentPaths = new Set(allCurrentFiles.map(f => f.filePath));\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, baseDir } of allCurrentFiles) {\n const fullPath = join(baseDir, filePath);\n\n try {\n const node = await parseMarkdownFile(fullPath, baseDir);\n\n if (existingPaths.has(node.path)) {\n // Check if file was modified\n const existing = existingNodes.find(n => n.path === node.path);\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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"}
@@ -1,4 +1,4 @@
1
- import { __exports as dist } from "../../../../_virtual/index6.js";
1
+ import { __exports as dist } from "../../../../_virtual/index5.js";
2
2
  import { __require as requireAstSpec } from "./generated/ast-spec.js";
3
3
  import { __require as requireLib } from "./lib.js";
4
4
  import { __require as requireParserOptions } from "./parser-options.js";
@@ -1,4 +1,4 @@
1
- import { __exports as dist } from "../../../../_virtual/index5.js";
1
+ import { __exports as dist } from "../../../../_virtual/index6.js";
2
2
  import { __require as requireGetKeys } from "./get-keys.js";
3
3
  import { __require as requireVisitorKeys } from "./visitor-keys.js";
4
4
  var hasRequiredDist;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weavelogic/knowledge-graph-agent",
3
- "version": "0.8.1",
3
+ "version": "0.8.3",
4
4
  "description": "Knowledge graph agent for Claude Code - generates knowledge graphs, initializes docs, and integrates with claude-flow",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",