sxng-cli 1.0.5 → 1.0.7

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 +88 -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 +155 -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 +153 -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 +69 -0
  55. package/dist/deep/session.d.ts.map +1 -0
  56. package/dist/deep/session.js +206 -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
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Query-graph subcommand - BFS subgraph extraction from knowledge graph
3
+ */
4
+ import { readFileSync, statSync } from 'fs';
5
+ import { join } from 'path';
6
+ import { homedir } from 'os';
7
+ import { deserializeGraph, bfsSubgraph, serializeGraph, graphStats } from '../deep/graph.js';
8
+ import { createSuccessEnvelope, createErrorEnvelope } from '../protocol.js';
9
+ /** Resolve graph file path — if directory (session), use graph.json inside it.
10
+ * Pure name (no separators) is resolved to ~/.sxng/sessions/<name>
11
+ */
12
+ function resolveGraphFile(path) {
13
+ // Pure name without path separators: resolve to default sessions dir
14
+ if (!path.includes('/') && !path.includes('\\')) {
15
+ path = join(homedir(), '.sxng', 'sessions', path);
16
+ }
17
+ try {
18
+ if (statSync(path).isDirectory()) {
19
+ return join(path, 'graph.json');
20
+ }
21
+ }
22
+ catch {
23
+ // Not a file/dir, return as-is
24
+ }
25
+ return path;
26
+ }
27
+ /** Format subgraph as human-readable text descriptions */
28
+ function formatSubgraphAsText(subgraph) {
29
+ const lines = [];
30
+ for (const edge of subgraph.edges) {
31
+ const src = subgraph.nodes.get(edge.source);
32
+ const tgt = subgraph.nodes.get(edge.target);
33
+ const srcLabel = src?.label || edge.source;
34
+ const tgtLabel = tgt?.label || edge.target;
35
+ const srcType = src?.type || '';
36
+ const tgtType = tgt?.type || '';
37
+ lines.push(`[${srcType}] ${srcLabel} → (${edge.attrs.relation}, w=${edge.attrs.weight.toFixed(2)}) → [${tgtType}] ${tgtLabel}`);
38
+ }
39
+ return lines.join('\n');
40
+ }
41
+ export async function runQueryGraph(options) {
42
+ const graphFile = resolveGraphFile(options.graphFile);
43
+ if (!graphFile) {
44
+ const envelope = createErrorEnvelope('MISSING_GRAPH_FILE', 'No graph file specified', { hint: 'Use: sxng query-graph graph.json --seeds "seed1,seed2" --depth 2' });
45
+ console.log(JSON.stringify(envelope, null, 2));
46
+ return 1;
47
+ }
48
+ let graphData;
49
+ try {
50
+ const raw = readFileSync(graphFile, 'utf-8');
51
+ const parsed = JSON.parse(raw);
52
+ // Handle envelope format
53
+ if (parsed.status === 'ok' && parsed.data?.graph) {
54
+ graphData = parsed.data.graph;
55
+ }
56
+ else if (parsed.nodes && parsed.edges) {
57
+ graphData = parsed;
58
+ }
59
+ else {
60
+ const envelope = createErrorEnvelope('INVALID_GRAPH_FORMAT', 'Graph file does not contain valid graphology data', { hint: 'Ensure the file was produced by sxng build-graph' });
61
+ console.log(JSON.stringify(envelope, null, 2));
62
+ return 1;
63
+ }
64
+ }
65
+ catch (error) {
66
+ const envelope = createErrorEnvelope('FILE_READ_FAILED', `Failed to read graph file: ${graphFile}`, { hint: 'Ensure the file exists and is readable' });
67
+ console.log(JSON.stringify(envelope, null, 2));
68
+ return 1;
69
+ }
70
+ const graph = deserializeGraph(graphData);
71
+ if (options.seeds.length === 0) {
72
+ const envelope = createErrorEnvelope('MISSING_SEEDS', 'No seed nodes specified for subgraph query', { hint: 'Use --seeds to specify starting nodes. Use partial IDs like "q:topic" or "d:example.com"' });
73
+ console.log(JSON.stringify(envelope, null, 2));
74
+ return 1;
75
+ }
76
+ // Resolve seed IDs — support exact, prefix, and label matching
77
+ const resolvedSeeds = [];
78
+ for (const seed of options.seeds) {
79
+ if (graph.hasNode(seed)) {
80
+ resolvedSeeds.push(seed);
81
+ }
82
+ else {
83
+ // Try prefix match: seed matches start of node ID (e.g. "e:tokio" matches "e:tokio_runtime")
84
+ // Or label match: seed matches node label (case-insensitive)
85
+ const matches = graph.filterNodes((node, attrs) => {
86
+ const lowerSeed = seed.toLowerCase();
87
+ if (node.toLowerCase().startsWith(lowerSeed))
88
+ return true;
89
+ if (attrs.label && attrs.label.toLowerCase().includes(lowerSeed))
90
+ return true;
91
+ return false;
92
+ });
93
+ for (const match of matches) {
94
+ resolvedSeeds.push(match);
95
+ }
96
+ }
97
+ }
98
+ if (resolvedSeeds.length === 0) {
99
+ const envelope = createErrorEnvelope('NO_SEED_FOUND', 'No matching nodes found for provided seeds', { hint: `Available nodes: ${graph.nodes().slice(0, 10).join(', ')}...` });
100
+ console.log(JSON.stringify(envelope, null, 2));
101
+ return 1;
102
+ }
103
+ const subgraph = bfsSubgraph(graph, resolvedSeeds, options.depth);
104
+ const serialized = serializeGraph(subgraph);
105
+ const stats = graphStats(subgraph);
106
+ if (options.format === 'md') {
107
+ // Build human-readable output
108
+ const nodes = new Map();
109
+ subgraph.forEachNode((node, attrs) => nodes.set(node, attrs));
110
+ const edges = [];
111
+ subgraph.forEachEdge((edge, attrs, source, target) => {
112
+ edges.push({ source, target, attrs });
113
+ });
114
+ const lines = [`Subgraph from seeds: ${resolvedSeeds.join(', ')} (depth ${options.depth})`];
115
+ lines.push(`Nodes: ${stats.nodes} (${stats.entities} entities, ${stats.results} results, ${stats.queries} queries, ${stats.domains} domains)`);
116
+ lines.push(`Edges: ${stats.edges}`);
117
+ lines.push('');
118
+ lines.push('Relationships:');
119
+ for (const edge of edges) {
120
+ const src = nodes.get(edge.source);
121
+ const tgt = nodes.get(edge.target);
122
+ const srcLabel = src?.label || edge.source;
123
+ const tgtLabel = tgt?.label || edge.target;
124
+ const srcType = src?.type || '?';
125
+ const tgtType = tgt?.type || '?';
126
+ lines.push(` [${srcType}] ${srcLabel} → (${edge.attrs.relation}, weight=${edge.attrs.weight.toFixed(2)}) → [${tgtType}] ${tgtLabel}`);
127
+ }
128
+ lines.push('');
129
+ lines.push('Nodes:');
130
+ for (const [id, attrs] of nodes) {
131
+ const parts = [`[${attrs.type}] ${attrs.label}`];
132
+ if (attrs.url)
133
+ parts.push(`url=${attrs.url}`);
134
+ if (attrs.entityType)
135
+ parts.push(`entityType=${attrs.entityType}`);
136
+ if (attrs.score)
137
+ parts.push(`score=${attrs.score}`);
138
+ lines.push(` ${id}: ${parts.join(', ')}`);
139
+ }
140
+ console.log(lines.join('\n'));
141
+ }
142
+ else {
143
+ const envelope = createSuccessEnvelope({
144
+ seeds: resolvedSeeds,
145
+ depth: options.depth,
146
+ stats,
147
+ graph: serialized,
148
+ });
149
+ console.log(JSON.stringify(envelope, null, 2));
150
+ }
151
+ return 0;
152
+ }
153
+ //# sourceMappingURL=query-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-graph.js","sourceRoot":"","sources":["../../src/commands/query-graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Raw search subcommand - multi-engine search with RRF fusion and dedup
3
+ */
4
+ import { SearXNGService } from '../service.js';
5
+ export interface RawOptions {
6
+ queries?: string[];
7
+ engines?: string[];
8
+ categories?: string[];
9
+ limit?: number;
10
+ language?: string;
11
+ timeRange?: 'day' | 'week' | 'month' | 'year' | 'all';
12
+ }
13
+ export declare function runRawSearch(service: SearXNGService, options: RawOptions): Promise<number>;
14
+ //# sourceMappingURL=raw.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raw.d.ts","sourceRoot":"","sources":["../../src/commands/raw.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAgC,MAAM,eAAe,CAAC;AAM7E,MAAM,WAAW,UAAU;IACvB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;CACzD;AAsBD,wBAAsB,YAAY,CAC9B,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,UAAU,GACpB,OAAO,CAAC,MAAM,CAAC,CAwIjB"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Raw search subcommand - multi-engine search with RRF fusion and dedup
3
+ */
4
+ import { config } from '../config.js';
5
+ import { rrf } from '../deep/rrf.js';
6
+ import { dedupeByUrl, normalizeUrl } from '../deep/dedupe.js';
7
+ import { createSuccessEnvelope, createErrorEnvelope } from '../protocol.js';
8
+ export async function runRawSearch(service, options) {
9
+ const queries = options.queries || [];
10
+ if (queries.length === 0) {
11
+ const envelope = createErrorEnvelope('MISSING_QUERY', 'No search query provided for raw search', { hint: 'Use: sxng raw "query" or sxng raw --queries "q1,q2,q3"' });
12
+ console.log(JSON.stringify(envelope, null, 2));
13
+ return 1;
14
+ }
15
+ const engines = options.engines || (config.defaultEngine ? [config.defaultEngine] : []);
16
+ if (config.allowedEngines.length > 0 && engines.length > 0) {
17
+ const invalid = engines.filter(e => !config.allowedEngines.includes(e));
18
+ if (invalid.length > 0) {
19
+ const envelope = createErrorEnvelope('INVALID_ENGINES', `Engines not allowed: ${invalid.join(', ')}`, { hint: `Allowed engines: ${config.allowedEngines.join(', ')}` });
20
+ console.log(JSON.stringify(envelope, null, 2));
21
+ return 1;
22
+ }
23
+ }
24
+ try {
25
+ // Multi-query search: each query gets its own results
26
+ const allResponses = [];
27
+ for (const query of queries) {
28
+ const searchOptions = {
29
+ query,
30
+ engines: engines.length > 0 ? engines : undefined,
31
+ categories: options.categories,
32
+ limit: options.limit ?? config.defaultLimit,
33
+ language: options.language,
34
+ timeRange: options.timeRange,
35
+ };
36
+ const response = await service.search(searchOptions);
37
+ allResponses.push(response);
38
+ }
39
+ // Collect all results across queries
40
+ const allResults = [];
41
+ const allSuggestions = [];
42
+ const allAnswers = [];
43
+ const allUnresponsive = [];
44
+ for (const resp of allResponses) {
45
+ allResults.push(...resp.results);
46
+ for (const s of resp.suggestions) {
47
+ if (!allSuggestions.includes(s))
48
+ allSuggestions.push(s);
49
+ }
50
+ for (const a of resp.answers) {
51
+ if (!allAnswers.includes(a))
52
+ allAnswers.push(a);
53
+ }
54
+ for (const u of resp.unresponsiveEngines) {
55
+ const name = Array.isArray(u) ? u[0] : u;
56
+ if (!allUnresponsive.includes(name))
57
+ allUnresponsive.push(name);
58
+ }
59
+ }
60
+ // RRF fusion if multiple queries or engines
61
+ let fusedResults;
62
+ if (allResponses.length > 1 || (engines.length > 1 && allResponses.length === 1)) {
63
+ // Use RRF when we have multiple ranked sources
64
+ const rankings = allResponses.map(resp => resp.results.map(r => ({ id: normalizeUrl(r.url), ...r })));
65
+ const rrfResults = rrf(rankings);
66
+ // Map RRF scores back to results, dedup by URL
67
+ const urlMap = new Map();
68
+ for (const r of allResults) {
69
+ const norm = normalizeUrl(r.url);
70
+ if (!urlMap.has(norm))
71
+ urlMap.set(norm, r);
72
+ }
73
+ fusedResults = rrfResults.map((item) => {
74
+ const original = urlMap.get(item.id);
75
+ if (!original)
76
+ return null;
77
+ return {
78
+ title: original.title,
79
+ url: original.url,
80
+ content: original.content,
81
+ engine: original.engine,
82
+ category: original.category,
83
+ score: item.score,
84
+ publishedDate: original.publishedDate,
85
+ };
86
+ }).filter(Boolean);
87
+ }
88
+ else {
89
+ // Single query, single/no engine: just dedup by URL
90
+ const deduped = dedupeByUrl(allResults);
91
+ fusedResults = deduped.map(r => ({
92
+ title: r.title,
93
+ url: r.url,
94
+ content: r.content,
95
+ engine: r.engine,
96
+ category: r.category,
97
+ score: r.score ?? 0,
98
+ publishedDate: r.publishedDate,
99
+ }));
100
+ }
101
+ // Apply limit
102
+ const limit = options.limit ?? config.defaultLimit;
103
+ if (limit > 0) {
104
+ fusedResults = fusedResults.slice(0, limit);
105
+ }
106
+ const output = {
107
+ queries,
108
+ timestamp: Date.now(),
109
+ totalResults: allResults.length,
110
+ results: fusedResults,
111
+ suggestions: allSuggestions,
112
+ answers: allAnswers,
113
+ unresponsiveEngines: allUnresponsive,
114
+ };
115
+ const envelope = createSuccessEnvelope(output);
116
+ console.log(JSON.stringify(envelope, null, 2));
117
+ return 0;
118
+ }
119
+ catch (error) {
120
+ const envelope = createErrorEnvelope('RAW_SEARCH_FAILED', error instanceof Error ? error.message : 'Raw search failed', { retryable: true, hint: 'Check your network connection and SearXNG server status' });
121
+ console.log(JSON.stringify(envelope, null, 2));
122
+ return 1;
123
+ }
124
+ }
125
+ //# sourceMappingURL=raw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raw.js","sourceRoot":"","sources":["../../src/commands/raw.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Session management subcommands - list, delete
3
+ */
4
+ export interface SessionMeta {
5
+ owner: string;
6
+ description: string;
7
+ createdAt: number;
8
+ updatedAt: number;
9
+ query?: string;
10
+ }
11
+ /** Default session root directory */
12
+ export declare function getDefaultSessionRoot(): string;
13
+ /** Load session meta.json */
14
+ export declare function loadSessionMeta(sessionDir: string): SessionMeta | null;
15
+ /** List all sessions under a root directory */
16
+ export declare function listSessions(rootDir: string): Array<{
17
+ name: string;
18
+ path: string;
19
+ meta: SessionMeta | null;
20
+ rounds: number;
21
+ results: number;
22
+ nodes: number;
23
+ edges: number;
24
+ }>;
25
+ export declare function runSessionList(rootDir?: string): Promise<number>;
26
+ /** Delete sessions by name, or by age with --older <hours> */
27
+ export declare function runSessionDelete(names: string[], olderHours?: number, rootDir?: string): Promise<number>;
28
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/commands/session.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,MAAM,WAAW,WAAW;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qCAAqC;AACrC,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED,6BAA6B;AAC7B,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAQtE;AAED,+CAA+C;AAC/C,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACjB,CAAC,CAqDD;AAED,wBAAsB,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBtE;AAED,8DAA8D;AAC9D,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAyD9G"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Session management subcommands - list, delete
3
+ */
4
+ import { readFileSync, readdirSync, rmSync, statSync } from 'fs';
5
+ import { join } from 'path';
6
+ import { createSuccessEnvelope } from '../protocol.js';
7
+ import { homedir } from 'os';
8
+ /** Default session root directory */
9
+ export function getDefaultSessionRoot() {
10
+ return join(homedir(), '.sxng', 'sessions');
11
+ }
12
+ /** Load session meta.json */
13
+ export function loadSessionMeta(sessionDir) {
14
+ const file = join(sessionDir, 'meta.json');
15
+ try {
16
+ const raw = readFileSync(file, 'utf-8');
17
+ return JSON.parse(raw);
18
+ }
19
+ catch {
20
+ return null;
21
+ }
22
+ }
23
+ /** List all sessions under a root directory */
24
+ export function listSessions(rootDir) {
25
+ try {
26
+ if (!statSync(rootDir).isDirectory())
27
+ return [];
28
+ }
29
+ catch {
30
+ return [];
31
+ }
32
+ const sessions = [];
33
+ for (const entry of readdirSync(rootDir, { withFileTypes: true })) {
34
+ if (!entry.isDirectory())
35
+ continue;
36
+ const sessionDir = join(rootDir, entry.name);
37
+ const meta = loadSessionMeta(sessionDir);
38
+ let rounds = 0;
39
+ let results = 0;
40
+ try {
41
+ const raw = readFileSync(join(sessionDir, 'results.json'), 'utf-8');
42
+ const parsed = JSON.parse(raw);
43
+ if (parsed.status === 'ok' && parsed.data) {
44
+ rounds = parsed.data.rounds || 0;
45
+ results = parsed.data.results?.length || 0;
46
+ }
47
+ }
48
+ catch { /* empty */ }
49
+ let nodes = 0;
50
+ let edges = 0;
51
+ try {
52
+ const raw = readFileSync(join(sessionDir, 'graph.json'), 'utf-8');
53
+ const parsed = JSON.parse(raw);
54
+ if (parsed.status === 'ok' && parsed.data?.stats) {
55
+ nodes = parsed.data.stats.nodes || 0;
56
+ edges = parsed.data.stats.edges || 0;
57
+ }
58
+ }
59
+ catch { /* empty */ }
60
+ sessions.push({ name: entry.name, path: sessionDir, meta, rounds, results, nodes, edges });
61
+ }
62
+ return sessions.sort((a, b) => {
63
+ const aTime = a.meta?.updatedAt || a.meta?.createdAt || 0;
64
+ const bTime = b.meta?.updatedAt || b.meta?.createdAt || 0;
65
+ return bTime - aTime;
66
+ });
67
+ }
68
+ export async function runSessionList(rootDir) {
69
+ const root = rootDir || getDefaultSessionRoot();
70
+ const sessions = listSessions(root);
71
+ const envelope = createSuccessEnvelope({
72
+ sessions: sessions.map(s => ({
73
+ name: s.name,
74
+ path: s.path,
75
+ owner: s.meta?.owner || '',
76
+ description: s.meta?.description || '',
77
+ createdAt: s.meta?.createdAt || 0,
78
+ updatedAt: s.meta?.updatedAt || 0,
79
+ rounds: s.rounds,
80
+ results: s.results,
81
+ nodes: s.nodes,
82
+ edges: s.edges,
83
+ })),
84
+ total: sessions.length,
85
+ root,
86
+ });
87
+ console.log(JSON.stringify(envelope, null, 2));
88
+ return 0;
89
+ }
90
+ /** Delete sessions by name, or by age with --older <hours> */
91
+ export async function runSessionDelete(names, olderHours, rootDir) {
92
+ const root = rootDir || getDefaultSessionRoot();
93
+ if (olderHours) {
94
+ // Delete sessions older than N hours
95
+ const sessions = listSessions(root);
96
+ const now = Date.now();
97
+ const maxAgeMs = olderHours * 3600 * 1000;
98
+ let deleted = 0;
99
+ const deletedNames = [];
100
+ for (const s of sessions) {
101
+ const updatedAt = s.meta?.updatedAt || s.meta?.createdAt || 0;
102
+ if (updatedAt > 0 && (now - updatedAt) > maxAgeMs) {
103
+ rmSync(s.path, { recursive: true, force: true });
104
+ deleted++;
105
+ deletedNames.push(s.name);
106
+ }
107
+ }
108
+ const envelope = createSuccessEnvelope({
109
+ deleted,
110
+ deletedNames,
111
+ remaining: sessions.length - deleted,
112
+ olderHours,
113
+ });
114
+ console.log(JSON.stringify(envelope, null, 2));
115
+ return 0;
116
+ }
117
+ // Delete specific sessions by name
118
+ if (names.length === 0) {
119
+ const envelope = createSuccessEnvelope({ deleted: 0, notFound: [] });
120
+ console.log(JSON.stringify(envelope, null, 2));
121
+ return 0;
122
+ }
123
+ let deleted = 0;
124
+ const notFound = [];
125
+ for (const name of names) {
126
+ const sessionDir = join(root, name);
127
+ try {
128
+ if (statSync(sessionDir).isDirectory()) {
129
+ rmSync(sessionDir, { recursive: true, force: true });
130
+ deleted++;
131
+ }
132
+ else {
133
+ notFound.push(name);
134
+ }
135
+ }
136
+ catch {
137
+ notFound.push(name);
138
+ }
139
+ }
140
+ const envelope = createSuccessEnvelope({ deleted, notFound });
141
+ console.log(JSON.stringify(envelope, null, 2));
142
+ return notFound.length > 0 ? 1 : 0;
143
+ }
144
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/commands/session.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -12,7 +12,7 @@ export interface SearXNGConfig {
12
12
  defaultEngine: string;
13
13
  allowedEngines: string[];
14
14
  defaultLimit: number;
15
- defaultFormat: 'json' | 'csv' | 'html' | 'md';
15
+ defaultFormat: 'json' | 'md';
16
16
  useProxy: boolean;
17
17
  proxyUrl: string;
18
18
  timeout: number;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC;IAC9C,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACnB;AAgHD,eAAO,MAAM,MAAM,EAAE,aAA6B,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACnB;AAgHD,eAAO,MAAM,MAAM,EAAE,aAA6B,CAAC"}
package/dist/config.js CHANGED
@@ -98,7 +98,7 @@ function mergeConfig() {
98
98
  config.defaultLimit = readIntEnv('SEARXNG_DEFAULT_LIMIT', config.defaultLimit);
99
99
  }
100
100
  const envDefaultFormat = process.env.SEARXNG_DEFAULT_FORMAT;
101
- if (envDefaultFormat !== undefined && ['json', 'csv', 'html', 'md'].includes(envDefaultFormat)) {
101
+ if (envDefaultFormat !== undefined && ['json', 'md'].includes(envDefaultFormat)) {
102
102
  config.defaultFormat = envDefaultFormat;
103
103
  }
104
104
  const envUseProxy = process.env.SEARXNG_USE_PROXY;
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Deduplication utilities for search results
3
+ */
4
+ export interface DedupItem {
5
+ url: string;
6
+ title: string;
7
+ content: string;
8
+ [key: string]: unknown;
9
+ }
10
+ export declare function normalizeUrl(url: string): string;
11
+ export declare function dedupeByUrl(items: DedupItem[]): DedupItem[];
12
+ export declare function dedupeBySimHash(items: DedupItem[], threshold?: number): DedupItem[];
13
+ export declare function dedupe(items: DedupItem[], simThreshold?: number): DedupItem[];
14
+ //# sourceMappingURL=dedupe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dedupe.d.ts","sourceRoot":"","sources":["../../src/deep/dedupe.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,WAAW,SAAS;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAWhD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE,CAW3D;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,SAAS,GAAE,MAAa,GAAG,SAAS,EAAE,CAwBzF;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,YAAY,GAAE,MAAa,GAAG,SAAS,EAAE,CAGnF"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Deduplication utilities for search results
3
+ */
4
+ import { SimHash } from './simhash.js';
5
+ export function normalizeUrl(url) {
6
+ try {
7
+ const u = new URL(url);
8
+ // Remove trailing slash, sort params, strip fragments
9
+ u.pathname = u.pathname.replace(/\/$/, '') || '/';
10
+ u.hash = '';
11
+ u.searchParams.sort();
12
+ return u.toString();
13
+ }
14
+ catch {
15
+ return url;
16
+ }
17
+ }
18
+ export function dedupeByUrl(items) {
19
+ const seen = new Map();
20
+ for (const item of items) {
21
+ const norm = normalizeUrl(item.url);
22
+ if (!seen.has(norm)) {
23
+ seen.set(norm, item);
24
+ }
25
+ }
26
+ return Array.from(seen.values());
27
+ }
28
+ export function dedupeBySimHash(items, threshold = 0.85) {
29
+ const simhash = new SimHash();
30
+ const kept = [];
31
+ const hashes = [];
32
+ for (const item of items) {
33
+ const text = `${item.title} ${item.content}`;
34
+ const h = simhash.hash(text);
35
+ let isDuplicate = false;
36
+ for (const existing of hashes) {
37
+ if (simhash.similarity(h, existing) >= threshold) {
38
+ isDuplicate = true;
39
+ break;
40
+ }
41
+ }
42
+ if (!isDuplicate) {
43
+ kept.push(item);
44
+ hashes.push(h);
45
+ }
46
+ }
47
+ return kept;
48
+ }
49
+ export function dedupe(items, simThreshold = 0.85) {
50
+ const urlDeduped = dedupeByUrl(items);
51
+ return dedupeBySimHash(urlDeduped, simThreshold);
52
+ }
53
+ //# sourceMappingURL=dedupe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dedupe.js","sourceRoot":"","sources":["../../src/deep/dedupe.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AASvC,MAAM,UAAU,YAAY,CAAC,GAAW;IACpC,IAAI,CAAC;QACD,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,sDAAsD;QACtD,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC;QAClD,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;QACZ,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QACtB,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,GAAG,CAAC;IACf,CAAC;AACL,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAkB;IAC1C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAqB,CAAC;IAE1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAClB,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACzB,CAAC;IACL,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAkB,EAAE,YAAoB,IAAI;IACxE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAgB,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QAC7C,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE7B,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,KAAK,MAAM,QAAQ,IAAI,MAAM,EAAE,CAAC;YAC5B,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC;gBAC/C,WAAW,GAAG,IAAI,CAAC;gBACnB,MAAM;YACV,CAAC;QACL,CAAC;QAED,IAAI,CAAC,WAAW,EAAE,CAAC;YACf,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnB,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,KAAkB,EAAE,eAAuB,IAAI;IAClE,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IACtC,OAAO,eAAe,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;AACrD,CAAC"}