gnosys 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1387 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +3753 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2267 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/archive.d.ts +95 -0
- package/dist/lib/archive.d.ts.map +1 -0
- package/dist/lib/archive.js +311 -0
- package/dist/lib/archive.js.map +1 -0
- package/dist/lib/ask.d.ts +77 -0
- package/dist/lib/ask.d.ts.map +1 -0
- package/dist/lib/ask.js +316 -0
- package/dist/lib/ask.js.map +1 -0
- package/dist/lib/audit.d.ts +47 -0
- package/dist/lib/audit.d.ts.map +1 -0
- package/dist/lib/audit.js +136 -0
- package/dist/lib/audit.js.map +1 -0
- package/dist/lib/bootstrap.d.ts +56 -0
- package/dist/lib/bootstrap.d.ts.map +1 -0
- package/dist/lib/bootstrap.js +163 -0
- package/dist/lib/bootstrap.js.map +1 -0
- package/dist/lib/config.d.ts +239 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +371 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/dashboard.d.ts +81 -0
- package/dist/lib/dashboard.d.ts.map +1 -0
- package/dist/lib/dashboard.js +314 -0
- package/dist/lib/dashboard.js.map +1 -0
- package/dist/lib/db.d.ts +182 -0
- package/dist/lib/db.d.ts.map +1 -0
- package/dist/lib/db.js +620 -0
- package/dist/lib/db.js.map +1 -0
- package/dist/lib/dbSearch.d.ts +65 -0
- package/dist/lib/dbSearch.d.ts.map +1 -0
- package/dist/lib/dbSearch.js +239 -0
- package/dist/lib/dbSearch.js.map +1 -0
- package/dist/lib/dbWrite.d.ts +56 -0
- package/dist/lib/dbWrite.d.ts.map +1 -0
- package/dist/lib/dbWrite.js +171 -0
- package/dist/lib/dbWrite.js.map +1 -0
- package/dist/lib/dream.d.ts +170 -0
- package/dist/lib/dream.d.ts.map +1 -0
- package/dist/lib/dream.js +706 -0
- package/dist/lib/dream.js.map +1 -0
- package/dist/lib/embeddings.d.ts +84 -0
- package/dist/lib/embeddings.d.ts.map +1 -0
- package/dist/lib/embeddings.js +226 -0
- package/dist/lib/embeddings.js.map +1 -0
- package/dist/lib/export.d.ts +92 -0
- package/dist/lib/export.d.ts.map +1 -0
- package/dist/lib/export.js +362 -0
- package/dist/lib/export.js.map +1 -0
- package/dist/lib/federated.d.ts +113 -0
- package/dist/lib/federated.d.ts.map +1 -0
- package/dist/lib/federated.js +346 -0
- package/dist/lib/federated.js.map +1 -0
- package/dist/lib/graph.d.ts +50 -0
- package/dist/lib/graph.d.ts.map +1 -0
- package/dist/lib/graph.js +118 -0
- package/dist/lib/graph.js.map +1 -0
- package/dist/lib/history.d.ts +39 -0
- package/dist/lib/history.d.ts.map +1 -0
- package/dist/lib/history.js +112 -0
- package/dist/lib/history.js.map +1 -0
- package/dist/lib/hybridSearch.d.ts +80 -0
- package/dist/lib/hybridSearch.d.ts.map +1 -0
- package/dist/lib/hybridSearch.js +296 -0
- package/dist/lib/hybridSearch.js.map +1 -0
- package/dist/lib/import.d.ts +52 -0
- package/dist/lib/import.d.ts.map +1 -0
- package/dist/lib/import.js +365 -0
- package/dist/lib/import.js.map +1 -0
- package/dist/lib/ingest.d.ts +51 -0
- package/dist/lib/ingest.d.ts.map +1 -0
- package/dist/lib/ingest.js +144 -0
- package/dist/lib/ingest.js.map +1 -0
- package/dist/lib/lensing.d.ts +35 -0
- package/dist/lib/lensing.d.ts.map +1 -0
- package/dist/lib/lensing.js +85 -0
- package/dist/lib/lensing.js.map +1 -0
- package/dist/lib/llm.d.ts +84 -0
- package/dist/lib/llm.d.ts.map +1 -0
- package/dist/lib/llm.js +386 -0
- package/dist/lib/llm.js.map +1 -0
- package/dist/lib/lock.d.ts +28 -0
- package/dist/lib/lock.d.ts.map +1 -0
- package/dist/lib/lock.js +145 -0
- package/dist/lib/lock.js.map +1 -0
- package/dist/lib/maintenance.d.ts +124 -0
- package/dist/lib/maintenance.d.ts.map +1 -0
- package/dist/lib/maintenance.js +587 -0
- package/dist/lib/maintenance.js.map +1 -0
- package/dist/lib/migrate.d.ts +19 -0
- package/dist/lib/migrate.d.ts.map +1 -0
- package/dist/lib/migrate.js +260 -0
- package/dist/lib/migrate.js.map +1 -0
- package/dist/lib/preferences.d.ts +49 -0
- package/dist/lib/preferences.d.ts.map +1 -0
- package/dist/lib/preferences.js +149 -0
- package/dist/lib/preferences.js.map +1 -0
- package/dist/lib/projectIdentity.d.ts +66 -0
- package/dist/lib/projectIdentity.d.ts.map +1 -0
- package/dist/lib/projectIdentity.js +148 -0
- package/dist/lib/projectIdentity.js.map +1 -0
- package/dist/lib/recall.d.ts +82 -0
- package/dist/lib/recall.d.ts.map +1 -0
- package/dist/lib/recall.js +289 -0
- package/dist/lib/recall.js.map +1 -0
- package/dist/lib/resolver.d.ts +116 -0
- package/dist/lib/resolver.d.ts.map +1 -0
- package/dist/lib/resolver.js +372 -0
- package/dist/lib/resolver.js.map +1 -0
- package/dist/lib/retry.d.ts +24 -0
- package/dist/lib/retry.d.ts.map +1 -0
- package/dist/lib/retry.js +60 -0
- package/dist/lib/retry.js.map +1 -0
- package/dist/lib/rulesGen.d.ts +51 -0
- package/dist/lib/rulesGen.d.ts.map +1 -0
- package/dist/lib/rulesGen.js +167 -0
- package/dist/lib/rulesGen.js.map +1 -0
- package/dist/lib/search.d.ts +51 -0
- package/dist/lib/search.d.ts.map +1 -0
- package/dist/lib/search.js +190 -0
- package/dist/lib/search.js.map +1 -0
- package/dist/lib/staticSearch.d.ts +70 -0
- package/dist/lib/staticSearch.d.ts.map +1 -0
- package/dist/lib/staticSearch.js +162 -0
- package/dist/lib/staticSearch.js.map +1 -0
- package/dist/lib/store.d.ts +79 -0
- package/dist/lib/store.d.ts.map +1 -0
- package/dist/lib/store.js +227 -0
- package/dist/lib/store.js.map +1 -0
- package/dist/lib/structuredIngest.d.ts +37 -0
- package/dist/lib/structuredIngest.d.ts.map +1 -0
- package/dist/lib/structuredIngest.js +208 -0
- package/dist/lib/structuredIngest.js.map +1 -0
- package/dist/lib/tags.d.ts +26 -0
- package/dist/lib/tags.d.ts.map +1 -0
- package/dist/lib/tags.js +109 -0
- package/dist/lib/tags.js.map +1 -0
- package/dist/lib/timeline.d.ts +34 -0
- package/dist/lib/timeline.d.ts.map +1 -0
- package/dist/lib/timeline.js +116 -0
- package/dist/lib/timeline.js.map +1 -0
- package/dist/lib/trace.d.ts +42 -0
- package/dist/lib/trace.d.ts.map +1 -0
- package/dist/lib/trace.js +338 -0
- package/dist/lib/trace.js.map +1 -0
- package/dist/lib/webIndex.d.ts +28 -0
- package/dist/lib/webIndex.d.ts.map +1 -0
- package/dist/lib/webIndex.js +208 -0
- package/dist/lib/webIndex.js.map +1 -0
- package/dist/lib/webIngest.d.ts +51 -0
- package/dist/lib/webIngest.d.ts.map +1 -0
- package/dist/lib/webIngest.js +533 -0
- package/dist/lib/webIngest.js.map +1 -0
- package/dist/lib/wikilinks.d.ts +63 -0
- package/dist/lib/wikilinks.d.ts.map +1 -0
- package/dist/lib/wikilinks.js +146 -0
- package/dist/lib/wikilinks.js.map +1 -0
- package/dist/sandbox/client.d.ts +82 -0
- package/dist/sandbox/client.d.ts.map +1 -0
- package/dist/sandbox/client.js +128 -0
- package/dist/sandbox/client.js.map +1 -0
- package/dist/sandbox/helper-template.d.ts +14 -0
- package/dist/sandbox/helper-template.d.ts.map +1 -0
- package/dist/sandbox/helper-template.js +285 -0
- package/dist/sandbox/helper-template.js.map +1 -0
- package/dist/sandbox/index.d.ts +10 -0
- package/dist/sandbox/index.d.ts.map +1 -0
- package/dist/sandbox/index.js +10 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/sandbox/manager.d.ts +40 -0
- package/dist/sandbox/manager.d.ts.map +1 -0
- package/dist/sandbox/manager.js +220 -0
- package/dist/sandbox/manager.js.map +1 -0
- package/dist/sandbox/server.d.ts +44 -0
- package/dist/sandbox/server.d.ts.map +1 -0
- package/dist/sandbox/server.js +661 -0
- package/dist/sandbox/server.js.map +1 -0
- package/package.json +103 -0
- package/prompts/synthesize.md +21 -0
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gnosys Web Ingest — Site crawling and content extraction for web knowledge base.
|
|
3
|
+
*
|
|
4
|
+
* Crawls a website (from sitemap, directory, or URL list), converts pages to markdown,
|
|
5
|
+
* generates Gnosys-format memory files with YAML frontmatter, and writes them to the
|
|
6
|
+
* knowledge directory.
|
|
7
|
+
*/
|
|
8
|
+
import fs from "fs/promises";
|
|
9
|
+
import { existsSync, readFileSync, mkdirSync } from "fs";
|
|
10
|
+
import path from "path";
|
|
11
|
+
import { createHash } from "crypto";
|
|
12
|
+
import matter from "gray-matter";
|
|
13
|
+
import TurndownService from "turndown";
|
|
14
|
+
import { getLLMProvider } from "./llm.js";
|
|
15
|
+
import { extractStructuredFrontmatter, computeTfIdf, } from "./structuredIngest.js";
|
|
16
|
+
// ─── Turndown instance ──────────────────────────────────────────────────
|
|
17
|
+
function createTurndown() {
|
|
18
|
+
const td = new TurndownService({
|
|
19
|
+
headingStyle: "atx",
|
|
20
|
+
codeBlockStyle: "fenced",
|
|
21
|
+
});
|
|
22
|
+
// Remove script, style, nav, footer, header elements
|
|
23
|
+
td.remove(["script", "style", "nav", "footer", "header", "aside", "iframe"]);
|
|
24
|
+
return td;
|
|
25
|
+
}
|
|
26
|
+
// ─── URL safety ──────────────────────────────────────────────────────────
|
|
27
|
+
/** Maximum recursion depth for sitemap index fetching. */
|
|
28
|
+
const MAX_SITEMAP_DEPTH = 3;
|
|
29
|
+
/** Maximum total URLs collected from sitemaps. */
|
|
30
|
+
const MAX_SITEMAP_URLS = 10_000;
|
|
31
|
+
/**
|
|
32
|
+
* Validate a URL is safe to fetch (blocks SSRF to internal networks).
|
|
33
|
+
* Only allows http/https schemes and rejects private/loopback IPs.
|
|
34
|
+
*/
|
|
35
|
+
function isSafeUrl(urlStr) {
|
|
36
|
+
try {
|
|
37
|
+
const url = new URL(urlStr);
|
|
38
|
+
// Only allow http/https
|
|
39
|
+
if (url.protocol !== "http:" && url.protocol !== "https:")
|
|
40
|
+
return false;
|
|
41
|
+
const hostname = url.hostname;
|
|
42
|
+
// Block loopback
|
|
43
|
+
if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname === "[::1]") {
|
|
44
|
+
return true; // Allow localhost for local dev — but block metadata endpoints below
|
|
45
|
+
}
|
|
46
|
+
// Block cloud metadata endpoints
|
|
47
|
+
if (hostname === "169.254.169.254" || hostname === "metadata.google.internal")
|
|
48
|
+
return false;
|
|
49
|
+
// Block private IPv4 ranges
|
|
50
|
+
const ipv4Match = hostname.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
|
|
51
|
+
if (ipv4Match) {
|
|
52
|
+
const [, a, b] = ipv4Match.map(Number);
|
|
53
|
+
if (a === 10)
|
|
54
|
+
return false; // 10.0.0.0/8
|
|
55
|
+
if (a === 172 && b >= 16 && b <= 31)
|
|
56
|
+
return false; // 172.16.0.0/12
|
|
57
|
+
if (a === 192 && b === 168)
|
|
58
|
+
return false; // 192.168.0.0/16
|
|
59
|
+
if (a === 169 && b === 254)
|
|
60
|
+
return false; // 169.254.0.0/16 (link-local)
|
|
61
|
+
}
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// ─── URL utilities ───────────────────────────────────────────────────────
|
|
69
|
+
function matchesExclude(url, patterns) {
|
|
70
|
+
const urlPath = new URL(url, "https://example.com").pathname;
|
|
71
|
+
return patterns.some((pattern) => matchGlobSimple(urlPath, pattern));
|
|
72
|
+
}
|
|
73
|
+
/** Safe glob matching without regex — avoids ReDoS from user-controlled patterns. */
|
|
74
|
+
function matchGlobSimple(value, pattern) {
|
|
75
|
+
// Split pattern on * to get literal segments
|
|
76
|
+
const parts = pattern.split("*");
|
|
77
|
+
if (parts.length === 1)
|
|
78
|
+
return value === pattern;
|
|
79
|
+
// First segment must be a prefix
|
|
80
|
+
if (!value.startsWith(parts[0]))
|
|
81
|
+
return false;
|
|
82
|
+
let pos = parts[0].length;
|
|
83
|
+
for (let i = 1; i < parts.length; i++) {
|
|
84
|
+
const segment = parts[i];
|
|
85
|
+
if (i === parts.length - 1 && segment === "") {
|
|
86
|
+
// Trailing * matches everything
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
const idx = value.indexOf(segment, pos);
|
|
90
|
+
if (idx === -1)
|
|
91
|
+
return false;
|
|
92
|
+
pos = idx + segment.length;
|
|
93
|
+
}
|
|
94
|
+
// Last segment must match the end
|
|
95
|
+
return pos === value.length || parts[parts.length - 1] === "";
|
|
96
|
+
}
|
|
97
|
+
function urlToFilePath(url, categories) {
|
|
98
|
+
const urlObj = new URL(url, "https://example.com");
|
|
99
|
+
const urlPath = urlObj.pathname;
|
|
100
|
+
// Determine category directory
|
|
101
|
+
let category = "general";
|
|
102
|
+
for (const [pattern, cat] of Object.entries(categories)) {
|
|
103
|
+
if (matchGlobSimple(urlPath, pattern)) {
|
|
104
|
+
category = cat;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Generate filename from URL path
|
|
109
|
+
const segments = urlPath.split("/").filter(Boolean);
|
|
110
|
+
const slug = segments.pop() || "index";
|
|
111
|
+
const cleanSlug = slug
|
|
112
|
+
.replace(/\.\w+$/, "")
|
|
113
|
+
.replace(/[^a-z0-9-]/gi, "-")
|
|
114
|
+
.toLowerCase();
|
|
115
|
+
return path.join(category, `${cleanSlug}.md`);
|
|
116
|
+
}
|
|
117
|
+
// ─── Sitemap parsing ─────────────────────────────────────────────────────
|
|
118
|
+
async function fetchSitemapUrls(sitemapUrl, depth = 0) {
|
|
119
|
+
if (depth > MAX_SITEMAP_DEPTH) {
|
|
120
|
+
throw new Error(`Sitemap recursion depth exceeded (max ${MAX_SITEMAP_DEPTH})`);
|
|
121
|
+
}
|
|
122
|
+
if (!isSafeUrl(sitemapUrl)) {
|
|
123
|
+
throw new Error(`Refusing to fetch unsafe URL: ${sitemapUrl}`);
|
|
124
|
+
}
|
|
125
|
+
const response = await fetch(sitemapUrl);
|
|
126
|
+
if (!response.ok) {
|
|
127
|
+
throw new Error(`Failed to fetch sitemap: ${response.status} ${response.statusText}`);
|
|
128
|
+
}
|
|
129
|
+
const xml = await response.text();
|
|
130
|
+
// Check for sitemap index
|
|
131
|
+
if (xml.includes("<sitemapindex")) {
|
|
132
|
+
const sitemapUrls = [...xml.matchAll(/<loc>\s*(.*?)\s*<\/loc>/g)].map((m) => m[1]);
|
|
133
|
+
const allUrls = [];
|
|
134
|
+
for (const childUrl of sitemapUrls) {
|
|
135
|
+
if (!isSafeUrl(childUrl))
|
|
136
|
+
continue;
|
|
137
|
+
const childUrls = await fetchSitemapUrls(childUrl, depth + 1);
|
|
138
|
+
allUrls.push(...childUrls);
|
|
139
|
+
if (allUrls.length >= MAX_SITEMAP_URLS) {
|
|
140
|
+
return allUrls.slice(0, MAX_SITEMAP_URLS);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return allUrls;
|
|
144
|
+
}
|
|
145
|
+
// Regular sitemap — extract <loc> URLs, filter unsafe
|
|
146
|
+
return [...xml.matchAll(/<loc>\s*(.*?)\s*<\/loc>/g)]
|
|
147
|
+
.map((m) => m[1])
|
|
148
|
+
.filter((u) => isSafeUrl(u))
|
|
149
|
+
.slice(0, MAX_SITEMAP_URLS);
|
|
150
|
+
}
|
|
151
|
+
// ─── Content fetching ────────────────────────────────────────────────────
|
|
152
|
+
async function fetchPage(url) {
|
|
153
|
+
if (!isSafeUrl(url)) {
|
|
154
|
+
throw new Error(`Refusing to fetch unsafe URL: ${url}`);
|
|
155
|
+
}
|
|
156
|
+
const response = await fetch(url);
|
|
157
|
+
if (!response.ok) {
|
|
158
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
159
|
+
}
|
|
160
|
+
return response.text();
|
|
161
|
+
}
|
|
162
|
+
function extractArticleContent(html) {
|
|
163
|
+
// Try to find main/article content area
|
|
164
|
+
const articleMatch = html.match(/<(?:article|main)[^>]*>([\s\S]*?)<\/(?:article|main)>/i);
|
|
165
|
+
if (articleMatch)
|
|
166
|
+
return articleMatch[1];
|
|
167
|
+
// Fallback: try content div patterns
|
|
168
|
+
const contentMatch = html.match(/<div[^>]*(?:class|id)=["'][^"']*(?:content|post|entry|article)[^"']*["'][^>]*>([\s\S]*?)<\/div>/i);
|
|
169
|
+
if (contentMatch)
|
|
170
|
+
return contentMatch[1];
|
|
171
|
+
// Last resort: use body
|
|
172
|
+
const bodyMatch = html.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
|
|
173
|
+
return bodyMatch ? bodyMatch[1] : html;
|
|
174
|
+
}
|
|
175
|
+
function htmlToMarkdown(html, td) {
|
|
176
|
+
const articleHtml = extractArticleContent(html);
|
|
177
|
+
return td.turndown(articleHtml).trim();
|
|
178
|
+
}
|
|
179
|
+
function isMarkdownFile(filePath) {
|
|
180
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
181
|
+
return ext === ".md" || ext === ".mdx";
|
|
182
|
+
}
|
|
183
|
+
function stripMdxComponents(content) {
|
|
184
|
+
// Remove JSX-style components: <Component /> and <Component>...</Component>
|
|
185
|
+
return content
|
|
186
|
+
.replace(/<[A-Z][a-zA-Z]*\s*\/>/g, "")
|
|
187
|
+
.replace(/<[A-Z][a-zA-Z]*[^>]*>[\s\S]*?<\/[A-Z][a-zA-Z]*>/g, "")
|
|
188
|
+
.replace(/import\s+.*?from\s+['"].*?['"]\s*;?\s*\n?/g, "")
|
|
189
|
+
.replace(/export\s+default\s+.*?;\s*\n?/g, "");
|
|
190
|
+
}
|
|
191
|
+
// ─── LLM structuring ────────────────────────────────────────────────────
|
|
192
|
+
async function llmStructure(content, url, categories, provider) {
|
|
193
|
+
const categoryList = [...new Set(Object.values(categories))].join(", ");
|
|
194
|
+
const prompt = `You are a knowledge structuring system. Given the following web page content and its URL, produce a JSON object with these fields:
|
|
195
|
+
|
|
196
|
+
- title: A clear, concise title
|
|
197
|
+
- category: One of: ${categoryList}, or "general"
|
|
198
|
+
- tags: An object with "domain" (array of topic tags) and "type" (array like ["article", "documentation", "product", "service", "faq", "page"])
|
|
199
|
+
- relevance: A keyword cloud (space-separated, 15-25 words) for search discovery. Include synonyms, related terms, abbreviations.
|
|
200
|
+
- confidence: 0.0 to 1.0
|
|
201
|
+
|
|
202
|
+
URL: ${url}
|
|
203
|
+
|
|
204
|
+
Content:
|
|
205
|
+
${content.slice(0, 4000)}
|
|
206
|
+
|
|
207
|
+
Respond with ONLY valid JSON, no markdown fences.`;
|
|
208
|
+
const response = await provider.generate(prompt, {
|
|
209
|
+
system: "You are a knowledge structuring assistant. Output only valid JSON.",
|
|
210
|
+
maxTokens: 500,
|
|
211
|
+
});
|
|
212
|
+
let parsed;
|
|
213
|
+
try {
|
|
214
|
+
// Strip markdown fences if present
|
|
215
|
+
const cleaned = response.replace(/```(?:json)?\n?/g, "").trim();
|
|
216
|
+
parsed = JSON.parse(cleaned);
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
// Fallback to structured mode
|
|
220
|
+
return extractStructuredFrontmatter(content, url, categories);
|
|
221
|
+
}
|
|
222
|
+
const urlPath = new URL(url, "https://example.com").pathname;
|
|
223
|
+
const slug = urlPath.split("/").filter(Boolean).pop() || "index";
|
|
224
|
+
const category = typeof parsed.category === "string" ? parsed.category : "general";
|
|
225
|
+
const prefix = category.slice(0, 4).toLowerCase();
|
|
226
|
+
return {
|
|
227
|
+
id: `${prefix}-${slug.replace(/[^a-z0-9-]/gi, "-").toLowerCase()}`,
|
|
228
|
+
title: typeof parsed.title === "string" ? parsed.title : slug,
|
|
229
|
+
category,
|
|
230
|
+
tags: {
|
|
231
|
+
domain: Array.isArray(parsed.tags?.domain)
|
|
232
|
+
? parsed.tags.domain
|
|
233
|
+
: [],
|
|
234
|
+
type: Array.isArray(parsed.tags?.type)
|
|
235
|
+
? parsed.tags.type
|
|
236
|
+
: ["page"],
|
|
237
|
+
},
|
|
238
|
+
relevance: typeof parsed.relevance === "string" ? parsed.relevance : "",
|
|
239
|
+
author: "ai",
|
|
240
|
+
authority: "imported",
|
|
241
|
+
confidence: typeof parsed.confidence === "number" ? parsed.confidence : 0.8,
|
|
242
|
+
created: new Date().toISOString().split("T")[0],
|
|
243
|
+
status: "active",
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
// ─── Memory file writing ─────────────────────────────────────────────────
|
|
247
|
+
function buildMemoryFile(fm, content) {
|
|
248
|
+
const lines = [
|
|
249
|
+
"---",
|
|
250
|
+
`id: ${fm.id}`,
|
|
251
|
+
`title: '${fm.title.replace(/'/g, "''")}'`,
|
|
252
|
+
`category: ${fm.category}`,
|
|
253
|
+
"tags:",
|
|
254
|
+
" domain:",
|
|
255
|
+
...fm.tags.domain.map((t) => ` - ${t}`),
|
|
256
|
+
" type:",
|
|
257
|
+
...fm.tags.type.map((t) => ` - ${t}`),
|
|
258
|
+
`relevance: '${fm.relevance.replace(/'/g, "''")}'`,
|
|
259
|
+
`author: ${fm.author}`,
|
|
260
|
+
`authority: ${fm.authority}`,
|
|
261
|
+
`confidence: ${fm.confidence}`,
|
|
262
|
+
`created: '${fm.created}'`,
|
|
263
|
+
`status: ${fm.status}`,
|
|
264
|
+
"---",
|
|
265
|
+
"",
|
|
266
|
+
`# ${fm.title}`,
|
|
267
|
+
"",
|
|
268
|
+
content,
|
|
269
|
+
];
|
|
270
|
+
return lines.join("\n");
|
|
271
|
+
}
|
|
272
|
+
// ─── Existing file hash check ────────────────────────────────────────────
|
|
273
|
+
function getExistingHash(filePath) {
|
|
274
|
+
if (!existsSync(filePath))
|
|
275
|
+
return null;
|
|
276
|
+
try {
|
|
277
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
278
|
+
const parsed = matter(raw);
|
|
279
|
+
return parsed.data.contentHash || null;
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
// ─── Concurrency limiter ─────────────────────────────────────────────────
|
|
286
|
+
async function pLimit(tasks, concurrency) {
|
|
287
|
+
const results = [];
|
|
288
|
+
let index = 0;
|
|
289
|
+
async function worker() {
|
|
290
|
+
while (index < tasks.length) {
|
|
291
|
+
const i = index++;
|
|
292
|
+
results[i] = await tasks[i]();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
const workers = Array.from({ length: Math.min(concurrency, tasks.length) }, () => worker());
|
|
296
|
+
await Promise.all(workers);
|
|
297
|
+
return results;
|
|
298
|
+
}
|
|
299
|
+
// ─── Public API ──────────────────────────────────────────────────────────
|
|
300
|
+
/**
|
|
301
|
+
* Ingest a website into a Gnosys knowledge directory.
|
|
302
|
+
*/
|
|
303
|
+
export async function ingestSite(config, gnosysConfig) {
|
|
304
|
+
const start = Date.now();
|
|
305
|
+
const result = {
|
|
306
|
+
added: [],
|
|
307
|
+
updated: [],
|
|
308
|
+
unchanged: [],
|
|
309
|
+
removed: [],
|
|
310
|
+
errors: [],
|
|
311
|
+
duration: 0,
|
|
312
|
+
};
|
|
313
|
+
const outputDir = path.resolve(config.outputDir);
|
|
314
|
+
const exclude = config.exclude || [];
|
|
315
|
+
const concurrency = config.concurrency || 3;
|
|
316
|
+
const crawlDelay = config.crawlDelayMs ?? 200;
|
|
317
|
+
const dryRun = config.dryRun || false;
|
|
318
|
+
// Determine LLM provider availability
|
|
319
|
+
let llmProvider = null;
|
|
320
|
+
if (config.llmEnrich !== false && gnosysConfig) {
|
|
321
|
+
try {
|
|
322
|
+
llmProvider = getLLMProvider(gnosysConfig, "structuring");
|
|
323
|
+
}
|
|
324
|
+
catch {
|
|
325
|
+
llmProvider = null;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// Collect URLs/files to process
|
|
329
|
+
let pages = [];
|
|
330
|
+
if (config.source === "sitemap" && config.sitemapUrl) {
|
|
331
|
+
const urls = await fetchSitemapUrls(config.sitemapUrl);
|
|
332
|
+
pages = urls
|
|
333
|
+
.filter((u) => !matchesExclude(u, exclude))
|
|
334
|
+
.map((u) => ({ url: u, isLocal: false }));
|
|
335
|
+
}
|
|
336
|
+
else if (config.source === "directory" && config.contentDir) {
|
|
337
|
+
const contentDir = path.resolve(config.contentDir);
|
|
338
|
+
const files = await findFilesRecursive(contentDir);
|
|
339
|
+
pages = files
|
|
340
|
+
.filter((f) => {
|
|
341
|
+
const ext = path.extname(f).toLowerCase();
|
|
342
|
+
return [".md", ".mdx", ".html", ".htm"].includes(ext);
|
|
343
|
+
})
|
|
344
|
+
.map((f) => ({
|
|
345
|
+
url: `file://${f}`,
|
|
346
|
+
isLocal: true,
|
|
347
|
+
}));
|
|
348
|
+
}
|
|
349
|
+
else if (config.source === "urls" && config.urls) {
|
|
350
|
+
pages = config.urls
|
|
351
|
+
.filter((u) => !matchesExclude(u, exclude))
|
|
352
|
+
.map((u) => ({ url: u, isLocal: false }));
|
|
353
|
+
}
|
|
354
|
+
if (pages.length === 0) {
|
|
355
|
+
result.duration = Date.now() - start;
|
|
356
|
+
return result;
|
|
357
|
+
}
|
|
358
|
+
// Ensure output directory exists
|
|
359
|
+
if (!dryRun) {
|
|
360
|
+
mkdirSync(outputDir, { recursive: true });
|
|
361
|
+
}
|
|
362
|
+
const td = createTurndown();
|
|
363
|
+
// Track which output files still exist in source (for pruning)
|
|
364
|
+
const processedFiles = new Set();
|
|
365
|
+
// Process pages with concurrency control
|
|
366
|
+
const tasks = pages.map((page, idx) => async () => {
|
|
367
|
+
// Crawl delay for remote URLs (skip for first request and localhost)
|
|
368
|
+
if (!page.isLocal && idx > 0 && crawlDelay > 0) {
|
|
369
|
+
const url = new URL(page.url);
|
|
370
|
+
if (url.hostname !== "localhost" && url.hostname !== "127.0.0.1") {
|
|
371
|
+
await new Promise((resolve) => setTimeout(resolve, crawlDelay));
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
try {
|
|
375
|
+
// Fetch content
|
|
376
|
+
let rawContent;
|
|
377
|
+
if (page.isLocal) {
|
|
378
|
+
const filePath = page.url.replace("file://", "");
|
|
379
|
+
rawContent = readFileSync(filePath, "utf-8");
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
rawContent = await fetchPage(page.url);
|
|
383
|
+
}
|
|
384
|
+
// Convert to markdown
|
|
385
|
+
let markdown;
|
|
386
|
+
if (page.isLocal && isMarkdownFile(page.url.replace("file://", ""))) {
|
|
387
|
+
const parsed = matter(rawContent);
|
|
388
|
+
markdown = parsed.content.trim();
|
|
389
|
+
if (page.url.endsWith(".mdx")) {
|
|
390
|
+
markdown = stripMdxComponents(markdown);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
markdown = htmlToMarkdown(rawContent, td);
|
|
395
|
+
}
|
|
396
|
+
// Compute content hash
|
|
397
|
+
const contentHash = createHash("sha256").update(markdown).digest("hex");
|
|
398
|
+
// Determine output path
|
|
399
|
+
const relativePath = urlToFilePath(page.url, config.categories);
|
|
400
|
+
const fullPath = path.join(outputDir, relativePath);
|
|
401
|
+
processedFiles.add(relativePath);
|
|
402
|
+
// Check for existing file with same hash
|
|
403
|
+
const existingHash = getExistingHash(fullPath);
|
|
404
|
+
if (existingHash === contentHash) {
|
|
405
|
+
result.unchanged.push(relativePath);
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
// Generate frontmatter
|
|
409
|
+
let fm;
|
|
410
|
+
if (llmProvider) {
|
|
411
|
+
fm = await llmStructure(markdown, page.url, config.categories, llmProvider);
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
fm = extractStructuredFrontmatter(rawContent, page.url, config.categories);
|
|
415
|
+
}
|
|
416
|
+
// Write file
|
|
417
|
+
if (!dryRun) {
|
|
418
|
+
const dir = path.dirname(fullPath);
|
|
419
|
+
mkdirSync(dir, { recursive: true });
|
|
420
|
+
// Add contentHash to frontmatter for change detection
|
|
421
|
+
const fileContent = buildMemoryFile(fm, markdown).replace("---\n", `---\ncontentHash: '${contentHash}'\n`);
|
|
422
|
+
await fs.writeFile(fullPath, fileContent, "utf-8");
|
|
423
|
+
}
|
|
424
|
+
if (existingHash) {
|
|
425
|
+
result.updated.push(relativePath);
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
result.added.push(relativePath);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
catch (err) {
|
|
432
|
+
result.errors.push({
|
|
433
|
+
url: page.url,
|
|
434
|
+
error: err instanceof Error ? err.message : String(err),
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
await pLimit(tasks, concurrency);
|
|
439
|
+
// Pruning
|
|
440
|
+
if (config.prune && !dryRun) {
|
|
441
|
+
const existingFiles = await findMdFilesRecursive(outputDir);
|
|
442
|
+
for (const existing of existingFiles) {
|
|
443
|
+
const rel = path.relative(outputDir, existing);
|
|
444
|
+
if (!processedFiles.has(rel) && rel !== "gnosys-index.json") {
|
|
445
|
+
await fs.unlink(existing);
|
|
446
|
+
result.removed.push(rel);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
// If using structured mode (no LLM), run TF-IDF across corpus for relevance
|
|
451
|
+
if (!llmProvider && !dryRun && (result.added.length > 0 || result.updated.length > 0)) {
|
|
452
|
+
await applyTfIdfRelevance(outputDir);
|
|
453
|
+
}
|
|
454
|
+
result.duration = Date.now() - start;
|
|
455
|
+
return result;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Ingest a single URL into the knowledge base.
|
|
459
|
+
*/
|
|
460
|
+
export async function ingestUrl(url, config, gnosysConfig) {
|
|
461
|
+
return ingestSite({ ...config, source: "urls", urls: [url] }, gnosysConfig);
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Ingest from a local directory.
|
|
465
|
+
*/
|
|
466
|
+
export async function ingestDirectory(dir, config, gnosysConfig) {
|
|
467
|
+
return ingestSite({ ...config, source: "directory", contentDir: dir }, gnosysConfig);
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Remove all knowledge files from the output directory.
|
|
471
|
+
*/
|
|
472
|
+
export async function removeKnowledge(knowledgePath) {
|
|
473
|
+
if (existsSync(knowledgePath)) {
|
|
474
|
+
await fs.rm(knowledgePath, { recursive: true, force: true });
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
// ─── Internal helpers ────────────────────────────────────────────────────
|
|
478
|
+
async function findFilesRecursive(dir) {
|
|
479
|
+
const results = [];
|
|
480
|
+
async function walk(current) {
|
|
481
|
+
const entries = await fs.readdir(current, { withFileTypes: true });
|
|
482
|
+
for (const entry of entries) {
|
|
483
|
+
const fullPath = path.join(current, entry.name);
|
|
484
|
+
if (entry.isDirectory()) {
|
|
485
|
+
await walk(fullPath);
|
|
486
|
+
}
|
|
487
|
+
else if (entry.isFile()) {
|
|
488
|
+
results.push(fullPath);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
await walk(dir);
|
|
493
|
+
return results.sort();
|
|
494
|
+
}
|
|
495
|
+
async function findMdFilesRecursive(dir) {
|
|
496
|
+
const allFiles = await findFilesRecursive(dir);
|
|
497
|
+
return allFiles.filter((f) => f.endsWith(".md"));
|
|
498
|
+
}
|
|
499
|
+
async function applyTfIdfRelevance(outputDir) {
|
|
500
|
+
const mdFiles = await findMdFilesRecursive(outputDir);
|
|
501
|
+
const docs = [];
|
|
502
|
+
for (const filePath of mdFiles) {
|
|
503
|
+
try {
|
|
504
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
505
|
+
const parsed = matter(raw);
|
|
506
|
+
const id = parsed.data.id || path.basename(filePath, ".md");
|
|
507
|
+
docs.push({ id, content: parsed.content, path: filePath });
|
|
508
|
+
}
|
|
509
|
+
catch {
|
|
510
|
+
continue;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
if (docs.length === 0)
|
|
514
|
+
return;
|
|
515
|
+
const tfidf = computeTfIdf(docs);
|
|
516
|
+
for (const doc of docs) {
|
|
517
|
+
const terms = tfidf.get(doc.id);
|
|
518
|
+
if (!terms || terms.length === 0)
|
|
519
|
+
continue;
|
|
520
|
+
const relevance = terms.map((t) => t.term).join(" ");
|
|
521
|
+
try {
|
|
522
|
+
const raw = readFileSync(doc.path, "utf-8");
|
|
523
|
+
const parsed = matter(raw);
|
|
524
|
+
parsed.data.relevance = relevance;
|
|
525
|
+
const updated = matter.stringify(parsed.content, parsed.data);
|
|
526
|
+
await fs.writeFile(doc.path, updated, "utf-8");
|
|
527
|
+
}
|
|
528
|
+
catch {
|
|
529
|
+
continue;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
//# sourceMappingURL=webIngest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webIngest.js","sourceRoot":"","sources":["../../src/lib/webIngest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gnosys Wikilinks — Obsidian-compatible cross-references between memories.
|
|
3
|
+
*
|
|
4
|
+
* Scans memory content for [[wikilinks]] and builds a link graph.
|
|
5
|
+
* Supports both [[title]] and [[path|display text]] formats.
|
|
6
|
+
*/
|
|
7
|
+
import { Memory } from "./store.js";
|
|
8
|
+
/** A single link found in a memory. */
|
|
9
|
+
export interface WikiLink {
|
|
10
|
+
/** The raw target inside [[ ]] — could be a title or relative path */
|
|
11
|
+
target: string;
|
|
12
|
+
/** Optional display text (from [[target|display]]) */
|
|
13
|
+
displayText: string | null;
|
|
14
|
+
/** The source memory's relative path */
|
|
15
|
+
sourcePath: string;
|
|
16
|
+
/** The source memory's title */
|
|
17
|
+
sourceTitle: string;
|
|
18
|
+
}
|
|
19
|
+
/** A node in the link graph with both outgoing and incoming links. */
|
|
20
|
+
export interface LinkNode {
|
|
21
|
+
/** This memory's relative path */
|
|
22
|
+
path: string;
|
|
23
|
+
/** This memory's title */
|
|
24
|
+
title: string;
|
|
25
|
+
/** Links going OUT from this memory */
|
|
26
|
+
outgoing: WikiLink[];
|
|
27
|
+
/** Backlinks coming IN to this memory */
|
|
28
|
+
incoming: WikiLink[];
|
|
29
|
+
}
|
|
30
|
+
/** Full link graph across all memories. */
|
|
31
|
+
export interface LinkGraph {
|
|
32
|
+
nodes: Map<string, LinkNode>;
|
|
33
|
+
/** Total number of wikilinks found */
|
|
34
|
+
totalLinks: number;
|
|
35
|
+
/** Targets that don't resolve to any known memory */
|
|
36
|
+
orphanedLinks: WikiLink[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Extract all wikilinks from a memory's content.
|
|
40
|
+
*/
|
|
41
|
+
export declare function extractLinks(memory: Memory): WikiLink[];
|
|
42
|
+
/**
|
|
43
|
+
* Resolve a wikilink target to a memory.
|
|
44
|
+
* Tries matching by: exact relative path, title (case-insensitive), id.
|
|
45
|
+
*/
|
|
46
|
+
export declare function resolveLink(target: string, memories: Memory[]): Memory | null;
|
|
47
|
+
/**
|
|
48
|
+
* Build a full link graph from all memories.
|
|
49
|
+
*/
|
|
50
|
+
export declare function buildLinkGraph(memories: Memory[]): LinkGraph;
|
|
51
|
+
/**
|
|
52
|
+
* Get backlinks for a specific memory.
|
|
53
|
+
*/
|
|
54
|
+
export declare function getBacklinks(memories: Memory[], targetPath: string): WikiLink[];
|
|
55
|
+
/**
|
|
56
|
+
* Get outgoing links for a specific memory.
|
|
57
|
+
*/
|
|
58
|
+
export declare function getOutgoingLinks(memories: Memory[], sourcePath: string): WikiLink[];
|
|
59
|
+
/**
|
|
60
|
+
* Format the link graph as a simple text summary.
|
|
61
|
+
*/
|
|
62
|
+
export declare function formatGraphSummary(graph: LinkGraph): string;
|
|
63
|
+
//# sourceMappingURL=wikilinks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wikilinks.d.ts","sourceRoot":"","sources":["../../src/lib/wikilinks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEpC,uCAAuC;AACvC,MAAM,WAAW,QAAQ;IACvB,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,sEAAsE;AACtE,MAAM,WAAW,QAAQ;IACvB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,yCAAyC;IACzC,QAAQ,EAAE,QAAQ,EAAE,CAAC;CACtB;AAED,2CAA2C;AAC3C,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC7B,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,aAAa,EAAE,QAAQ,EAAE,CAAC;CAC3B;AAKD;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAE,CAiBvD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAAE,GACjB,MAAM,GAAG,IAAI,CA4Bf;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAS,CAsC5D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAAE,EAClB,UAAU,EAAE,MAAM,GACjB,QAAQ,EAAE,CAIZ;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAAE,EAClB,UAAU,EAAE,MAAM,GACjB,QAAQ,EAAE,CAIZ;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAsC3D"}
|