sxng-cli 1.0.5 → 1.0.6

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 (65) hide show
  1. package/README.md +120 -4
  2. package/dist/commands/build-graph.d.ts +8 -0
  3. package/dist/commands/build-graph.d.ts.map +1 -0
  4. package/dist/commands/build-graph.js +70 -0
  5. package/dist/commands/build-graph.js.map +1 -0
  6. package/dist/commands/extract.d.ts +11 -0
  7. package/dist/commands/extract.d.ts.map +1 -0
  8. package/dist/commands/extract.js +84 -0
  9. package/dist/commands/extract.js.map +1 -0
  10. package/dist/commands/graph-add.d.ts +13 -0
  11. package/dist/commands/graph-add.d.ts.map +1 -0
  12. package/dist/commands/graph-add.js +148 -0
  13. package/dist/commands/graph-add.js.map +1 -0
  14. package/dist/commands/query-graph.d.ts +11 -0
  15. package/dist/commands/query-graph.d.ts.map +1 -0
  16. package/dist/commands/query-graph.js +146 -0
  17. package/dist/commands/query-graph.js.map +1 -0
  18. package/dist/commands/raw.d.ts +14 -0
  19. package/dist/commands/raw.d.ts.map +1 -0
  20. package/dist/commands/raw.js +125 -0
  21. package/dist/commands/raw.js.map +1 -0
  22. package/dist/commands/session.d.ts +28 -0
  23. package/dist/commands/session.d.ts.map +1 -0
  24. package/dist/commands/session.js +144 -0
  25. package/dist/commands/session.js.map +1 -0
  26. package/dist/config.d.ts +1 -1
  27. package/dist/config.d.ts.map +1 -1
  28. package/dist/config.js +1 -1
  29. package/dist/config.js.map +1 -1
  30. package/dist/deep/dedupe.d.ts +14 -0
  31. package/dist/deep/dedupe.d.ts.map +1 -0
  32. package/dist/deep/dedupe.js +53 -0
  33. package/dist/deep/dedupe.js.map +1 -0
  34. package/dist/deep/extractor.d.ts +29 -0
  35. package/dist/deep/extractor.d.ts.map +1 -0
  36. package/dist/deep/extractor.js +125 -0
  37. package/dist/deep/extractor.js.map +1 -0
  38. package/dist/deep/graph.d.ts +55 -0
  39. package/dist/deep/graph.d.ts.map +1 -0
  40. package/dist/deep/graph.js +153 -0
  41. package/dist/deep/graph.js.map +1 -0
  42. package/dist/deep/index.d.ts +10 -0
  43. package/dist/deep/index.d.ts.map +1 -0
  44. package/dist/deep/index.js +10 -0
  45. package/dist/deep/index.js.map +1 -0
  46. package/dist/deep/keywords.d.ts +27 -0
  47. package/dist/deep/keywords.d.ts.map +1 -0
  48. package/dist/deep/keywords.js +293 -0
  49. package/dist/deep/keywords.js.map +1 -0
  50. package/dist/deep/rrf.d.ts +13 -0
  51. package/dist/deep/rrf.d.ts.map +1 -0
  52. package/dist/deep/rrf.js +23 -0
  53. package/dist/deep/rrf.js.map +1 -0
  54. package/dist/deep/session.d.ts +65 -0
  55. package/dist/deep/session.d.ts.map +1 -0
  56. package/dist/deep/session.js +197 -0
  57. package/dist/deep/session.js.map +1 -0
  58. package/dist/deep/simhash.d.ts +12 -0
  59. package/dist/deep/simhash.d.ts.map +1 -0
  60. package/dist/deep/simhash.js +56 -0
  61. package/dist/deep/simhash.js.map +1 -0
  62. package/dist/runCli.d.ts.map +1 -1
  63. package/dist/runCli.js +394 -100
  64. package/dist/runCli.js.map +1 -1
  65. package/package.json +6 -2
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SearXNG CLI
2
2
 
3
- A command-line interface for searching with SearXNG, a privacy-respecting meta search engine.
3
+ A command-line interface for searching with SearXNG, a privacy-respecting meta search engine. Supports deep multi-round search with knowledge graph, session accumulation, and content extraction.
4
4
 
5
5
  ## Installation
6
6
 
@@ -34,13 +34,15 @@ sxng "your search query"
34
34
 
35
35
  Configuration can be provided via:
36
36
  1. Environment variables (highest priority)
37
- 2. Config file: `./searxng.config.json`
37
+ 2. Config file: `./searxng.config.json` or `~/.sxng/config.json`
38
38
  3. Default values (lowest priority)
39
39
 
40
40
  See `searxng.config.example.json` for an example configuration.
41
41
 
42
42
  ## Usage
43
43
 
44
+ ### Basic Search
45
+
44
46
  ```bash
45
47
  # Simple search
46
48
  sxng "TypeScript tutorial"
@@ -57,8 +59,8 @@ sxng --categories it,science "machine learning"
57
59
  # Recent results only
58
60
  sxng --time week "latest news"
59
61
 
60
- # Output as CSV
61
- sxng "docker tutorial" --format csv > results.csv
62
+ # Output as JSON
63
+ sxng -f json "docker tutorial"
62
64
 
63
65
  # Check server health
64
66
  sxng --health
@@ -70,6 +72,120 @@ sxng --engines-list
70
72
  sxng --categories-list
71
73
  ```
72
74
 
75
+ ### Multi-Query Search
76
+
77
+ Run multiple queries with RRF (Reciprocal Rank Fusion) result fusion and deduplication:
78
+
79
+ ```bash
80
+ sxng --queries "tokio tutorial,rust async basics,tokio vs async-std"
81
+ ```
82
+
83
+ ### Content Extraction
84
+
85
+ Extract full article content from web pages:
86
+
87
+ ```bash
88
+ # Extract from specific URLs
89
+ sxng extract --urls "https://example.com/article1,https://example.com/article2"
90
+
91
+ # Extract from search results JSON file
92
+ sxng extract --from-json search-results.json
93
+ ```
94
+
95
+ ## Deep Search
96
+
97
+ Deep search enables multi-round iterative research with session accumulation and knowledge graph building.
98
+
99
+ ### Session Management
100
+
101
+ ```bash
102
+ # Create a new session with auto-generated name
103
+ sxng --session new --owner "research-agent" --desc "Rust async research" "rust async ecosystem"
104
+
105
+ # List all sessions
106
+ sxng session-list
107
+
108
+ # Delete a specific session
109
+ sxng session-delete ds_1745000000_abcd123
110
+
111
+ # Delete sessions older than N hours
112
+ sxng session-delete --older 24
113
+ ```
114
+
115
+ ### Deep Search Workflow
116
+
117
+ The deep search flow follows an iterative loop: search → extract → analyze → build graph → decide.
118
+
119
+ ```bash
120
+ # Round 1: Create session and search
121
+ sxng --session new --owner "agent-1" --desc "async ecosystem research" "rust async ecosystem"
122
+ # Note the returned session path, e.g., ~/.sxng/sessions/ds_1745000000_abcd123
123
+
124
+ # Extract content from results
125
+ sxng extract --session ~/.sxng/sessions/ds_1745000000_abcd123
126
+
127
+ # Add entities and relationships to knowledge graph
128
+ sxng graph-add ~/.sxng/sessions/ds_1745000000_abcd123 --data '{
129
+ "entities": [
130
+ {"label": "tokio", "entityType": "runtime", "score": 0.95},
131
+ {"label": "async-std", "entityType": "runtime", "score": 0.85}
132
+ ],
133
+ "edges": [
134
+ {"source": "e:tokio", "target": "e:async_std", "relation": "alternative_to", "weight": 0.9}
135
+ ]
136
+ }'
137
+
138
+ # Query the knowledge graph
139
+ sxng query-graph ~/.sxng/sessions/ds_1745000000_abcd123 --seeds "tokio" --depth 2
140
+
141
+ # Round 2: Search with multiple queries (results accumulate in session)
142
+ sxng --session ~/.sxng/sessions/ds_1745000000_abcd123 --queries "tokio vs async-std comparison,rust async benchmark 2024"
143
+
144
+ # Extract again and continue the loop...
145
+ ```
146
+
147
+ ### Session Data Structure
148
+
149
+ Each session stores three files in `~/.sxng/sessions/<session-name>/`:
150
+
151
+ - **`results.json`** — Accumulated search result pool (URL dedup, multi-round accumulation)
152
+ - **`graph.json`** — Knowledge graph (structural + semantic layers)
153
+ - **`meta.json`** — Session metadata (owner, description, timestamps)
154
+
155
+ ### Knowledge Graph
156
+
157
+ The graph has two layers:
158
+
159
+ **Structural Layer** (auto-built by CLI every search):
160
+
161
+ | Node type | Prefix | Attributes |
162
+ |-----------|--------|------------|
163
+ | query | `q:` | label, query, round |
164
+ | result | `r:` | label, url, title, rank |
165
+ | domain | `d:` | label, domain |
166
+
167
+ **Semantic Layer** (added via `graph-add`):
168
+
169
+ | Node type | Prefix | Attributes |
170
+ |-----------|--------|------------|
171
+ | entity | `e:` | label, entityType, score |
172
+
173
+ ## Options Reference
174
+
175
+ | Option | Short | Description | Example |
176
+ |--------|-------|-------------|---------|
177
+ | `--limit` | `-l` | Max results | `-l 20` |
178
+ | `--engines` | `-e` | Specific search engines | `-e google,github` |
179
+ | `--categories` | `-c` | Filter by category | `-c it,science` |
180
+ | `--page` | `-p` | Pagination | `-p 2` |
181
+ | `--lang` | | Result language | `--lang zh` |
182
+ | `--time` | | Time filter | `--time week` |
183
+ | `--format` | `-f` | Output format | `-f json` |
184
+ | `--queries` | | Multi-query with RRF fusion | `--queries "q1,q2,q3"` |
185
+ | `--session` | | Session directory or "new" | `--session new` |
186
+ | `--owner` | | Session owner identifier | `--owner "agent-1"` |
187
+ | `--desc` | | Session description | `--desc "research topic"` |
188
+
73
189
  ## Environment Variables
74
190
 
75
191
  | Variable | Description | Default |
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Build-graph subcommand - construct knowledge graph from search results
3
+ */
4
+ export interface BuildGraphOptions {
5
+ inputs: string[];
6
+ }
7
+ export declare function runBuildGraph(options: BuildGraphOptions): Promise<number>;
8
+ //# sourceMappingURL=build-graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-graph.d.ts","sourceRoot":"","sources":["../../src/commands/build-graph.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,MAAM,EAAE,CAAC;CACpB;AA0BD,wBAAsB,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsD/E"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Build-graph subcommand - construct knowledge graph from search results
3
+ */
4
+ import { readFileSync } from 'fs';
5
+ import { buildGraphFromResults, serializeGraph, graphStats } from '../deep/graph.js';
6
+ import { createSuccessEnvelope, createErrorEnvelope } from '../protocol.js';
7
+ function loadResultsFromFiles(files) {
8
+ const allResults = [];
9
+ for (const file of files) {
10
+ try {
11
+ const raw = readFileSync(file, 'utf-8');
12
+ const parsed = JSON.parse(raw);
13
+ // Handle envelope format
14
+ let data = parsed;
15
+ if (parsed.status === 'ok' && parsed.data) {
16
+ data = parsed.data;
17
+ }
18
+ const results = data.results || [];
19
+ allResults.push(...results);
20
+ }
21
+ catch {
22
+ // Skip invalid files silently
23
+ }
24
+ }
25
+ return allResults;
26
+ }
27
+ export async function runBuildGraph(options) {
28
+ if (options.inputs.length === 0) {
29
+ const envelope = createErrorEnvelope('MISSING_INPUT', 'No input files provided for graph building', { hint: 'Use: sxng build-graph --inputs file1.json,file2.json' });
30
+ console.log(JSON.stringify(envelope, null, 2));
31
+ return 1;
32
+ }
33
+ const allResults = loadResultsFromFiles(options.inputs);
34
+ if (allResults.length === 0) {
35
+ const envelope = createErrorEnvelope('NO_RESULTS', 'No search results found in input files', { hint: 'Ensure input files contain valid search results with a results array' });
36
+ console.log(JSON.stringify(envelope, null, 2));
37
+ return 1;
38
+ }
39
+ // Collect all queries from input files
40
+ const allQueries = [];
41
+ for (const file of options.inputs) {
42
+ try {
43
+ const raw = readFileSync(file, 'utf-8');
44
+ const parsed = JSON.parse(raw);
45
+ let data = parsed;
46
+ if (parsed.status === 'ok' && parsed.data) {
47
+ data = parsed.data;
48
+ }
49
+ if (data.queries) {
50
+ allQueries.push(...data.queries);
51
+ }
52
+ else if (data.query) {
53
+ allQueries.push(data.query);
54
+ }
55
+ }
56
+ catch {
57
+ // Skip
58
+ }
59
+ }
60
+ const graph = buildGraphFromResults(allResults, allQueries);
61
+ const serialized = serializeGraph(graph);
62
+ const stats = graphStats(graph);
63
+ const envelope = createSuccessEnvelope({
64
+ stats,
65
+ graph: serialized,
66
+ });
67
+ console.log(JSON.stringify(envelope, null, 2));
68
+ return 0;
69
+ }
70
+ //# sourceMappingURL=build-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-graph.js","sourceRoot":"","sources":["../../src/commands/build-graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Extract subcommand - content extraction from URLs or search results
3
+ */
4
+ import { ContentExtractor } from '../deep/extractor.js';
5
+ export interface ExtractOptions {
6
+ urls?: string[];
7
+ fromJson?: string;
8
+ session?: string;
9
+ }
10
+ export declare function runExtract(extractor: ContentExtractor, options: ExtractOptions): Promise<number>;
11
+ //# sourceMappingURL=extract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/commands/extract.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAoB,MAAM,sBAAsB,CAAC;AAK1E,MAAM,WAAW,cAAc;IAC3B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAYD,wBAAsB,UAAU,CAC5B,SAAS,EAAE,gBAAgB,EAC3B,OAAO,EAAE,cAAc,GACxB,OAAO,CAAC,MAAM,CAAC,CAoGjB"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Extract subcommand - content extraction from URLs or search results
3
+ */
4
+ import { createSuccessEnvelope, createErrorEnvelope } from '../protocol.js';
5
+ import { readFileSync } from 'fs';
6
+ import { loadSessionResults, mergeExtractedContent } from '../deep/session.js';
7
+ export async function runExtract(extractor, options) {
8
+ let urls = [];
9
+ if (options.urls && options.urls.length > 0) {
10
+ urls = options.urls;
11
+ }
12
+ else if (options.session) {
13
+ // Read URLs from session results
14
+ const results = loadSessionResults(options.session);
15
+ if (results.length === 0) {
16
+ const envelope = createErrorEnvelope('SESSION_EMPTY', `Session has no results: ${options.session}`, { hint: 'Run a search with --session first to accumulate results' });
17
+ console.log(JSON.stringify(envelope, null, 2));
18
+ return 1;
19
+ }
20
+ urls = results.map(r => r.url).filter(u => typeof u === 'string' && u.length > 0);
21
+ }
22
+ else if (options.fromJson) {
23
+ try {
24
+ const raw = readFileSync(options.fromJson, 'utf-8');
25
+ const parsed = JSON.parse(raw);
26
+ // Handle envelope format
27
+ let data = parsed;
28
+ if (parsed.status === 'ok' && parsed.data) {
29
+ data = parsed.data;
30
+ }
31
+ // Extract URLs from results array
32
+ const results = data.results || [];
33
+ urls = results
34
+ .map((r) => r.url)
35
+ .filter((u) => typeof u === 'string' && u.length > 0);
36
+ }
37
+ catch (error) {
38
+ const envelope = createErrorEnvelope('FILE_READ_FAILED', `Failed to read or parse file: ${options.fromJson}`, { hint: 'Ensure the file exists and contains valid JSON with a results array' });
39
+ console.log(JSON.stringify(envelope, null, 2));
40
+ return 1;
41
+ }
42
+ }
43
+ else {
44
+ const envelope = createErrorEnvelope('MISSING_INPUT', 'No URLs or input file provided for extraction', { hint: 'Use: sxng extract --urls "url1,url2" or sxng extract --from-json results.json or sxng extract --session /tmp/s' });
45
+ console.log(JSON.stringify(envelope, null, 2));
46
+ return 1;
47
+ }
48
+ if (urls.length === 0) {
49
+ const envelope = createErrorEnvelope('NO_URLS', 'No URLs found to extract', { hint: 'Provide URLs directly or ensure the JSON/session contains results with URLs' });
50
+ console.log(JSON.stringify(envelope, null, 2));
51
+ return 1;
52
+ }
53
+ try {
54
+ const contents = await extractor.extractBatch(urls);
55
+ const extracted = contents.filter(c => !c.error && c.content.length > 100);
56
+ const failed = contents.filter(c => c.error || c.content.length <= 100).map(c => c.url);
57
+ // Merge extracted content into session if --session provided
58
+ let sessionMerge = null;
59
+ if (options.session) {
60
+ sessionMerge = mergeExtractedContent(options.session, contents);
61
+ }
62
+ const output = {
63
+ extracted,
64
+ failed,
65
+ stats: {
66
+ total: urls.length,
67
+ success: extracted.length,
68
+ failed: failed.length,
69
+ },
70
+ };
71
+ const envelope = createSuccessEnvelope({
72
+ ...output,
73
+ ...(sessionMerge ? { session: sessionMerge } : {}),
74
+ });
75
+ console.log(JSON.stringify(envelope, null, 2));
76
+ return 0;
77
+ }
78
+ catch (error) {
79
+ const envelope = createErrorEnvelope('EXTRACT_FAILED', error instanceof Error ? error.message : 'Content extraction failed', { retryable: true });
80
+ console.log(JSON.stringify(envelope, null, 2));
81
+ return 1;
82
+ }
83
+ }
84
+ //# sourceMappingURL=extract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/commands/extract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * graph-add subcommand - Add entities and edges to an entity-centric knowledge graph
3
+ *
4
+ * Agent (LLM) extracts entities from search results and sends them here.
5
+ * Each entity is connected to its source result via "mentions" edges.
6
+ * Result nodes store lightweight metadata (title, url, rank).
7
+ */
8
+ export interface GraphAddOptions {
9
+ graphFile: string;
10
+ data: string;
11
+ }
12
+ export declare function runGraphAdd(options: GraphAddOptions): Promise<number>;
13
+ //# sourceMappingURL=graph-add.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-add.d.ts","sourceRoot":"","sources":["../../src/commands/graph-add.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAoBH,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CAChB;AAsBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAoJ3E"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * graph-add subcommand - Add entities and edges to an entity-centric knowledge graph
3
+ *
4
+ * Agent (LLM) extracts entities from search results and sends them here.
5
+ * Each entity is connected to its source result via "mentions" edges.
6
+ * Result nodes store lightweight metadata (title, url, rank).
7
+ */
8
+ import { readFileSync, writeFileSync, existsSync, statSync } from 'fs';
9
+ import { join } from 'path';
10
+ import { deserializeGraph, serializeGraph, graphStats, entityId, resultId } from '../deep/graph.js';
11
+ import { DirectedGraph } from 'graphology';
12
+ import { createSuccessEnvelope, createErrorEnvelope } from '../protocol.js';
13
+ /** Resolve graph file path — if directory (session), use graph.json inside it */
14
+ function resolveGraphFile(path) {
15
+ try {
16
+ if (statSync(path).isDirectory()) {
17
+ return join(path, 'graph.json');
18
+ }
19
+ }
20
+ catch {
21
+ // Not a file/dir, return as-is
22
+ }
23
+ return path;
24
+ }
25
+ export async function runGraphAdd(options) {
26
+ const graphFile = resolveGraphFile(options.graphFile);
27
+ if (!graphFile) {
28
+ const envelope = createErrorEnvelope('MISSING_GRAPH_FILE', 'No graph file specified', { hint: 'Use: sxng graph-add graph.json --data \'...\'' });
29
+ console.log(JSON.stringify(envelope, null, 2));
30
+ return 1;
31
+ }
32
+ // Parse input data
33
+ let parsed;
34
+ try {
35
+ parsed = JSON.parse(options.data);
36
+ }
37
+ catch {
38
+ const envelope = createErrorEnvelope('INVALID_JSON', 'Failed to parse --data JSON', { hint: 'Ensure --data contains valid JSON with "entities", "results", and/or "edges" arrays' });
39
+ console.log(JSON.stringify(envelope, null, 2));
40
+ return 1;
41
+ }
42
+ // Load or create graph
43
+ let graph;
44
+ if (existsSync(graphFile)) {
45
+ try {
46
+ const raw = readFileSync(graphFile, 'utf-8');
47
+ const fileParsed = JSON.parse(raw);
48
+ const graphData = fileParsed.status === 'ok' && fileParsed.data?.graph
49
+ ? fileParsed.data.graph
50
+ : (fileParsed.nodes && fileParsed.edges ? fileParsed : null);
51
+ graph = graphData
52
+ ? deserializeGraph(graphData)
53
+ : new DirectedGraph();
54
+ }
55
+ catch {
56
+ const envelope = createErrorEnvelope('GRAPH_LOAD_FAILED', `Failed to load graph from: ${graphFile}`, { hint: 'Ensure the file contains a valid graphology graph' });
57
+ console.log(JSON.stringify(envelope, null, 2));
58
+ return 1;
59
+ }
60
+ }
61
+ else {
62
+ graph = new DirectedGraph();
63
+ }
64
+ let entitiesAdded = 0;
65
+ let resultsAdded = 0;
66
+ let edgesAdded = 0;
67
+ // Add entity nodes
68
+ for (const entity of parsed.entities || []) {
69
+ const id = entity.id || entityId(entity.label);
70
+ if (!graph.hasNode(id)) {
71
+ graph.mergeNode(id, {
72
+ type: 'entity',
73
+ label: entity.label,
74
+ entityType: entity.entityType,
75
+ score: entity.score,
76
+ });
77
+ entitiesAdded++;
78
+ }
79
+ else {
80
+ // Update existing entity
81
+ const existing = graph.getNodeAttributes(id);
82
+ graph.mergeNode(id, {
83
+ ...existing,
84
+ label: entity.label,
85
+ entityType: entity.entityType ?? existing.entityType,
86
+ score: entity.score ?? existing.score,
87
+ });
88
+ }
89
+ }
90
+ // Add result metadata nodes
91
+ for (const result of parsed.results || []) {
92
+ const id = resultId(result.url);
93
+ if (!graph.hasNode(id)) {
94
+ graph.mergeNode(id, {
95
+ type: 'result',
96
+ label: result.title,
97
+ url: result.url,
98
+ title: result.title,
99
+ rank: result.rank,
100
+ });
101
+ resultsAdded++;
102
+ }
103
+ else {
104
+ // Update rank if better
105
+ const existing = graph.getNodeAttributes(id);
106
+ if (result.rank !== undefined) {
107
+ graph.mergeNode(id, {
108
+ ...existing,
109
+ rank: result.rank < (existing.rank ?? Infinity) ? result.rank : existing.rank,
110
+ });
111
+ }
112
+ }
113
+ }
114
+ // Add edges (entity-entity and entity-result relationships)
115
+ const skippedEdges = [];
116
+ for (const edge of parsed.edges || []) {
117
+ if (!graph.hasNode(edge.source) || !graph.hasNode(edge.target)) {
118
+ skippedEdges.push({ source: edge.source, target: edge.target, relation: edge.relation });
119
+ continue;
120
+ }
121
+ graph.mergeEdge(edge.source, edge.target, {
122
+ relation: edge.relation,
123
+ weight: edge.weight ?? 1,
124
+ });
125
+ edgesAdded++;
126
+ }
127
+ // Save graph
128
+ const serialized = serializeGraph(graph);
129
+ const stats = graphStats(graph);
130
+ try {
131
+ writeFileSync(graphFile, JSON.stringify({ status: 'ok', data: { graph: serialized, stats } }, null, 2), 'utf-8');
132
+ }
133
+ catch (e) {
134
+ const envelope = createErrorEnvelope('GRAPH_WRITE_FAILED', `Failed to write graph to: ${graphFile}`, { hint: 'Check directory permissions and disk space', details: { error: e instanceof Error ? e.message : String(e) } });
135
+ console.log(JSON.stringify(envelope, null, 2));
136
+ return 1;
137
+ }
138
+ const envelope = createSuccessEnvelope({
139
+ entitiesAdded,
140
+ resultsAdded,
141
+ edgesAdded,
142
+ skippedEdges,
143
+ stats,
144
+ });
145
+ console.log(JSON.stringify(envelope, null, 2));
146
+ return 0;
147
+ }
148
+ //# sourceMappingURL=graph-add.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-add.js","sourceRoot":"","sources":["../../src/commands/graph-add.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Query-graph subcommand - BFS subgraph extraction from knowledge graph
3
+ */
4
+ export interface QueryGraphOptions {
5
+ graphFile: string;
6
+ seeds: string[];
7
+ depth: number;
8
+ format?: 'json' | 'md';
9
+ }
10
+ export declare function runQueryGraph(options: QueryGraphOptions): Promise<number>;
11
+ //# sourceMappingURL=query-graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-graph.d.ts","sourceRoot":"","sources":["../../src/commands/query-graph.ts"],"names":[],"mappings":"AAAA;;GAEG;AAoCH,MAAM,WAAW,iBAAiB;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsI/E"}