@weavelogic/knowledge-graph-agent 0.6.0 → 0.7.1

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.
Files changed (219) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +70 -3
  3. package/dist/_virtual/__vite-browser-external.js +2 -2
  4. package/dist/_virtual/__vite-browser-external.js.map +1 -1
  5. package/dist/_virtual/index12.js +7 -0
  6. package/dist/_virtual/index12.js.map +1 -0
  7. package/dist/_virtual/ort-web.min.js +8 -0
  8. package/dist/_virtual/ort-web.min.js.map +1 -0
  9. package/dist/_virtual/ort-web.min2.js +5 -0
  10. package/dist/_virtual/ort-web.min2.js.map +1 -0
  11. package/dist/agents/base-agent.d.ts +63 -0
  12. package/dist/agents/base-agent.d.ts.map +1 -1
  13. package/dist/agents/base-agent.js +139 -0
  14. package/dist/agents/base-agent.js.map +1 -1
  15. package/dist/agents/coordinator-agent.d.ts +422 -0
  16. package/dist/agents/coordinator-agent.d.ts.map +1 -0
  17. package/dist/agents/documenter-agent.d.ts +298 -0
  18. package/dist/agents/documenter-agent.d.ts.map +1 -0
  19. package/dist/agents/index.d.ts +11 -1
  20. package/dist/agents/index.d.ts.map +1 -1
  21. package/dist/agents/index.js +4 -0
  22. package/dist/agents/index.js.map +1 -1
  23. package/dist/agents/mixins/index.d.ts +9 -0
  24. package/dist/agents/mixins/index.d.ts.map +1 -0
  25. package/dist/agents/mixins/trajectory-mixin.d.ts +112 -0
  26. package/dist/agents/mixins/trajectory-mixin.d.ts.map +1 -0
  27. package/dist/agents/optimizer-agent.d.ts +388 -0
  28. package/dist/agents/optimizer-agent.d.ts.map +1 -0
  29. package/dist/agents/planner-agent.d.ts +395 -0
  30. package/dist/agents/planner-agent.d.ts.map +1 -0
  31. package/dist/agents/registry.d.ts.map +1 -1
  32. package/dist/agents/registry.js +5 -0
  33. package/dist/agents/registry.js.map +1 -1
  34. package/dist/agents/reviewer-agent.d.ts +330 -0
  35. package/dist/agents/reviewer-agent.d.ts.map +1 -0
  36. package/dist/agents/types.d.ts +12 -1
  37. package/dist/agents/types.d.ts.map +1 -1
  38. package/dist/agents/types.js +1 -0
  39. package/dist/agents/types.js.map +1 -1
  40. package/dist/cli/commands/hive-mind/add-frontmatter.d.ts +102 -0
  41. package/dist/cli/commands/hive-mind/add-frontmatter.d.ts.map +1 -0
  42. package/dist/cli/commands/hive-mind/add-frontmatter.js +439 -0
  43. package/dist/cli/commands/hive-mind/add-frontmatter.js.map +1 -0
  44. package/dist/cli/commands/hive-mind/analyze-links.d.ts +80 -0
  45. package/dist/cli/commands/hive-mind/analyze-links.d.ts.map +1 -0
  46. package/dist/cli/commands/hive-mind/analyze-links.js +367 -0
  47. package/dist/cli/commands/hive-mind/analyze-links.js.map +1 -0
  48. package/dist/cli/commands/hive-mind/find-connections.d.ts +75 -0
  49. package/dist/cli/commands/hive-mind/find-connections.d.ts.map +1 -0
  50. package/dist/cli/commands/hive-mind/find-connections.js +347 -0
  51. package/dist/cli/commands/hive-mind/find-connections.js.map +1 -0
  52. package/dist/cli/commands/hive-mind/index.d.ts +37 -0
  53. package/dist/cli/commands/hive-mind/index.d.ts.map +1 -0
  54. package/dist/cli/commands/hive-mind/index.js +33 -0
  55. package/dist/cli/commands/hive-mind/index.js.map +1 -0
  56. package/dist/cli/commands/hive-mind/validate-names.d.ts +79 -0
  57. package/dist/cli/commands/hive-mind/validate-names.d.ts.map +1 -0
  58. package/dist/cli/commands/hive-mind/validate-names.js +353 -0
  59. package/dist/cli/commands/hive-mind/validate-names.js.map +1 -0
  60. package/dist/cli/commands/vector.js +2 -0
  61. package/dist/cli/commands/vector.js.map +1 -1
  62. package/dist/cli/index.d.ts.map +1 -1
  63. package/dist/cli/index.js +7 -0
  64. package/dist/cli/index.js.map +1 -1
  65. package/dist/equilibrium/agent-equilibrium.d.ts +194 -0
  66. package/dist/equilibrium/agent-equilibrium.d.ts.map +1 -0
  67. package/dist/equilibrium/agent-equilibrium.js +304 -0
  68. package/dist/equilibrium/agent-equilibrium.js.map +1 -0
  69. package/dist/equilibrium/graph-equilibrium.d.ts +177 -0
  70. package/dist/equilibrium/graph-equilibrium.d.ts.map +1 -0
  71. package/dist/equilibrium/index.d.ts +11 -0
  72. package/dist/equilibrium/index.d.ts.map +1 -0
  73. package/dist/equilibrium/memory-equilibrium.d.ts +153 -0
  74. package/dist/equilibrium/memory-equilibrium.d.ts.map +1 -0
  75. package/dist/graphql/resolvers/index.d.ts.map +1 -1
  76. package/dist/graphql/resolvers/queries.d.ts +11 -0
  77. package/dist/graphql/resolvers/queries.d.ts.map +1 -1
  78. package/dist/index.d.ts +2 -0
  79. package/dist/index.d.ts.map +1 -1
  80. package/dist/index.js +10 -4
  81. package/dist/index.js.map +1 -1
  82. package/dist/inference/index.d.ts +9 -0
  83. package/dist/inference/index.d.ts.map +1 -0
  84. package/dist/inference/model-selection.d.ts +131 -0
  85. package/dist/inference/model-selection.d.ts.map +1 -0
  86. package/dist/integrations/agentic-flow/adapters/agent-booster-adapter.d.ts +265 -0
  87. package/dist/integrations/agentic-flow/adapters/agent-booster-adapter.d.ts.map +1 -0
  88. package/dist/integrations/agentic-flow/adapters/agentdb-adapter.d.ts +197 -0
  89. package/dist/integrations/agentic-flow/adapters/agentdb-adapter.d.ts.map +1 -0
  90. package/dist/integrations/agentic-flow/adapters/agentdb-vector-store.d.ts +249 -0
  91. package/dist/integrations/agentic-flow/adapters/agentdb-vector-store.d.ts.map +1 -0
  92. package/dist/integrations/agentic-flow/adapters/base-adapter.d.ts +120 -0
  93. package/dist/integrations/agentic-flow/adapters/base-adapter.d.ts.map +1 -0
  94. package/dist/integrations/agentic-flow/adapters/federation-hub-adapter.d.ts +444 -0
  95. package/dist/integrations/agentic-flow/adapters/federation-hub-adapter.d.ts.map +1 -0
  96. package/dist/integrations/agentic-flow/adapters/index.d.ts +17 -0
  97. package/dist/integrations/agentic-flow/adapters/index.d.ts.map +1 -0
  98. package/dist/integrations/agentic-flow/adapters/model-router-adapter.d.ts +242 -0
  99. package/dist/integrations/agentic-flow/adapters/model-router-adapter.d.ts.map +1 -0
  100. package/dist/integrations/agentic-flow/adapters/quic-transport-adapter.d.ts +364 -0
  101. package/dist/integrations/agentic-flow/adapters/quic-transport-adapter.d.ts.map +1 -0
  102. package/dist/integrations/agentic-flow/adapters/reasoning-bank-adapter.d.ts +209 -0
  103. package/dist/integrations/agentic-flow/adapters/reasoning-bank-adapter.d.ts.map +1 -0
  104. package/dist/integrations/agentic-flow/benchmark/index.d.ts +9 -0
  105. package/dist/integrations/agentic-flow/benchmark/index.d.ts.map +1 -0
  106. package/dist/integrations/agentic-flow/benchmark/vector-benchmark.d.ts +253 -0
  107. package/dist/integrations/agentic-flow/benchmark/vector-benchmark.d.ts.map +1 -0
  108. package/dist/integrations/agentic-flow/config.d.ts +109 -0
  109. package/dist/integrations/agentic-flow/config.d.ts.map +1 -0
  110. package/dist/integrations/agentic-flow/feature-flags.d.ts +140 -0
  111. package/dist/integrations/agentic-flow/feature-flags.d.ts.map +1 -0
  112. package/dist/integrations/agentic-flow/index.d.ts +22 -0
  113. package/dist/integrations/agentic-flow/index.d.ts.map +1 -0
  114. package/dist/integrations/agentic-flow/migration/index.d.ts +9 -0
  115. package/dist/integrations/agentic-flow/migration/index.d.ts.map +1 -0
  116. package/dist/integrations/agentic-flow/migration/migrate-to-agentdb.d.ts +242 -0
  117. package/dist/integrations/agentic-flow/migration/migrate-to-agentdb.d.ts.map +1 -0
  118. package/dist/learning/index.d.ts +91 -0
  119. package/dist/learning/index.d.ts.map +1 -0
  120. package/dist/learning/learning-loop.d.ts +176 -0
  121. package/dist/learning/learning-loop.d.ts.map +1 -0
  122. package/dist/learning/services/ab-testing-framework.d.ts +135 -0
  123. package/dist/learning/services/ab-testing-framework.d.ts.map +1 -0
  124. package/dist/learning/services/agent-priming-service.d.ts +207 -0
  125. package/dist/learning/services/agent-priming-service.d.ts.map +1 -0
  126. package/dist/learning/services/daily-log-generator.d.ts +113 -0
  127. package/dist/learning/services/daily-log-generator.d.ts.map +1 -0
  128. package/dist/learning/services/index.d.ts +14 -0
  129. package/dist/learning/services/index.d.ts.map +1 -0
  130. package/dist/learning/services/memory-extraction-service.d.ts +87 -0
  131. package/dist/learning/services/memory-extraction-service.d.ts.map +1 -0
  132. package/dist/learning/services/task-completion-consumer.d.ts +162 -0
  133. package/dist/learning/services/task-completion-consumer.d.ts.map +1 -0
  134. package/dist/learning/services/trajectory-tracker.d.ts +174 -0
  135. package/dist/learning/services/trajectory-tracker.d.ts.map +1 -0
  136. package/dist/learning/types.d.ts +516 -0
  137. package/dist/learning/types.d.ts.map +1 -0
  138. package/dist/mcp/clients/claude-flow-memory-client.d.ts +259 -0
  139. package/dist/mcp/clients/claude-flow-memory-client.d.ts.map +1 -0
  140. package/dist/mcp/clients/claude-flow-memory-client.js +305 -0
  141. package/dist/mcp/clients/claude-flow-memory-client.js.map +1 -0
  142. package/dist/mcp/clients/index.d.ts +11 -0
  143. package/dist/mcp/clients/index.d.ts.map +1 -0
  144. package/dist/mcp/clients/mcp-client-adapter.d.ts +146 -0
  145. package/dist/mcp/clients/mcp-client-adapter.d.ts.map +1 -0
  146. package/dist/mcp/clients/mcp-client-adapter.js +372 -0
  147. package/dist/mcp/clients/mcp-client-adapter.js.map +1 -0
  148. package/dist/mcp/index.d.ts +10 -0
  149. package/dist/mcp/index.d.ts.map +1 -0
  150. package/dist/memory/vault-sync.d.ts +12 -0
  151. package/dist/memory/vault-sync.d.ts.map +1 -1
  152. package/dist/memory/vault-sync.js +94 -11
  153. package/dist/memory/vault-sync.js.map +1 -1
  154. package/dist/node_modules/@huggingface/jinja/dist/index.js +118 -0
  155. package/dist/node_modules/@huggingface/jinja/dist/index.js.map +1 -0
  156. package/dist/node_modules/@typescript-eslint/project-service/dist/index.js +1 -1
  157. package/dist/node_modules/@xenova/transformers/src/backends/onnx.js +24 -0
  158. package/dist/node_modules/@xenova/transformers/src/backends/onnx.js.map +1 -0
  159. package/dist/node_modules/@xenova/transformers/src/configs.js +52 -0
  160. package/dist/node_modules/@xenova/transformers/src/configs.js.map +1 -0
  161. package/dist/node_modules/@xenova/transformers/src/env.js +35 -0
  162. package/dist/node_modules/@xenova/transformers/src/env.js.map +1 -0
  163. package/dist/node_modules/@xenova/transformers/src/models.js +3852 -0
  164. package/dist/node_modules/@xenova/transformers/src/models.js.map +1 -0
  165. package/dist/node_modules/@xenova/transformers/src/tokenizers.js +144 -0
  166. package/dist/node_modules/@xenova/transformers/src/tokenizers.js.map +1 -0
  167. package/dist/node_modules/@xenova/transformers/src/utils/core.js +52 -0
  168. package/dist/node_modules/@xenova/transformers/src/utils/core.js.map +1 -0
  169. package/dist/node_modules/@xenova/transformers/src/utils/generation.js +623 -0
  170. package/dist/node_modules/@xenova/transformers/src/utils/generation.js.map +1 -0
  171. package/dist/node_modules/@xenova/transformers/src/utils/hub.js +395 -0
  172. package/dist/node_modules/@xenova/transformers/src/utils/hub.js.map +1 -0
  173. package/dist/node_modules/@xenova/transformers/src/utils/image.js +12 -0
  174. package/dist/node_modules/@xenova/transformers/src/utils/image.js.map +1 -0
  175. package/dist/node_modules/@xenova/transformers/src/utils/maths.js +89 -0
  176. package/dist/node_modules/@xenova/transformers/src/utils/maths.js.map +1 -0
  177. package/dist/node_modules/@xenova/transformers/src/utils/tensor.js +750 -0
  178. package/dist/node_modules/@xenova/transformers/src/utils/tensor.js.map +1 -0
  179. package/dist/node_modules/fdir/dist/index.js +13 -13
  180. package/dist/node_modules/fdir/dist/index.js.map +1 -1
  181. package/dist/node_modules/onnxruntime-common/dist/lib/backend-impl.js +67 -0
  182. package/dist/node_modules/onnxruntime-common/dist/lib/backend-impl.js.map +1 -0
  183. package/dist/node_modules/onnxruntime-common/dist/lib/env-impl.js +24 -0
  184. package/dist/node_modules/onnxruntime-common/dist/lib/env-impl.js.map +1 -0
  185. package/dist/node_modules/onnxruntime-common/dist/lib/env.js +6 -0
  186. package/dist/node_modules/onnxruntime-common/dist/lib/env.js.map +1 -0
  187. package/dist/node_modules/onnxruntime-common/dist/lib/index.js +11 -0
  188. package/dist/node_modules/onnxruntime-common/dist/lib/index.js.map +1 -0
  189. package/dist/node_modules/onnxruntime-common/dist/lib/inference-session-impl.js +162 -0
  190. package/dist/node_modules/onnxruntime-common/dist/lib/inference-session-impl.js.map +1 -0
  191. package/dist/node_modules/onnxruntime-common/dist/lib/inference-session.js +6 -0
  192. package/dist/node_modules/onnxruntime-common/dist/lib/inference-session.js.map +1 -0
  193. package/dist/node_modules/onnxruntime-common/dist/lib/tensor-impl.js +393 -0
  194. package/dist/node_modules/onnxruntime-common/dist/lib/tensor-impl.js.map +1 -0
  195. package/dist/node_modules/onnxruntime-common/dist/lib/tensor.js +6 -0
  196. package/dist/node_modules/onnxruntime-common/dist/lib/tensor.js.map +1 -0
  197. package/dist/node_modules/onnxruntime-web/dist/ort-web.min.js +12919 -0
  198. package/dist/node_modules/onnxruntime-web/dist/ort-web.min.js.map +1 -0
  199. package/dist/node_modules/tinyglobby/dist/index.js +14 -14
  200. package/dist/node_modules/tinyglobby/dist/index.js.map +1 -1
  201. package/dist/node_modules/typescript/lib/typescript.js +24 -24
  202. package/dist/node_modules/typescript/lib/typescript.js.map +1 -1
  203. package/dist/transport/agent-transport.d.ts +269 -0
  204. package/dist/transport/agent-transport.d.ts.map +1 -0
  205. package/dist/transport/index.d.ts +10 -0
  206. package/dist/transport/index.d.ts.map +1 -0
  207. package/dist/vector/index.d.ts +1 -1
  208. package/dist/vector/index.d.ts.map +1 -1
  209. package/dist/vector/services/embedding-service.d.ts +244 -0
  210. package/dist/vector/services/embedding-service.d.ts.map +1 -0
  211. package/dist/vector/services/embedding-service.js +10 -0
  212. package/dist/vector/services/embedding-service.js.map +1 -0
  213. package/dist/vector/services/hybrid-search.d.ts +320 -0
  214. package/dist/vector/services/hybrid-search.d.ts.map +1 -0
  215. package/dist/vector/services/hybrid-search.js +3 -0
  216. package/dist/vector/services/hybrid-search.js.map +1 -0
  217. package/dist/vector/services/index.d.ts +4 -0
  218. package/dist/vector/services/index.d.ts.map +1 -1
  219. package/package.json +10 -1
@@ -0,0 +1,367 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import * as path from "path";
4
+ import { writeFile, access, readFile } from "fs/promises";
5
+ import { glob } from "fast-glob";
6
+ import matter from "gray-matter";
7
+ class LinkAnalyzer {
8
+ fileMap = /* @__PURE__ */ new Map();
9
+ allFiles = /* @__PURE__ */ new Set();
10
+ /**
11
+ * Analyze a vault for links and build adjacency list
12
+ */
13
+ async analyzeVault(vaultPath, options = {}) {
14
+ const resolvedPath = path.resolve(vaultPath);
15
+ try {
16
+ await access(resolvedPath);
17
+ } catch {
18
+ throw new Error(`Vault path does not exist: ${resolvedPath}`);
19
+ }
20
+ const files = await glob("**/*.md", {
21
+ cwd: resolvedPath,
22
+ ignore: ["node_modules/**", ".git/**", "dist/**"],
23
+ absolute: false
24
+ });
25
+ if (files.length === 0) {
26
+ throw new Error(`No markdown files found in: ${resolvedPath}`);
27
+ }
28
+ this.buildFileMap(files);
29
+ const adjacencyList = /* @__PURE__ */ new Map();
30
+ const brokenLinks = [];
31
+ const incomingLinks = /* @__PURE__ */ new Map();
32
+ let totalWikiLinks = 0;
33
+ let totalMarkdownLinks = 0;
34
+ let maxLinksInFile = 0;
35
+ let maxLinksFile = "";
36
+ for (const file of files) {
37
+ adjacencyList.set(file, []);
38
+ incomingLinks.set(file, /* @__PURE__ */ new Set());
39
+ }
40
+ for (const file of files) {
41
+ const filePath = path.join(resolvedPath, file);
42
+ const content = await readFile(filePath, "utf-8");
43
+ const { content: bodyContent } = matter(content);
44
+ const wikiLinks = this.parseWikiLinks(bodyContent);
45
+ const markdownLinks = this.parseMarkdownLinks(bodyContent);
46
+ totalWikiLinks += wikiLinks.length;
47
+ totalMarkdownLinks += markdownLinks.length;
48
+ const fileLinks = adjacencyList.get(file) || [];
49
+ const totalLinksInThisFile = wikiLinks.length + markdownLinks.length;
50
+ if (totalLinksInThisFile > maxLinksInFile) {
51
+ maxLinksInFile = totalLinksInThisFile;
52
+ maxLinksFile = file;
53
+ }
54
+ for (const link of wikiLinks) {
55
+ const resolved = this.resolveLink(link, file);
56
+ if (resolved && this.allFiles.has(resolved)) {
57
+ fileLinks.push(resolved);
58
+ incomingLinks.get(resolved)?.add(file);
59
+ } else {
60
+ brokenLinks.push({
61
+ source: file,
62
+ target: link,
63
+ type: "wikilink"
64
+ });
65
+ }
66
+ }
67
+ for (const link of markdownLinks) {
68
+ const resolved = this.resolveLink(link, file);
69
+ if (resolved && this.allFiles.has(resolved)) {
70
+ fileLinks.push(resolved);
71
+ incomingLinks.get(resolved)?.add(file);
72
+ } else if (!this.isExternalLink(link)) {
73
+ brokenLinks.push({
74
+ source: file,
75
+ target: link,
76
+ type: "markdown"
77
+ });
78
+ }
79
+ }
80
+ adjacencyList.set(file, [...new Set(fileLinks)]);
81
+ }
82
+ const orphanFiles = [];
83
+ for (const file of files) {
84
+ const outgoing = adjacencyList.get(file) || [];
85
+ const incoming = incomingLinks.get(file) || /* @__PURE__ */ new Set();
86
+ if (outgoing.length === 0 && incoming.size === 0) {
87
+ orphanFiles.push(file);
88
+ }
89
+ }
90
+ const totalFiles = files.length;
91
+ const filesWithLinks = files.filter((f) => {
92
+ const outgoing = adjacencyList.get(f) || [];
93
+ const incoming = incomingLinks.get(f) || /* @__PURE__ */ new Set();
94
+ return outgoing.length > 0 || incoming.size > 0;
95
+ }).length;
96
+ const orphanRate = totalFiles > 0 ? orphanFiles.length / totalFiles * 100 : 0;
97
+ const totalLinks = totalWikiLinks + totalMarkdownLinks;
98
+ const linkDensity = totalFiles > 0 ? totalLinks / totalFiles : 0;
99
+ const averageLinksPerFile = totalFiles > 0 ? totalLinks / totalFiles : 0;
100
+ const isolatedClusters = this.countClusters(adjacencyList, files);
101
+ return {
102
+ totalFiles,
103
+ filesWithLinks,
104
+ orphanFiles,
105
+ orphanRate: Math.round(orphanRate * 100) / 100,
106
+ linkDensity: Math.round(linkDensity * 100) / 100,
107
+ adjacencyList,
108
+ brokenLinks,
109
+ statistics: {
110
+ totalLinks,
111
+ wikiLinks: totalWikiLinks,
112
+ markdownLinks: totalMarkdownLinks,
113
+ averageLinksPerFile: Math.round(averageLinksPerFile * 100) / 100,
114
+ maxLinksInFile,
115
+ maxLinksFile,
116
+ isolatedClusters
117
+ }
118
+ };
119
+ }
120
+ /**
121
+ * Build a map from filename (without extension) to full path
122
+ */
123
+ buildFileMap(files) {
124
+ this.fileMap.clear();
125
+ this.allFiles.clear();
126
+ for (const file of files) {
127
+ this.allFiles.add(file);
128
+ const basename = path.basename(file, ".md");
129
+ if (!this.fileMap.has(basename)) {
130
+ this.fileMap.set(basename, file);
131
+ }
132
+ const pathWithoutExt = file.replace(/\.md$/, "");
133
+ this.fileMap.set(pathWithoutExt, file);
134
+ }
135
+ }
136
+ /**
137
+ * Parse [[wiki-links]] from content
138
+ * Handles: [[link]], [[link|alias]], [[folder/link]], [[link#heading]]
139
+ */
140
+ parseWikiLinks(content) {
141
+ const links = [];
142
+ const regex = /\[\[([^\]|#]+)(?:#[^\]|]*)?(?:\|[^\]]+)?\]\]/g;
143
+ let match;
144
+ while ((match = regex.exec(content)) !== null) {
145
+ const link = match[1].trim();
146
+ if (link) {
147
+ links.push(link);
148
+ }
149
+ }
150
+ return links;
151
+ }
152
+ /**
153
+ * Parse [markdown](links) from content
154
+ * Handles: [text](link.md), [text](./link.md), [text](../folder/link.md)
155
+ */
156
+ parseMarkdownLinks(content) {
157
+ const links = [];
158
+ const regex = /(?<!!)\[([^\]]*)\]\(([^)]+)\)/g;
159
+ let match;
160
+ while ((match = regex.exec(content)) !== null) {
161
+ const link = match[2].trim();
162
+ if (link && !this.isExternalLink(link) && !link.startsWith("#")) {
163
+ links.push(link);
164
+ }
165
+ }
166
+ return links;
167
+ }
168
+ /**
169
+ * Check if a link is external (http, https, etc.)
170
+ */
171
+ isExternalLink(link) {
172
+ return /^(https?:|mailto:|tel:|ftp:)/i.test(link);
173
+ }
174
+ /**
175
+ * Resolve a link to a file in the vault
176
+ */
177
+ resolveLink(link, sourceFile) {
178
+ let cleanLink = link.replace(/\.md$/, "");
179
+ if (cleanLink.startsWith("./") || cleanLink.startsWith("../")) {
180
+ const sourceDir = path.dirname(sourceFile);
181
+ const resolved = path.normalize(path.join(sourceDir, cleanLink));
182
+ cleanLink = resolved;
183
+ }
184
+ const found = this.fileMap.get(cleanLink);
185
+ if (found) return found;
186
+ const withMd = cleanLink + ".md";
187
+ if (this.allFiles.has(withMd)) return withMd;
188
+ const basename = path.basename(cleanLink);
189
+ const byBasename = this.fileMap.get(basename);
190
+ if (byBasename) return byBasename;
191
+ return null;
192
+ }
193
+ /**
194
+ * Count isolated clusters using union-find algorithm
195
+ */
196
+ countClusters(adjacencyList, files) {
197
+ const parent = /* @__PURE__ */ new Map();
198
+ const rank = /* @__PURE__ */ new Map();
199
+ for (const file of files) {
200
+ parent.set(file, file);
201
+ rank.set(file, 0);
202
+ }
203
+ const find = (x) => {
204
+ if (parent.get(x) !== x) {
205
+ parent.set(x, find(parent.get(x)));
206
+ }
207
+ return parent.get(x);
208
+ };
209
+ const union = (x, y) => {
210
+ const rootX = find(x);
211
+ const rootY = find(y);
212
+ if (rootX !== rootY) {
213
+ const rankX = rank.get(rootX) || 0;
214
+ const rankY = rank.get(rootY) || 0;
215
+ if (rankX < rankY) {
216
+ parent.set(rootX, rootY);
217
+ } else if (rankX > rankY) {
218
+ parent.set(rootY, rootX);
219
+ } else {
220
+ parent.set(rootY, rootX);
221
+ rank.set(rootX, rankX + 1);
222
+ }
223
+ }
224
+ };
225
+ for (const [source, targets] of adjacencyList) {
226
+ for (const target of targets) {
227
+ if (parent.has(target)) {
228
+ union(source, target);
229
+ }
230
+ }
231
+ }
232
+ const roots = /* @__PURE__ */ new Set();
233
+ for (const file of files) {
234
+ roots.add(find(file));
235
+ }
236
+ return roots.size;
237
+ }
238
+ /**
239
+ * Generate a detailed report
240
+ */
241
+ generateReport(result) {
242
+ const lines = [];
243
+ lines.push("# Link Analysis Report\n");
244
+ lines.push(`Generated: ${(/* @__PURE__ */ new Date()).toISOString()}
245
+ `);
246
+ lines.push("## Summary\n");
247
+ lines.push(`| Metric | Value |`);
248
+ lines.push(`|--------|-------|`);
249
+ lines.push(`| Total Files | ${result.totalFiles} |`);
250
+ lines.push(`| Files with Links | ${result.filesWithLinks} |`);
251
+ lines.push(`| Orphan Files | ${result.orphanFiles.length} |`);
252
+ lines.push(`| Orphan Rate | ${result.orphanRate}% |`);
253
+ lines.push(`| Link Density | ${result.linkDensity} |`);
254
+ lines.push(`| Total Links | ${result.statistics.totalLinks} |`);
255
+ lines.push(`| Wiki Links | ${result.statistics.wikiLinks} |`);
256
+ lines.push(`| Markdown Links | ${result.statistics.markdownLinks} |`);
257
+ lines.push(`| Avg Links/File | ${result.statistics.averageLinksPerFile} |`);
258
+ lines.push(`| Max Links in File | ${result.statistics.maxLinksInFile} |`);
259
+ lines.push(`| Most Linked File | ${result.statistics.maxLinksFile} |`);
260
+ lines.push(`| Isolated Clusters | ${result.statistics.isolatedClusters} |`);
261
+ lines.push("");
262
+ if (result.orphanFiles.length > 0) {
263
+ lines.push("## Orphan Files\n");
264
+ lines.push("Files with no incoming or outgoing links:\n");
265
+ for (const file of result.orphanFiles.slice(0, 50)) {
266
+ lines.push(`- \`${file}\``);
267
+ }
268
+ if (result.orphanFiles.length > 50) {
269
+ lines.push(`
270
+ ... and ${result.orphanFiles.length - 50} more`);
271
+ }
272
+ lines.push("");
273
+ }
274
+ if (result.brokenLinks.length > 0) {
275
+ lines.push("## Broken Links\n");
276
+ lines.push("Links that point to non-existent files:\n");
277
+ for (const broken of result.brokenLinks.slice(0, 50)) {
278
+ lines.push(`- \`${broken.source}\` -> \`${broken.target}\` (${broken.type})`);
279
+ }
280
+ if (result.brokenLinks.length > 50) {
281
+ lines.push(`
282
+ ... and ${result.brokenLinks.length - 50} more`);
283
+ }
284
+ lines.push("");
285
+ }
286
+ return lines.join("\n");
287
+ }
288
+ }
289
+ function createAnalyzeLinksCommand() {
290
+ const command = new Command("analyze-links").description("Analyze wiki-links and markdown links in a vault").argument("<vault-path>", "Path to Obsidian vault or docs directory").option("-o, --output <file>", "Output file for results (JSON or Markdown)").option("--json", "Output as JSON").option("-v, --verbose", "Show detailed output").action(async (vaultPath, options) => {
291
+ const analyzer = new LinkAnalyzer();
292
+ console.log(chalk.cyan("\nAnalyzing links in vault...\n"));
293
+ try {
294
+ const result = await analyzer.analyzeVault(vaultPath, options);
295
+ if (options.json) {
296
+ const jsonResult = {
297
+ ...result,
298
+ adjacencyList: Object.fromEntries(result.adjacencyList)
299
+ };
300
+ if (options.output) {
301
+ await writeFile(options.output, JSON.stringify(jsonResult, null, 2));
302
+ console.log(chalk.green(`Results written to: ${options.output}`));
303
+ } else {
304
+ console.log(JSON.stringify(jsonResult, null, 2));
305
+ }
306
+ } else {
307
+ console.log(chalk.bold("Summary:"));
308
+ console.log(chalk.white(` Total Files: ${result.totalFiles}`));
309
+ console.log(chalk.white(` Files with Links: ${result.filesWithLinks}`));
310
+ console.log(chalk.white(` Orphan Files: ${chalk.yellow(result.orphanFiles.length.toString())}`));
311
+ console.log(chalk.white(` Orphan Rate: ${chalk.yellow(result.orphanRate + "%")}`));
312
+ console.log(chalk.white(` Link Density: ${result.linkDensity}`));
313
+ console.log("");
314
+ console.log(chalk.bold("Link Statistics:"));
315
+ console.log(chalk.white(` Total Links: ${result.statistics.totalLinks}`));
316
+ console.log(chalk.white(` Wiki Links: ${result.statistics.wikiLinks}`));
317
+ console.log(chalk.white(` Markdown Links: ${result.statistics.markdownLinks}`));
318
+ console.log(chalk.white(` Avg Links/File: ${result.statistics.averageLinksPerFile}`));
319
+ console.log(chalk.white(` Isolated Clusters: ${result.statistics.isolatedClusters}`));
320
+ console.log("");
321
+ if (result.brokenLinks.length > 0) {
322
+ console.log(chalk.bold(chalk.red(`Broken Links: ${result.brokenLinks.length}`)));
323
+ if (options.verbose) {
324
+ for (const broken of result.brokenLinks.slice(0, 10)) {
325
+ console.log(chalk.red(` ${broken.source} -> ${broken.target}`));
326
+ }
327
+ if (result.brokenLinks.length > 10) {
328
+ console.log(chalk.gray(` ... and ${result.brokenLinks.length - 10} more`));
329
+ }
330
+ }
331
+ console.log("");
332
+ }
333
+ if (options.verbose && result.orphanFiles.length > 0) {
334
+ console.log(chalk.bold(chalk.yellow("Orphan Files:")));
335
+ for (const file of result.orphanFiles.slice(0, 10)) {
336
+ console.log(chalk.yellow(` ${file}`));
337
+ }
338
+ if (result.orphanFiles.length > 10) {
339
+ console.log(chalk.gray(` ... and ${result.orphanFiles.length - 10} more`));
340
+ }
341
+ console.log("");
342
+ }
343
+ if (options.output) {
344
+ const report = analyzer.generateReport(result);
345
+ await writeFile(options.output, report);
346
+ console.log(chalk.green(`Report written to: ${options.output}`));
347
+ }
348
+ console.log(chalk.bold("Target Metrics:"));
349
+ const orphanStatus = result.orphanRate < 10 ? chalk.green("PASS") : chalk.red("FAIL");
350
+ const densityStatus = result.linkDensity > 5 ? chalk.green("PASS") : chalk.red("FAIL");
351
+ console.log(chalk.white(` Orphan Rate: ${result.orphanRate}% (target: < 10%) ${orphanStatus}`));
352
+ console.log(chalk.white(` Link Density: ${result.linkDensity} (target: > 5.0) ${densityStatus}`));
353
+ console.log("");
354
+ }
355
+ } catch (error) {
356
+ console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
357
+ process.exit(1);
358
+ }
359
+ });
360
+ return command;
361
+ }
362
+ export {
363
+ LinkAnalyzer,
364
+ createAnalyzeLinksCommand,
365
+ createAnalyzeLinksCommand as default
366
+ };
367
+ //# sourceMappingURL=analyze-links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze-links.js","sources":["../../../../src/cli/commands/hive-mind/analyze-links.ts"],"sourcesContent":["/**\n * Hive Mind - Link Analyzer\n *\n * Analyzes wiki-links and markdown links in a vault to build an adjacency list\n * and identify orphan files.\n *\n * SPEC-003: Hive Mind Reconnection Tools\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport * as path from 'path';\nimport { readFile, access, writeFile } from 'fs/promises';\nimport { glob } from 'fast-glob';\nimport matter from 'gray-matter';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface AnalyzeOptions {\n output?: string;\n json?: boolean;\n verbose?: boolean;\n includeContent?: boolean;\n}\n\nexport interface BrokenLink {\n source: string;\n target: string;\n type: 'wikilink' | 'markdown';\n lineNumber?: number;\n}\n\nexport interface LinkAnalysisResult {\n totalFiles: number;\n filesWithLinks: number;\n orphanFiles: string[];\n orphanRate: number;\n linkDensity: number;\n adjacencyList: Map<string, string[]>;\n brokenLinks: BrokenLink[];\n statistics: {\n totalLinks: number;\n wikiLinks: number;\n markdownLinks: number;\n averageLinksPerFile: number;\n maxLinksInFile: number;\n maxLinksFile: string;\n isolatedClusters: number;\n };\n}\n\n// ============================================================================\n// Link Analyzer Class\n// ============================================================================\n\nexport class LinkAnalyzer {\n private fileMap: Map<string, string> = new Map();\n private allFiles: Set<string> = new Set();\n\n /**\n * Analyze a vault for links and build adjacency list\n */\n async analyzeVault(vaultPath: string, options: AnalyzeOptions = {}): Promise<LinkAnalysisResult> {\n const resolvedPath = path.resolve(vaultPath);\n\n // Check if path exists\n try {\n await access(resolvedPath);\n } catch {\n throw new Error(`Vault path does not exist: ${resolvedPath}`);\n }\n\n // Find all markdown files\n const files = await glob('**/*.md', {\n cwd: resolvedPath,\n ignore: ['node_modules/**', '.git/**', 'dist/**'],\n absolute: false,\n });\n\n if (files.length === 0) {\n throw new Error(`No markdown files found in: ${resolvedPath}`);\n }\n\n // Build file map for resolution (filename without extension -> full path)\n this.buildFileMap(files);\n\n const adjacencyList = new Map<string, string[]>();\n const brokenLinks: BrokenLink[] = [];\n const incomingLinks = new Map<string, Set<string>>();\n let totalWikiLinks = 0;\n let totalMarkdownLinks = 0;\n let maxLinksInFile = 0;\n let maxLinksFile = '';\n\n // Initialize adjacency list and incoming links\n for (const file of files) {\n adjacencyList.set(file, []);\n incomingLinks.set(file, new Set());\n }\n\n // Process each file\n for (const file of files) {\n const filePath = path.join(resolvedPath, file);\n const content = await readFile(filePath, 'utf-8');\n\n // Parse frontmatter to skip it for link counting\n const { content: bodyContent } = matter(content);\n\n // Extract links\n const wikiLinks = this.parseWikiLinks(bodyContent);\n const markdownLinks = this.parseMarkdownLinks(bodyContent);\n\n totalWikiLinks += wikiLinks.length;\n totalMarkdownLinks += markdownLinks.length;\n\n const fileLinks = adjacencyList.get(file) || [];\n const totalLinksInThisFile = wikiLinks.length + markdownLinks.length;\n\n if (totalLinksInThisFile > maxLinksInFile) {\n maxLinksInFile = totalLinksInThisFile;\n maxLinksFile = file;\n }\n\n // Process wiki links\n for (const link of wikiLinks) {\n const resolved = this.resolveLink(link, file);\n if (resolved && this.allFiles.has(resolved)) {\n fileLinks.push(resolved);\n incomingLinks.get(resolved)?.add(file);\n } else {\n brokenLinks.push({\n source: file,\n target: link,\n type: 'wikilink',\n });\n }\n }\n\n // Process markdown links\n for (const link of markdownLinks) {\n const resolved = this.resolveLink(link, file);\n if (resolved && this.allFiles.has(resolved)) {\n fileLinks.push(resolved);\n incomingLinks.get(resolved)?.add(file);\n } else if (!this.isExternalLink(link)) {\n brokenLinks.push({\n source: file,\n target: link,\n type: 'markdown',\n });\n }\n }\n\n adjacencyList.set(file, [...new Set(fileLinks)]); // Dedupe\n }\n\n // Find orphan files (no incoming AND no outgoing links)\n const orphanFiles: string[] = [];\n for (const file of files) {\n const outgoing = adjacencyList.get(file) || [];\n const incoming = incomingLinks.get(file) || new Set();\n if (outgoing.length === 0 && incoming.size === 0) {\n orphanFiles.push(file);\n }\n }\n\n // Calculate metrics\n const totalFiles = files.length;\n const filesWithLinks = files.filter(f => {\n const outgoing = adjacencyList.get(f) || [];\n const incoming = incomingLinks.get(f) || new Set();\n return outgoing.length > 0 || incoming.size > 0;\n }).length;\n\n const orphanRate = totalFiles > 0 ? (orphanFiles.length / totalFiles) * 100 : 0;\n const totalLinks = totalWikiLinks + totalMarkdownLinks;\n const linkDensity = totalFiles > 0 ? totalLinks / totalFiles : 0;\n const averageLinksPerFile = totalFiles > 0 ? totalLinks / totalFiles : 0;\n\n // Calculate isolated clusters using union-find\n const isolatedClusters = this.countClusters(adjacencyList, files);\n\n return {\n totalFiles,\n filesWithLinks,\n orphanFiles,\n orphanRate: Math.round(orphanRate * 100) / 100,\n linkDensity: Math.round(linkDensity * 100) / 100,\n adjacencyList,\n brokenLinks,\n statistics: {\n totalLinks,\n wikiLinks: totalWikiLinks,\n markdownLinks: totalMarkdownLinks,\n averageLinksPerFile: Math.round(averageLinksPerFile * 100) / 100,\n maxLinksInFile,\n maxLinksFile,\n isolatedClusters,\n },\n };\n }\n\n /**\n * Build a map from filename (without extension) to full path\n */\n private buildFileMap(files: string[]): void {\n this.fileMap.clear();\n this.allFiles.clear();\n\n for (const file of files) {\n this.allFiles.add(file);\n\n // Map by filename without extension\n const basename = path.basename(file, '.md');\n if (!this.fileMap.has(basename)) {\n this.fileMap.set(basename, file);\n }\n\n // Also map by full path without extension\n const pathWithoutExt = file.replace(/\\.md$/, '');\n this.fileMap.set(pathWithoutExt, file);\n }\n }\n\n /**\n * Parse [[wiki-links]] from content\n * Handles: [[link]], [[link|alias]], [[folder/link]], [[link#heading]]\n */\n parseWikiLinks(content: string): string[] {\n const links: string[] = [];\n // Match [[link]] and [[link|alias]] patterns\n const regex = /\\[\\[([^\\]|#]+)(?:#[^\\]|]*)?(?:\\|[^\\]]+)?\\]\\]/g;\n let match;\n\n while ((match = regex.exec(content)) !== null) {\n const link = match[1].trim();\n if (link) {\n links.push(link);\n }\n }\n\n return links;\n }\n\n /**\n * Parse [markdown](links) from content\n * Handles: [text](link.md), [text](./link.md), [text](../folder/link.md)\n */\n parseMarkdownLinks(content: string): string[] {\n const links: string[] = [];\n // Match [text](link) patterns, excluding images ![...](...) and external links\n const regex = /(?<!!)\\[([^\\]]*)\\]\\(([^)]+)\\)/g;\n let match;\n\n while ((match = regex.exec(content)) !== null) {\n const link = match[2].trim();\n // Skip external links, anchors, and non-md files\n if (link && !this.isExternalLink(link) && !link.startsWith('#')) {\n links.push(link);\n }\n }\n\n return links;\n }\n\n /**\n * Check if a link is external (http, https, etc.)\n */\n private isExternalLink(link: string): boolean {\n return /^(https?:|mailto:|tel:|ftp:)/i.test(link);\n }\n\n /**\n * Resolve a link to a file in the vault\n */\n private resolveLink(link: string, sourceFile: string): string | null {\n // Remove .md extension if present\n let cleanLink = link.replace(/\\.md$/, '');\n\n // Remove leading ./ or ../ and resolve relative paths\n if (cleanLink.startsWith('./') || cleanLink.startsWith('../')) {\n const sourceDir = path.dirname(sourceFile);\n const resolved = path.normalize(path.join(sourceDir, cleanLink));\n cleanLink = resolved;\n }\n\n // Try to find in file map\n const found = this.fileMap.get(cleanLink);\n if (found) return found;\n\n // Try with .md extension\n const withMd = cleanLink + '.md';\n if (this.allFiles.has(withMd)) return withMd;\n\n // Try just the basename (for simple wiki-links)\n const basename = path.basename(cleanLink);\n const byBasename = this.fileMap.get(basename);\n if (byBasename) return byBasename;\n\n return null;\n }\n\n /**\n * Count isolated clusters using union-find algorithm\n */\n private countClusters(adjacencyList: Map<string, string[]>, files: string[]): number {\n const parent = new Map<string, string>();\n const rank = new Map<string, number>();\n\n // Initialize each file as its own cluster\n for (const file of files) {\n parent.set(file, file);\n rank.set(file, 0);\n }\n\n const find = (x: string): string => {\n if (parent.get(x) !== x) {\n parent.set(x, find(parent.get(x)!));\n }\n return parent.get(x)!;\n };\n\n const union = (x: string, y: string): void => {\n const rootX = find(x);\n const rootY = find(y);\n if (rootX !== rootY) {\n const rankX = rank.get(rootX) || 0;\n const rankY = rank.get(rootY) || 0;\n if (rankX < rankY) {\n parent.set(rootX, rootY);\n } else if (rankX > rankY) {\n parent.set(rootY, rootX);\n } else {\n parent.set(rootY, rootX);\n rank.set(rootX, rankX + 1);\n }\n }\n };\n\n // Union connected files\n for (const [source, targets] of adjacencyList) {\n for (const target of targets) {\n if (parent.has(target)) {\n union(source, target);\n }\n }\n }\n\n // Count unique roots\n const roots = new Set<string>();\n for (const file of files) {\n roots.add(find(file));\n }\n\n return roots.size;\n }\n\n /**\n * Generate a detailed report\n */\n generateReport(result: LinkAnalysisResult): string {\n const lines: string[] = [];\n\n lines.push('# Link Analysis Report\\n');\n lines.push(`Generated: ${new Date().toISOString()}\\n`);\n\n lines.push('## Summary\\n');\n lines.push(`| Metric | Value |`);\n lines.push(`|--------|-------|`);\n lines.push(`| Total Files | ${result.totalFiles} |`);\n lines.push(`| Files with Links | ${result.filesWithLinks} |`);\n lines.push(`| Orphan Files | ${result.orphanFiles.length} |`);\n lines.push(`| Orphan Rate | ${result.orphanRate}% |`);\n lines.push(`| Link Density | ${result.linkDensity} |`);\n lines.push(`| Total Links | ${result.statistics.totalLinks} |`);\n lines.push(`| Wiki Links | ${result.statistics.wikiLinks} |`);\n lines.push(`| Markdown Links | ${result.statistics.markdownLinks} |`);\n lines.push(`| Avg Links/File | ${result.statistics.averageLinksPerFile} |`);\n lines.push(`| Max Links in File | ${result.statistics.maxLinksInFile} |`);\n lines.push(`| Most Linked File | ${result.statistics.maxLinksFile} |`);\n lines.push(`| Isolated Clusters | ${result.statistics.isolatedClusters} |`);\n lines.push('');\n\n if (result.orphanFiles.length > 0) {\n lines.push('## Orphan Files\\n');\n lines.push('Files with no incoming or outgoing links:\\n');\n for (const file of result.orphanFiles.slice(0, 50)) {\n lines.push(`- \\`${file}\\``);\n }\n if (result.orphanFiles.length > 50) {\n lines.push(`\\n... and ${result.orphanFiles.length - 50} more`);\n }\n lines.push('');\n }\n\n if (result.brokenLinks.length > 0) {\n lines.push('## Broken Links\\n');\n lines.push('Links that point to non-existent files:\\n');\n for (const broken of result.brokenLinks.slice(0, 50)) {\n lines.push(`- \\`${broken.source}\\` -> \\`${broken.target}\\` (${broken.type})`);\n }\n if (result.brokenLinks.length > 50) {\n lines.push(`\\n... and ${result.brokenLinks.length - 50} more`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n }\n}\n\n// ============================================================================\n// CLI Command\n// ============================================================================\n\nexport function createAnalyzeLinksCommand(): Command {\n const command = new Command('analyze-links')\n .description('Analyze wiki-links and markdown links in a vault')\n .argument('<vault-path>', 'Path to Obsidian vault or docs directory')\n .option('-o, --output <file>', 'Output file for results (JSON or Markdown)')\n .option('--json', 'Output as JSON')\n .option('-v, --verbose', 'Show detailed output')\n .action(async (vaultPath: string, options: AnalyzeOptions) => {\n const analyzer = new LinkAnalyzer();\n\n console.log(chalk.cyan('\\nAnalyzing links in vault...\\n'));\n\n try {\n const result = await analyzer.analyzeVault(vaultPath, options);\n\n if (options.json) {\n // Convert Map to Object for JSON serialization\n const jsonResult = {\n ...result,\n adjacencyList: Object.fromEntries(result.adjacencyList),\n };\n\n if (options.output) {\n await writeFile(options.output, JSON.stringify(jsonResult, null, 2));\n console.log(chalk.green(`Results written to: ${options.output}`));\n } else {\n console.log(JSON.stringify(jsonResult, null, 2));\n }\n } else {\n // Display summary\n console.log(chalk.bold('Summary:'));\n console.log(chalk.white(` Total Files: ${result.totalFiles}`));\n console.log(chalk.white(` Files with Links: ${result.filesWithLinks}`));\n console.log(chalk.white(` Orphan Files: ${chalk.yellow(result.orphanFiles.length.toString())}`));\n console.log(chalk.white(` Orphan Rate: ${chalk.yellow(result.orphanRate + '%')}`));\n console.log(chalk.white(` Link Density: ${result.linkDensity}`));\n console.log('');\n\n console.log(chalk.bold('Link Statistics:'));\n console.log(chalk.white(` Total Links: ${result.statistics.totalLinks}`));\n console.log(chalk.white(` Wiki Links: ${result.statistics.wikiLinks}`));\n console.log(chalk.white(` Markdown Links: ${result.statistics.markdownLinks}`));\n console.log(chalk.white(` Avg Links/File: ${result.statistics.averageLinksPerFile}`));\n console.log(chalk.white(` Isolated Clusters: ${result.statistics.isolatedClusters}`));\n console.log('');\n\n if (result.brokenLinks.length > 0) {\n console.log(chalk.bold(chalk.red(`Broken Links: ${result.brokenLinks.length}`)));\n if (options.verbose) {\n for (const broken of result.brokenLinks.slice(0, 10)) {\n console.log(chalk.red(` ${broken.source} -> ${broken.target}`));\n }\n if (result.brokenLinks.length > 10) {\n console.log(chalk.gray(` ... and ${result.brokenLinks.length - 10} more`));\n }\n }\n console.log('');\n }\n\n if (options.verbose && result.orphanFiles.length > 0) {\n console.log(chalk.bold(chalk.yellow('Orphan Files:')));\n for (const file of result.orphanFiles.slice(0, 10)) {\n console.log(chalk.yellow(` ${file}`));\n }\n if (result.orphanFiles.length > 10) {\n console.log(chalk.gray(` ... and ${result.orphanFiles.length - 10} more`));\n }\n console.log('');\n }\n\n // Write report if output specified\n if (options.output) {\n const report = analyzer.generateReport(result);\n await writeFile(options.output, report);\n console.log(chalk.green(`Report written to: ${options.output}`));\n }\n\n // Show target metrics comparison\n console.log(chalk.bold('Target Metrics:'));\n const orphanStatus = result.orphanRate < 10 ? chalk.green('PASS') : chalk.red('FAIL');\n const densityStatus = result.linkDensity > 5.0 ? chalk.green('PASS') : chalk.red('FAIL');\n console.log(chalk.white(` Orphan Rate: ${result.orphanRate}% (target: < 10%) ${orphanStatus}`));\n console.log(chalk.white(` Link Density: ${result.linkDensity} (target: > 5.0) ${densityStatus}`));\n console.log('');\n }\n } catch (error) {\n console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');\n process.exit(1);\n }\n });\n\n return command;\n}\n\nexport default createAnalyzeLinksCommand;\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Hive Mind - Connection Finder
3
+ *
4
+ * Uses TF-IDF similarity to find potential connections between documents.
5
+ * Suggests links for orphan files to reconnect the knowledge graph.
6
+ *
7
+ * SPEC-003: Hive Mind Reconnection Tools
8
+ */
9
+ import { Command } from 'commander';
10
+ export interface FindConnectionsOptions {
11
+ threshold?: string;
12
+ suggest?: boolean;
13
+ limit?: string;
14
+ output?: string;
15
+ json?: boolean;
16
+ verbose?: boolean;
17
+ }
18
+ export interface SimilarityMatch {
19
+ source: string;
20
+ target: string;
21
+ similarity: number;
22
+ sharedTerms: string[];
23
+ }
24
+ export interface DocumentVector {
25
+ file: string;
26
+ terms: Map<string, number>;
27
+ magnitude: number;
28
+ }
29
+ export interface ConnectionFinderResult {
30
+ totalDocuments: number;
31
+ suggestedConnections: SimilarityMatch[];
32
+ orphanConnections: SimilarityMatch[];
33
+ termCount: number;
34
+ averageSimilarity: number;
35
+ }
36
+ export declare class ConnectionFinder {
37
+ private documents;
38
+ private documentVectors;
39
+ private documentFrequency;
40
+ private totalDocuments;
41
+ /**
42
+ * Build TF-IDF index from vault
43
+ */
44
+ buildIndex(vaultPath: string): Promise<void>;
45
+ /**
46
+ * Find similar documents to a source file
47
+ */
48
+ findSimilar(sourceFile: string, threshold?: number, limit?: number): SimilarityMatch[];
49
+ /**
50
+ * Calculate cosine similarity between two document vectors
51
+ */
52
+ private cosineSimilarity;
53
+ /**
54
+ * Find shared terms between two documents
55
+ */
56
+ private findSharedTerms;
57
+ /**
58
+ * Suggest connections for orphan files
59
+ */
60
+ suggestConnections(vaultPath: string, orphanFiles: string[], threshold?: number, limit?: number): Promise<SimilarityMatch[]>;
61
+ /**
62
+ * Find all potential connections above threshold
63
+ */
64
+ findAllConnections(vaultPath: string, threshold?: number, limit?: number): Promise<ConnectionFinderResult>;
65
+ /**
66
+ * Get index statistics
67
+ */
68
+ getStats(): {
69
+ documents: number;
70
+ terms: number;
71
+ };
72
+ }
73
+ export declare function createFindConnectionsCommand(): Command;
74
+ export default createFindConnectionsCommand;
75
+ //# sourceMappingURL=find-connections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-connections.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/hive-mind/find-connections.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,eAAe,EAAE,CAAC;IACxC,iBAAiB,EAAE,eAAe,EAAE,CAAC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAqDD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,eAAe,CAA0C;IACjE,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,OAAO,CAAC,cAAc,CAAK;IAE3B;;OAEG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2FlD;;OAEG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,SAAM,EAAE,KAAK,SAAK,GAAG,eAAe,EAAE;IA8B/E;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAYxB;;OAEG;IACH,OAAO,CAAC,eAAe;IAgBvB;;OAEG;IACG,kBAAkB,CACtB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EAAE,EACrB,SAAS,SAAM,EACf,KAAK,SAAI,GACR,OAAO,CAAC,eAAe,EAAE,CAAC;IAmB7B;;OAEG;IACG,kBAAkB,CACtB,SAAS,EAAE,MAAM,EACjB,SAAS,SAAM,EACf,KAAK,SAAM,GACV,OAAO,CAAC,sBAAsB,CAAC;IAsClC;;OAEG;IACH,QAAQ,IAAI;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;CAMjD;AAMD,wBAAgB,4BAA4B,IAAI,OAAO,CAwGtD;AAED,eAAe,4BAA4B,CAAC"}