@lincoln504/pi-research 0.1.12 ā 1.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 +1 -1
- package/README.md +64 -115
- package/dist/cli.mjs +23211 -0
- package/dist/prompts/research-knowledge-relevance-triage.md +35 -0
- package/dist/prompts/research-knowledge-search-extractor.md +41 -0
- package/dist/prompts/research-tool-usage.md +92 -0
- package/dist/prompts/researcher.md +89 -0
- package/dist/prompts/system-coordinator.md +75 -0
- package/dist/prompts/system-lead-evaluator.md +118 -0
- package/dist/thread-worker.mjs +2611 -0
- package/dist/webgpu-probe.mjs +80 -0
- package/docs/AGENT-SKILL.md +102 -0
- package/docs/ARCHITECTURE.md +306 -80
- package/docs/CONFIGURATION.md +249 -0
- package/docs/KNOWLEDGE-STORE.md +213 -0
- package/docs/PI-EXTENSION.md +91 -0
- package/docs/SDK.md +113 -0
- package/docs/THIRD-PARTY-NOTICES.md +64 -0
- package/package.json +102 -36
- package/scripts/build.cjs +140 -0
- package/scripts/cleanup.cjs +149 -0
- package/scripts/prepare.cjs +28 -0
- package/scripts/setup.cjs +134 -0
- package/skills/pi-research/README.md +90 -0
- package/skills/pi-research/SKILL.md +102 -0
- package/skills/pi-research/references/configuration.md +77 -0
- package/skills/pi-research/scripts/run.mjs +237 -0
- package/src/cleanup/research-cleanup.ts +140 -0
- package/src/cli.ts +1044 -0
- package/src/config.ts +1036 -147
- package/src/constants.ts +115 -84
- package/src/core/health-check-service.ts +265 -0
- package/src/core/interfaces/health-check-interfaces.ts +50 -0
- package/src/core/interfaces/knowledge-interfaces.ts +190 -0
- package/src/core/interfaces/observer-interfaces.ts +67 -0
- package/src/core/interfaces/orchestration-interfaces.ts +86 -0
- package/src/core/interfaces/planning-interfaces.ts +100 -0
- package/src/core/interfaces/process-interfaces.ts +37 -0
- package/src/core/interfaces/research-plan-types.ts +52 -0
- package/src/core/interfaces/scheduler-interfaces.ts +91 -0
- package/src/core/interfaces/service-names.ts +39 -0
- package/src/core/interfaces/state-manager-interfaces.ts +29 -0
- package/src/core/interfaces/steering-interfaces.ts +31 -0
- package/src/core/llm/agentic-repair.ts +169 -0
- package/src/core/llm/inject-date.ts +52 -0
- package/src/core/llm/llm-timeout.ts +64 -0
- package/src/core/llm/llm-utils.ts +86 -0
- package/src/core/llm/model-registry-factory.ts +287 -0
- package/src/core/llm/pi-ai-completion.ts +29 -0
- package/src/core/llm/prompts.ts +50 -0
- package/src/core/llm/research-model-resolver.ts +91 -0
- package/src/core/planning-constants.ts +13 -0
- package/src/core/planning-service.ts +649 -0
- package/src/core/planning-utils.ts +299 -0
- package/src/core/scheduler-factory.ts +48 -0
- package/src/core/scheduler-service.ts +123 -0
- package/src/core/service-initialization.ts +194 -0
- package/src/core/service-interfaces.ts +48 -0
- package/src/core/service-registry.ts +659 -0
- package/src/healthcheck/index.ts +271 -265
- package/src/healthcheck/registry.ts +130 -0
- package/src/index.ts +639 -50
- package/src/infrastructure/browser/browser-cleanup.ts +309 -0
- package/src/infrastructure/browser/browser-client.ts +199 -0
- package/src/infrastructure/browser/browser-error-utils.ts +160 -0
- package/src/infrastructure/browser/browser-lifecycle.ts +120 -0
- package/src/infrastructure/browser/browser-server.ts +174 -0
- package/src/infrastructure/browser/browser-task-scheduler.ts +461 -0
- package/src/infrastructure/browser/cleanup-utils.ts +155 -0
- package/src/infrastructure/browser/client-agent.ts +31 -0
- package/src/infrastructure/browser/config.ts +288 -0
- package/src/infrastructure/browser/ensure-browser.ts +205 -0
- package/src/infrastructure/browser/index.ts +37 -0
- package/src/infrastructure/browser/priority-task-queue.ts +226 -0
- package/src/infrastructure/browser/scheduler-factory.ts +354 -0
- package/src/infrastructure/browser/task-execution-service.ts +209 -0
- package/src/infrastructure/browser/thread-worker-browser.ts +282 -0
- package/src/infrastructure/browser/thread-worker-lifecycle.ts +323 -0
- package/src/infrastructure/browser/thread-worker-messaging.ts +662 -0
- package/src/infrastructure/browser/thread-worker-types.ts +25 -0
- package/src/infrastructure/browser/thread-worker.mjs +2611 -0
- package/src/infrastructure/browser/thread-worker.ts +168 -0
- package/src/infrastructure/browser/worker-pool-manager.ts +449 -0
- package/src/infrastructure/embedding/embedding-client.ts +205 -0
- package/src/infrastructure/embedding/embedding-factory.ts +324 -0
- package/src/infrastructure/embedding/embedding-server.ts +535 -0
- package/src/infrastructure/file-lock-service.ts +592 -0
- package/src/infrastructure/gpu-resource-service.ts +191 -0
- package/src/infrastructure/knowledge-store-service.ts +475 -0
- package/src/infrastructure/metrics-service.ts +129 -0
- package/src/infrastructure/process-lifecycle-service.ts +253 -0
- package/src/infrastructure/scheduler-factory-service.ts +58 -0
- package/src/infrastructure/service-initialization.ts +292 -0
- package/src/infrastructure/state/state-backup-manager.ts +290 -0
- package/src/infrastructure/state/state-browser-api.ts +62 -0
- package/src/infrastructure/state/state-browser-manager.ts +70 -0
- package/src/infrastructure/state/state-manager-service.ts +264 -0
- package/src/infrastructure/state/state-manager.ts +547 -0
- package/src/infrastructure/state/state-metrics.ts +92 -0
- package/src/infrastructure/state/state-migration.ts +103 -0
- package/src/infrastructure/state/state-path-configuration.ts +119 -0
- package/src/infrastructure/state/state-session-api.ts +94 -0
- package/src/infrastructure/state/state-session-manager.ts +127 -0
- package/src/infrastructure/state/state-validator.ts +93 -0
- package/src/infrastructure/types/state-types.ts +85 -0
- package/src/knowledge/chunker.ts +157 -0
- package/src/knowledge/embedder-init.ts +413 -0
- package/src/knowledge/embedder-utils.ts +296 -0
- package/src/knowledge/embedder.ts +592 -0
- package/src/knowledge/index.ts +126 -0
- package/src/knowledge/lancedb-loader.ts +35 -0
- package/src/knowledge/migration.ts +17 -0
- package/src/knowledge/model-config.ts +132 -0
- package/src/knowledge/onnx-env.ts +48 -0
- package/src/knowledge/store-operations.ts +291 -0
- package/src/knowledge/store-schema.ts +79 -0
- package/src/knowledge/store.ts +1251 -0
- package/src/knowledge/transformers-loader.ts +31 -0
- package/src/knowledge/webgpu-probe.mjs +80 -0
- package/src/knowledge/webgpu-viability.ts +255 -0
- package/src/knowledge/writer-queue.ts +252 -0
- package/src/logger.ts +316 -122
- package/src/observers/research-observer-impl.ts +459 -0
- package/src/orchestration/deep-research-orchestrator.ts +524 -773
- package/src/orchestration/deep-research-types.ts +47 -35
- package/src/orchestration/headless-observer.ts +114 -0
- package/src/orchestration/orchestration-types.ts +33 -0
- package/src/orchestration/quick-research-orchestrator.ts +463 -0
- package/src/orchestration/research-orchestration-service.ts +549 -0
- package/src/orchestration/research-session-service.ts +178 -0
- package/src/orchestration/research-synthesis-service.ts +348 -0
- package/src/orchestration/researcher-executor.ts +394 -0
- package/src/orchestration/researcher.ts +115 -42
- package/src/orchestration/service-initialization.ts +109 -0
- package/src/orchestration/session-context.ts +7 -3
- package/src/orchestration/session-state.ts +672 -0
- package/src/prompts/research-knowledge-relevance-triage.md +35 -0
- package/src/prompts/research-knowledge-search-extractor.md +41 -0
- package/src/prompts/research-tool-usage.md +63 -16
- package/src/prompts/researcher.md +59 -136
- package/src/prompts/system-coordinator.md +64 -13
- package/src/prompts/system-lead-evaluator.md +82 -189
- package/src/research-config.ts +872 -0
- package/src/sdk.ts +847 -0
- package/src/security/cisa-kev.ts +72 -9
- package/src/security/cvss.ts +92 -0
- package/src/security/ecosystem.ts +45 -0
- package/src/security/github-advisories.ts +168 -428
- package/src/security/github-advisory-types.ts +282 -0
- package/src/security/index.ts +63 -177
- package/src/security/nvd-client.ts +550 -0
- package/src/security/nvd-types.ts +179 -0
- package/src/security/osv-client.ts +246 -0
- package/src/security/osv-types.ts +285 -0
- package/src/security/types.ts +67 -53
- package/src/skill-install/skill-installer.ts +519 -0
- package/src/stackexchange/index.ts +81 -27
- package/src/stackexchange/output/compact.ts +7 -6
- package/src/stackexchange/output/table.ts +11 -7
- package/src/stackexchange/queries.ts +0 -10
- package/src/stackexchange/rest-client.ts +141 -66
- package/src/stackexchange/types.ts +0 -17
- package/src/tool.ts +15 -423
- package/src/tools/grep.ts +32 -310
- package/src/tools/health-tool-definition.ts +101 -0
- package/src/tools/index.ts +38 -9
- package/src/tools/research-knowledge-search.ts +974 -0
- package/src/tools/research-knowledge-types.ts +77 -0
- package/src/tools/research-tool-definition.ts +494 -0
- package/src/tools/scrape.ts +286 -388
- package/src/tools/search.ts +98 -153
- package/src/tools/security.ts +107 -80
- package/src/tools/stackexchange.ts +58 -35
- package/src/tools/youtube-transcript.ts +163 -0
- package/src/tui/knowledge-search-panel.ts +86 -0
- package/src/tui/pulse.ts +86 -0
- package/src/tui/research-health.ts +124 -0
- package/src/tui/research-panel-color-utils.ts +340 -0
- package/src/tui/research-panel-format.ts +54 -0
- package/src/tui/research-panel-state.ts +404 -0
- package/src/tui/research-panel-wave.ts +280 -0
- package/src/tui/research-panel.ts +339 -435
- package/src/tui/research-tui-manager.ts +233 -0
- package/src/tui/tui-controller.ts +137 -0
- package/src/types/extension-context.ts +18 -49
- package/src/types/index.ts +61 -0
- package/src/types/llm.ts +68 -29
- package/src/types/research-panel-types.ts +61 -0
- package/src/utils/circuit-breaker.ts +146 -0
- package/src/utils/citation-utils.ts +97 -0
- package/src/utils/disk-space-checker.ts +55 -0
- package/src/utils/error-tracker.ts +265 -0
- package/src/utils/host-config.ts +45 -0
- package/src/utils/input-validation.ts +8 -10
- package/src/utils/json-utils.ts +150 -16
- package/src/utils/llm-usage.ts +54 -0
- package/src/utils/log-rotation.ts +125 -0
- package/src/utils/log-utils.ts +159 -0
- package/src/utils/make-resource-loader.ts +3 -1
- package/src/utils/metrics-summary.ts +459 -0
- package/src/utils/metrics.ts +302 -0
- package/src/utils/research-export.ts +28 -12
- package/src/utils/safe-unref.ts +31 -0
- package/src/utils/shared-links.ts +195 -90
- package/src/utils/shutdown-manager.ts +65 -0
- package/src/utils/stdio-capture.ts +407 -0
- package/src/utils/text-utils.ts +264 -7
- package/src/utils/tool-usage-tracker.ts +83 -16
- package/src/utils/url-utils.ts +255 -0
- package/src/utils/user-agent.ts +28 -0
- package/src/web-research/browser-search.ts +179 -0
- package/src/web-research/retry-utils.ts +173 -77
- package/src/web-research/scraper-types.ts +72 -0
- package/src/web-research/scraper-utils.ts +434 -0
- package/src/web-research/search.ts +78 -218
- package/src/web-research/types.ts +9 -24
- package/src/web-research/utils.ts +2 -143
- package/src/web-research/web-scraper.ts +477 -0
- package/src/youtube/index.ts +154 -0
- package/src/youtube/potoken.ts +259 -0
- package/src/youtube/transcript-client.ts +390 -0
- package/src/youtube/video-id.ts +118 -0
- package/config/searxng/default-settings.yml +0 -189
- package/config/searxng/limiter.toml +0 -34
- package/config/tooling/eslint.config.js +0 -73
- package/config/tooling/vitest.config.integration.ts +0 -17
- package/config/tooling/vitest.config.ts +0 -40
- package/config/tooling/vitest.config.unit.ts +0 -12
- package/docs/assets/README-banner.jpg +0 -0
- package/scripts/setup.js +0 -174
- package/src/infrastructure/searxng-lifecycle.ts +0 -577
- package/src/infrastructure/searxng-manager.ts +0 -1183
- package/src/infrastructure/state-manager.ts +0 -918
- package/src/orchestration/deep-research-reducer.ts +0 -129
- package/src/orchestration/id-utils.ts +0 -63
- package/src/security/nvd.ts +0 -532
- package/src/security/osv.ts +0 -487
- package/src/stackexchange/cache.ts +0 -111
- package/src/stackexchange/output/index.ts +0 -7
- package/src/stackexchange/output/json.ts +0 -21
- package/src/tui/searxng-status.ts +0 -80
- package/src/utils/inject-date.ts +0 -29
- package/src/utils/research-error.ts +0 -205
- package/src/utils/searxng-config.ts +0 -94
- package/src/utils/session-state.ts +0 -295
- package/src/web-research/dependencies.ts +0 -20
- package/src/web-research/scrapers.ts +0 -935
- package/tsconfig.json +0 -40
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YouTube video-ID extraction
|
|
3
|
+
*
|
|
4
|
+
* Pure helpers (no I/O) for turning the URLs a researcher already has in its
|
|
5
|
+
* link pool into canonical 11-character YouTube video IDs. The researcher
|
|
6
|
+
* selects which YouTube links to transcribe ā exactly like it selects which
|
|
7
|
+
* pages to scrape ā and this module validates and normalizes that selection.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** A YouTube video ID is always 11 chars from the URL-safe base64 alphabet. */
|
|
11
|
+
const VIDEO_ID_RE = /^[A-Za-z0-9_-]{11}$/;
|
|
12
|
+
|
|
13
|
+
const YOUTUBE_HOSTS = new Set([
|
|
14
|
+
'youtube.com',
|
|
15
|
+
'www.youtube.com',
|
|
16
|
+
'm.youtube.com',
|
|
17
|
+
'music.youtube.com',
|
|
18
|
+
'youtube-nocookie.com',
|
|
19
|
+
'www.youtube-nocookie.com',
|
|
20
|
+
'youtu.be',
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
/** Path prefixes that carry the video ID as the next path segment. */
|
|
24
|
+
const PATH_PREFIXES = ['embed', 'shorts', 'live', 'v'];
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Returns true when the input looks like a YouTube watch/share URL (or a bare
|
|
28
|
+
* 11-char video ID). Used to filter a mixed link pool down to YouTube links.
|
|
29
|
+
*/
|
|
30
|
+
export function isYoutubeUrl(input: string): boolean {
|
|
31
|
+
const trimmed = input.trim();
|
|
32
|
+
if (VIDEO_ID_RE.test(trimmed)) return true;
|
|
33
|
+
try {
|
|
34
|
+
const url = new URL(trimmed);
|
|
35
|
+
return YOUTUBE_HOSTS.has(url.hostname.toLowerCase());
|
|
36
|
+
} catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Extract the canonical 11-character video ID from any common YouTube URL form,
|
|
43
|
+
* or from a bare ID. Returns null when no valid ID can be found ā callers must
|
|
44
|
+
* treat null as "not a usable YouTube video" and skip it.
|
|
45
|
+
*
|
|
46
|
+
* Handles:
|
|
47
|
+
* - bare ID: dQw4w9WgXcQ
|
|
48
|
+
* - youtu.be/<id>: https://youtu.be/dQw4w9WgXcQ?si=...
|
|
49
|
+
* - watch?v=<id>: https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=42
|
|
50
|
+
* - /embed/<id>, /shorts/<id>,
|
|
51
|
+
* /live/<id>, /v/<id>: https://www.youtube.com/shorts/dQw4w9WgXcQ
|
|
52
|
+
*/
|
|
53
|
+
export function extractVideoId(input: string): string | null {
|
|
54
|
+
const trimmed = input.trim();
|
|
55
|
+
if (!trimmed) return null;
|
|
56
|
+
if (VIDEO_ID_RE.test(trimmed)) return trimmed;
|
|
57
|
+
|
|
58
|
+
let url: URL;
|
|
59
|
+
try {
|
|
60
|
+
url = new URL(trimmed);
|
|
61
|
+
} catch {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const host = url.hostname.toLowerCase();
|
|
66
|
+
if (!YOUTUBE_HOSTS.has(host)) return null;
|
|
67
|
+
|
|
68
|
+
// youtu.be/<id>
|
|
69
|
+
if (host === 'youtu.be') {
|
|
70
|
+
const id = url.pathname.split('/').filter(Boolean)[0];
|
|
71
|
+
return id && VIDEO_ID_RE.test(id) ? id : null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// watch?v=<id> (also covers /watch and music.youtube.com/watch)
|
|
75
|
+
const vParam = url.searchParams.get('v');
|
|
76
|
+
if (vParam && VIDEO_ID_RE.test(vParam)) return vParam;
|
|
77
|
+
|
|
78
|
+
// /embed/<id>, /shorts/<id>, /live/<id>, /v/<id>
|
|
79
|
+
const segments = url.pathname.split('/').filter(Boolean);
|
|
80
|
+
if (segments.length >= 2 && PATH_PREFIXES.includes(segments[0]!.toLowerCase())) {
|
|
81
|
+
const id = segments[1]!;
|
|
82
|
+
if (VIDEO_ID_RE.test(id)) return id;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Map a list of raw link-pool entries to a deduplicated list of valid video IDs
|
|
90
|
+
* (preserving order, capped to `max`), while reporting which inputs were not
|
|
91
|
+
* usable YouTube links so the caller can surface that to the agent.
|
|
92
|
+
*/
|
|
93
|
+
export function selectVideoIds(
|
|
94
|
+
urls: string[],
|
|
95
|
+
max: number,
|
|
96
|
+
): { videoIds: string[]; rejected: string[] } {
|
|
97
|
+
const seen = new Set<string>();
|
|
98
|
+
const videoIds: string[] = [];
|
|
99
|
+
const rejected: string[] = [];
|
|
100
|
+
|
|
101
|
+
for (const raw of urls) {
|
|
102
|
+
const id = extractVideoId(raw);
|
|
103
|
+
if (!id) {
|
|
104
|
+
rejected.push(raw);
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (seen.has(id)) continue;
|
|
108
|
+
seen.add(id);
|
|
109
|
+
if (videoIds.length < max) videoIds.push(id);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return { videoIds, rejected };
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Canonical watch URL for a video ID (used in result formatting). */
|
|
116
|
+
export function watchUrl(videoId: string): string {
|
|
117
|
+
return `https://www.youtube.com/watch?v=${videoId}`;
|
|
118
|
+
}
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
# SearXNG Default Configuration for pi-search-scrape Extension
|
|
2
|
-
# IMPROVED: Better timeouts, removed problematic engines, added real user agent
|
|
3
|
-
|
|
4
|
-
general:
|
|
5
|
-
instance_name: "pi SearXNG"
|
|
6
|
-
debug: false
|
|
7
|
-
privacypolicy_url: false
|
|
8
|
-
contact_url: false
|
|
9
|
-
enable_metrics: true # ENABLED for debugging engine issues
|
|
10
|
-
open_metrics: ''
|
|
11
|
-
|
|
12
|
-
brand:
|
|
13
|
-
new_issue_url: https://github.com/searxng/searxng/issues/new
|
|
14
|
-
docs_url: https://docs.searxng.org/
|
|
15
|
-
public_instances: https://searx.space
|
|
16
|
-
wiki_url: https://github.com/searxng/searxng/wiki
|
|
17
|
-
issue_url: https://github.com/searxng/searxng/issues
|
|
18
|
-
|
|
19
|
-
server:
|
|
20
|
-
port: 8080
|
|
21
|
-
bind_address: "0.0.0.0"
|
|
22
|
-
secret_key: ""
|
|
23
|
-
base_url: false
|
|
24
|
-
limiter: false
|
|
25
|
-
public_instance: false
|
|
26
|
-
image_proxy: false
|
|
27
|
-
http_protocol_version: "1.1"
|
|
28
|
-
method: "GET"
|
|
29
|
-
default_http_headers:
|
|
30
|
-
# REAL BROWSER USER AGENT - prevents bot detection
|
|
31
|
-
User-Agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
|
32
|
-
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"
|
|
33
|
-
Accept-Language: "en-US,en;q=0.9"
|
|
34
|
-
Accept-Encoding: "gzip, deflate, br"
|
|
35
|
-
X-Content-Type-Options: nosniff
|
|
36
|
-
X-Download-Options: noopen
|
|
37
|
-
X-Robots-Tag: noindex, nofollow
|
|
38
|
-
Referrer-Policy: no-referrer
|
|
39
|
-
|
|
40
|
-
search:
|
|
41
|
-
safe_search: 1
|
|
42
|
-
autocomplete: ""
|
|
43
|
-
autocomplete_min: 4
|
|
44
|
-
favicon_resolver: ""
|
|
45
|
-
default_lang: "en-US"
|
|
46
|
-
ban_time_on_fail: 5
|
|
47
|
-
max_ban_time_on_fail: 120
|
|
48
|
-
formats:
|
|
49
|
-
- html
|
|
50
|
-
- json
|
|
51
|
-
- csv
|
|
52
|
-
- rss
|
|
53
|
-
suspended_times:
|
|
54
|
-
# Long backoff prevents hammering blocked engines ā re-check after 24h
|
|
55
|
-
SearxEngineAccessDenied: 86400
|
|
56
|
-
SearxEngineCaptcha: 86400
|
|
57
|
-
SearxEngineTooManyRequests: 3600
|
|
58
|
-
cf_SearxEngineCaptcha: 1296000
|
|
59
|
-
cf_SearxEngineAccessDenied: 86400
|
|
60
|
-
recaptcha_SearxEngineCaptcha: 604800
|
|
61
|
-
|
|
62
|
-
ui:
|
|
63
|
-
static_path: ""
|
|
64
|
-
templates_path: ""
|
|
65
|
-
query_in_title: false
|
|
66
|
-
default_theme: simple
|
|
67
|
-
center_alignment: false
|
|
68
|
-
default_locale: ""
|
|
69
|
-
results_on_new_tab: false
|
|
70
|
-
theme_args:
|
|
71
|
-
simple_style: auto
|
|
72
|
-
search_on_category_select: true
|
|
73
|
-
hotkeys: default
|
|
74
|
-
url_formatting: pretty
|
|
75
|
-
|
|
76
|
-
outgoing:
|
|
77
|
-
request_timeout: 20.0 # INCREASED from 10.0
|
|
78
|
-
max_request_timeout: 60.0 # INCREASED from 30.0
|
|
79
|
-
useragent_suffix: ""
|
|
80
|
-
pool_connections: 200 # INCREASED from 150
|
|
81
|
-
pool_maxsize: 30 # INCREASED from 20
|
|
82
|
-
enable_http2: true # ENABLED (was false)
|
|
83
|
-
retries: 3 # INCREASED from 2
|
|
84
|
-
using_tor_proxy: false
|
|
85
|
-
extra_proxy_timeout: 15
|
|
86
|
-
|
|
87
|
-
doi_resolvers:
|
|
88
|
-
oadoi.org: 'https://oadoi.org/'
|
|
89
|
-
doi.org: 'https://doi.org/'
|
|
90
|
-
default_doi_resolver: 'oadoi.org'
|
|
91
|
-
|
|
92
|
-
# Search engines configuration
|
|
93
|
-
#
|
|
94
|
-
# Engine reliability for a private low-volume self-hosted instance (2026):
|
|
95
|
-
# Bing ā most consistently available; scrapes bing.com directly; weak on ambiguous queries
|
|
96
|
-
# Brave ā independent index; moderate bot detection; occasional suspension at burst rates
|
|
97
|
-
# Yahoo ā different backend from Bing; low blocking rate; lower result quality
|
|
98
|
-
# Qwant ā EU-based independent index; low-volume private use is generally fine
|
|
99
|
-
# DuckDuckGo ā ddg-lite endpoint (no vqd); intermittent IP blocks (issue #4824, open)
|
|
100
|
-
# StartPage ā DISABLED: broken in current SearXNG due to missing sgt param (issue #4549, open)
|
|
101
|
-
# Google ā DISABLED: IP-blocks any nontrivial automated use
|
|
102
|
-
#
|
|
103
|
-
# If BRAVE_SEARCH_API_KEY is set, searxng-lifecycle.ts injects a braveapi engine at weight 1.2
|
|
104
|
-
# which uses the official REST API and is not subject to bot detection.
|
|
105
|
-
|
|
106
|
-
engines:
|
|
107
|
-
# Bing: most reliable free general-web engine for private instances at low volume
|
|
108
|
-
- name: bing
|
|
109
|
-
engine: bing
|
|
110
|
-
shortcut: bi
|
|
111
|
-
weight: 1.5
|
|
112
|
-
|
|
113
|
-
# Brave (scraping): independent index, different coverage from Bing
|
|
114
|
-
# Can enter suspension after bursts; max_page 10 respected by SearXNG
|
|
115
|
-
- name: brave
|
|
116
|
-
engine: brave
|
|
117
|
-
shortcut: bv
|
|
118
|
-
weight: 0.8
|
|
119
|
-
|
|
120
|
-
# Yahoo: distinct backend, low blocking rate, fills gaps when others are suspended
|
|
121
|
-
- name: yahoo
|
|
122
|
-
engine: yahoo
|
|
123
|
-
shortcut: yh
|
|
124
|
-
weight: 0.8
|
|
125
|
-
|
|
126
|
-
# Qwant: EU-based independent index, low-volume private use stable
|
|
127
|
-
- name: qwant
|
|
128
|
-
engine: qwant
|
|
129
|
-
shortcut: qw
|
|
130
|
-
weight: 0.7
|
|
131
|
-
|
|
132
|
-
# DuckDuckGo: ddg-lite endpoint (no vqd); intermittent IP blocks (issue #4824 open)
|
|
133
|
-
- name: duckduckgo
|
|
134
|
-
engine: duckduckgo
|
|
135
|
-
shortcut: ddg
|
|
136
|
-
weight: 0.6
|
|
137
|
-
|
|
138
|
-
# DISABLED: startpage ā sgt parameter missing in SearXNG parser (issue #4549, open)
|
|
139
|
-
# DISABLED: google ā IP-blocks automated access within minutes
|
|
140
|
-
|
|
141
|
-
# Wikipedia: Encyclopedic reference
|
|
142
|
-
# - Reliability: HIGH (uses REST API)
|
|
143
|
-
# - Note: Keep weight low to prioritize search engines
|
|
144
|
-
- name: wikipedia
|
|
145
|
-
engine: wikipedia
|
|
146
|
-
shortcut: wp
|
|
147
|
-
categories: [general]
|
|
148
|
-
weight: 0.3 # LOWER - reference only, not primary search
|
|
149
|
-
|
|
150
|
-
# Images (only when category=images is requested)
|
|
151
|
-
- name: bing images
|
|
152
|
-
engine: bing_images
|
|
153
|
-
categories: [images]
|
|
154
|
-
shortcut: bii
|
|
155
|
-
|
|
156
|
-
# News (only when category=news is requested)
|
|
157
|
-
- name: bing news
|
|
158
|
-
engine: bing_news
|
|
159
|
-
categories: [news]
|
|
160
|
-
shortcut: bin
|
|
161
|
-
|
|
162
|
-
# REMOVED: brave_news (engine not available in SearXNG container)
|
|
163
|
-
|
|
164
|
-
# Videos (only when category=videos is requested)
|
|
165
|
-
- name: bing videos
|
|
166
|
-
engine: bing_videos
|
|
167
|
-
categories: [videos]
|
|
168
|
-
shortcut: biv
|
|
169
|
-
|
|
170
|
-
# Technical/IT (only when category=it is requested)
|
|
171
|
-
# REMOVED: stackoverflow (engine not available in SearXNG container)
|
|
172
|
-
- name: github
|
|
173
|
-
engine: github
|
|
174
|
-
categories: [it]
|
|
175
|
-
shortcut: gh
|
|
176
|
-
weight: 1.0
|
|
177
|
-
|
|
178
|
-
# Science/Academic (only when category=science is requested)
|
|
179
|
-
- name: arxiv
|
|
180
|
-
engine: arxiv
|
|
181
|
-
categories: [science]
|
|
182
|
-
weight: 1.5 # INCREASED
|
|
183
|
-
shortcut: arx
|
|
184
|
-
|
|
185
|
-
- name: semantic scholar
|
|
186
|
-
engine: semantic_scholar
|
|
187
|
-
categories: [science]
|
|
188
|
-
weight: 1.5 # INCREASED
|
|
189
|
-
shortcut: sem
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# SearXNG Limiter Configuration for pi-search-scrape
|
|
2
|
-
# This configuration disables all bot detection and rate limiting for local use
|
|
3
|
-
|
|
4
|
-
[botdetection]
|
|
5
|
-
# The prefix defines number of leading bits in an address that are compared
|
|
6
|
-
# to determine whether or not an address is part of a (client) network.
|
|
7
|
-
ipv4_prefix = 32
|
|
8
|
-
ipv6_prefix = 48
|
|
9
|
-
|
|
10
|
-
# Trust localhost requests completely (no bot detection for local connections)
|
|
11
|
-
trusted_proxies = [
|
|
12
|
-
'127.0.0.0/8',
|
|
13
|
-
'::1',
|
|
14
|
-
]
|
|
15
|
-
|
|
16
|
-
[botdetection.ip_limit]
|
|
17
|
-
# Disable rate limiting for link-local addresses (localhost)
|
|
18
|
-
filter_link_local = false
|
|
19
|
-
# Disable link token method (no captcha required)
|
|
20
|
-
link_token = false
|
|
21
|
-
|
|
22
|
-
[botdetection.ip_lists]
|
|
23
|
-
# No IP blocking for local use
|
|
24
|
-
block_ip = []
|
|
25
|
-
|
|
26
|
-
# Allow all localhost requests without restrictions
|
|
27
|
-
pass_ip = [
|
|
28
|
-
'127.0.0.0/8', # IPv4 localhost
|
|
29
|
-
'fe80::/10', # IPv6 link-local
|
|
30
|
-
'0.0.0.0/0', # Allow all IPv4 (for local container use)
|
|
31
|
-
]
|
|
32
|
-
|
|
33
|
-
# Allow SearXNG org IPs for checks
|
|
34
|
-
pass_searxng_org = true
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import js from '@eslint/js';
|
|
2
|
-
import tseslint from '@typescript-eslint/eslint-plugin';
|
|
3
|
-
import tsparser from '@typescript-eslint/parser';
|
|
4
|
-
|
|
5
|
-
export default [
|
|
6
|
-
// Global ignores
|
|
7
|
-
{
|
|
8
|
-
ignores: [
|
|
9
|
-
'node_modules/**',
|
|
10
|
-
'dist/**',
|
|
11
|
-
'*.d.ts',
|
|
12
|
-
'examples/**',
|
|
13
|
-
],
|
|
14
|
-
},
|
|
15
|
-
// JavaScript recommended rules
|
|
16
|
-
js.configs.recommended,
|
|
17
|
-
// TypeScript recommended rules
|
|
18
|
-
{
|
|
19
|
-
files: ['**/*.ts'],
|
|
20
|
-
languageOptions: {
|
|
21
|
-
parser: tsparser,
|
|
22
|
-
parserOptions: {
|
|
23
|
-
ecmaVersion: 2022,
|
|
24
|
-
sourceType: 'module',
|
|
25
|
-
project: './tsconfig.json',
|
|
26
|
-
},
|
|
27
|
-
globals: {
|
|
28
|
-
process: 'readonly',
|
|
29
|
-
console: 'readonly',
|
|
30
|
-
Buffer: 'readonly',
|
|
31
|
-
__dirname: 'readonly',
|
|
32
|
-
__filename: 'readonly',
|
|
33
|
-
require: 'readonly',
|
|
34
|
-
module: 'readonly',
|
|
35
|
-
exports: 'readonly',
|
|
36
|
-
NodeJS: 'readonly',
|
|
37
|
-
setTimeout: 'readonly',
|
|
38
|
-
setInterval: 'readonly',
|
|
39
|
-
clearTimeout: 'readonly',
|
|
40
|
-
clearInterval: 'readonly',
|
|
41
|
-
crypto: 'readonly',
|
|
42
|
-
AbortSignal: 'readonly',
|
|
43
|
-
AbortController: 'readonly',
|
|
44
|
-
Request: 'readonly',
|
|
45
|
-
RequestInit: 'readonly',
|
|
46
|
-
Response: 'readonly',
|
|
47
|
-
FormData: 'readonly',
|
|
48
|
-
fetch: 'readonly',
|
|
49
|
-
URL: 'readonly',
|
|
50
|
-
URLSearchParams: 'readonly',
|
|
51
|
-
ArrayBuffer: 'readonly',
|
|
52
|
-
ReadableStream: 'readonly',
|
|
53
|
-
Blob: 'readonly',
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
plugins: {
|
|
57
|
-
'@typescript-eslint': tseslint,
|
|
58
|
-
},
|
|
59
|
-
rules: {
|
|
60
|
-
// Override specific rules
|
|
61
|
-
'no-console': 'off', // Allow console.log for debugging
|
|
62
|
-
'no-unused-vars': 'off', // Disable in favor of TypeScript version
|
|
63
|
-
'@typescript-eslint/no-unused-vars': [
|
|
64
|
-
'error',
|
|
65
|
-
{
|
|
66
|
-
argsIgnorePattern: '^_',
|
|
67
|
-
varsIgnorePattern: '^_',
|
|
68
|
-
caughtErrorsIgnorePattern: '^_',
|
|
69
|
-
},
|
|
70
|
-
],
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
];
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vitest/config';
|
|
2
|
-
import baseConfig from './vitest.config';
|
|
3
|
-
|
|
4
|
-
export default defineConfig({
|
|
5
|
-
...baseConfig,
|
|
6
|
-
test: {
|
|
7
|
-
...baseConfig.test,
|
|
8
|
-
// Integration tests using testcontainers
|
|
9
|
-
include: ['test/integration/**/*.test.ts'],
|
|
10
|
-
setupFiles: [],
|
|
11
|
-
testTimeout: 180000, // 180 second timeout for integration tests
|
|
12
|
-
maxConcurrency: 1, // Only one integration test at a time due to containers
|
|
13
|
-
fileParallelism: false,
|
|
14
|
-
pool: 'forks',
|
|
15
|
-
hookTimeout: 60000,
|
|
16
|
-
},
|
|
17
|
-
});
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vitest/config';
|
|
2
|
-
import { fileURLToPath } from 'node:url';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
|
|
5
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
-
|
|
7
|
-
export default defineConfig({
|
|
8
|
-
test: {
|
|
9
|
-
globals: true,
|
|
10
|
-
environment: 'node',
|
|
11
|
-
include: ['**/*.test.ts', '**/*.spec.ts'],
|
|
12
|
-
exclude: ['node_modules', 'dist', '.tmp'],
|
|
13
|
-
coverage: {
|
|
14
|
-
provider: 'v8',
|
|
15
|
-
reporter: ['text', 'json', 'html', 'lcov'],
|
|
16
|
-
exclude: [
|
|
17
|
-
'node_modules/',
|
|
18
|
-
'dist/',
|
|
19
|
-
'**/*.test.ts',
|
|
20
|
-
'**/*.spec.ts',
|
|
21
|
-
'**/types.ts',
|
|
22
|
-
'**/index.ts',
|
|
23
|
-
'test/',
|
|
24
|
-
],
|
|
25
|
-
reportOnFailure: true,
|
|
26
|
-
},
|
|
27
|
-
testTimeout: 60000,
|
|
28
|
-
hookTimeout: 30000,
|
|
29
|
-
teardownTimeout: 10000,
|
|
30
|
-
pool: 'threads',
|
|
31
|
-
includeSource: ['src/**/*.ts'],
|
|
32
|
-
setupFiles: ['./test/setup/unit.ts'],
|
|
33
|
-
},
|
|
34
|
-
resolve: {
|
|
35
|
-
alias: {
|
|
36
|
-
'@': path.resolve(__dirname, './src'),
|
|
37
|
-
'@test': path.resolve(__dirname, './test'),
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
});
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vitest/config';
|
|
2
|
-
import baseConfig from './vitest.config';
|
|
3
|
-
|
|
4
|
-
export default defineConfig({
|
|
5
|
-
...baseConfig,
|
|
6
|
-
test: {
|
|
7
|
-
...baseConfig.test,
|
|
8
|
-
include: ['test/unit/**/*.test.ts'],
|
|
9
|
-
setupFiles: ['./test/setup/unit.ts'],
|
|
10
|
-
testTimeout: 10000,
|
|
11
|
-
},
|
|
12
|
-
});
|
|
Binary file
|
package/scripts/setup.js
DELETED
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* pi-research Postinstall Setup Script
|
|
5
|
-
*
|
|
6
|
-
* This script runs automatically after `npm install` and ensures:
|
|
7
|
-
* 1. Playwright browser binaries are installed (Chromium, Firefox, WebKit)
|
|
8
|
-
* 2. System dependencies are available (if run with --system-deps flag)
|
|
9
|
-
*
|
|
10
|
-
* Usage:
|
|
11
|
-
* npm run setup # Full setup: install deps + browsers
|
|
12
|
-
* npm run install:browsers # Install only browser binaries
|
|
13
|
-
* npm run install:deps # Install system dependencies only
|
|
14
|
-
*
|
|
15
|
-
* Environment Variables:
|
|
16
|
-
* PLAYWRIGHT_BROWSERS_PATH - Custom path for browser cache
|
|
17
|
-
* PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 - Skip browser download
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
import { execSync } from 'child_process';
|
|
21
|
-
import { existsSync, readdirSync, statSync } from 'fs';
|
|
22
|
-
import { join, dirname } from 'path';
|
|
23
|
-
import { fileURLToPath } from 'url';
|
|
24
|
-
import { homedir, platform } from 'os';
|
|
25
|
-
|
|
26
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
27
|
-
const __dirname = dirname(__filename);
|
|
28
|
-
|
|
29
|
-
console.log('='.repeat(60));
|
|
30
|
-
console.log('š§ pi-research Setup');
|
|
31
|
-
console.log('='.repeat(60));
|
|
32
|
-
|
|
33
|
-
// Check Node.js version
|
|
34
|
-
const nodeVersion = process.version.replace('v', '');
|
|
35
|
-
const [major] = nodeVersion.split('.').map(Number);
|
|
36
|
-
|
|
37
|
-
console.log(`\nā¹ļø Node.js version: v${nodeVersion}`);
|
|
38
|
-
|
|
39
|
-
const requiredVersions = {
|
|
40
|
-
min: 22,
|
|
41
|
-
preferred: [22, 24]
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
if (major < requiredVersions.min) {
|
|
45
|
-
console.warn(
|
|
46
|
-
`ā ļø WARNING: Node.js ${nodeVersion} is below the minimum required version ${requiredVersions.min}.`
|
|
47
|
-
);
|
|
48
|
-
console.warn(' Please upgrade to Node.js 22.13.0+ or 24.x+');
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
console.log(` Required: >= ${requiredVersions.min}.0.0`);
|
|
52
|
-
|
|
53
|
-
// Check if playwright is installed
|
|
54
|
-
const playwrightPath = join(process.cwd(), 'node_modules', 'playwright');
|
|
55
|
-
|
|
56
|
-
if (!existsSync(playwrightPath)) {
|
|
57
|
-
console.error('\nā ERROR: playwright is not installed.');
|
|
58
|
-
console.error(' Run `npm install` first, then `npm run setup`.');
|
|
59
|
-
process.exit(1);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
console.log('ā
Playwright package installed');
|
|
63
|
-
|
|
64
|
-
// Detect OS for browser installation
|
|
65
|
-
const isLinux = platform() === 'linux';
|
|
66
|
-
const isDarwin = platform() === 'darwin';
|
|
67
|
-
const isWindows = platform() === 'win32';
|
|
68
|
-
|
|
69
|
-
console.log(`\nš¦ Detected platform: ${platform()}`);
|
|
70
|
-
|
|
71
|
-
// Install browsers
|
|
72
|
-
console.log('\nš Installing Playwright browsers...');
|
|
73
|
-
|
|
74
|
-
try {
|
|
75
|
-
// Check if user wants to install system dependencies
|
|
76
|
-
const installDeps = process.argv.includes('--system-deps') ||
|
|
77
|
-
process.env.PLAYWRIGHT_INSTALL_DEPS === 'true';
|
|
78
|
-
|
|
79
|
-
if (installDeps && isLinux) {
|
|
80
|
-
console.log('āļø Installing Linux system dependencies for Playwright...');
|
|
81
|
-
try {
|
|
82
|
-
execSync('npx playwright install-deps', {
|
|
83
|
-
stdio: 'inherit',
|
|
84
|
-
env: { ...process.env, PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '0' }
|
|
85
|
-
});
|
|
86
|
-
console.log('ā
System dependencies installed');
|
|
87
|
-
} catch (error) {
|
|
88
|
-
console.warn('ā ļø Could not install system dependencies automatically.');
|
|
89
|
-
console.warn(' Try running: sudo apt-get install $(npx playwright install-deps --print-deps)');
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Install browser binaries
|
|
94
|
-
// Only Chromium is needed for scraping (as per scrapers.ts implementation)
|
|
95
|
-
console.log(' Installing Chromium browser...');
|
|
96
|
-
execSync('npx playwright install chromium', {
|
|
97
|
-
stdio: 'inherit',
|
|
98
|
-
env: {
|
|
99
|
-
...process.env,
|
|
100
|
-
PLAYWRIGHT_BROWSERS_PATH: process.env.PLAYWRIGHT_BROWSERS_PATH || ''
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
console.log('ā
Browsers installed successfully');
|
|
105
|
-
|
|
106
|
-
// Verify installation
|
|
107
|
-
console.log('\nš Verifying browser installation...');
|
|
108
|
-
const browsers = ['chromium']; // Only Chromium is required for scraping
|
|
109
|
-
const cacheDir = process.env['PLAYWRIGHT_BROWSERS_PATH'] ||
|
|
110
|
-
(process.platform === 'win32'
|
|
111
|
-
? join(process.env['LOCALAPPDATA'] || join(homedir(), 'AppData', 'Local'), 'ms-playwright')
|
|
112
|
-
: join(homedir(), '.cache', 'ms-playwright'));
|
|
113
|
-
|
|
114
|
-
browsers.forEach(browser => {
|
|
115
|
-
let browserDirs = [];
|
|
116
|
-
try {
|
|
117
|
-
browserDirs = readdirSync(cacheDir).filter(f =>
|
|
118
|
-
f.startsWith(browser) && statSync(join(cacheDir, f)).isDirectory()
|
|
119
|
-
);
|
|
120
|
-
} catch {
|
|
121
|
-
// cache dir may not exist yet or may be at a different path
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (browserDirs.length > 0) {
|
|
125
|
-
console.log(` ā
${browser}: ${browserDirs.sort().join(', ')}`);
|
|
126
|
-
} else {
|
|
127
|
-
console.warn(` ā ļø ${browser}: Not found in cache`);
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
// Show browser versions
|
|
132
|
-
console.log('\nš Browser versions:');
|
|
133
|
-
try {
|
|
134
|
-
const playwrightVersion = execSync('npx playwright --version', { encoding: 'utf8' }).trim();
|
|
135
|
-
console.log(` Playwright: ${playwrightVersion}`);
|
|
136
|
-
} catch (error) {
|
|
137
|
-
console.warn(' Could not determine Playwright version');
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
} catch (error) {
|
|
141
|
-
console.error('\nā ERROR: Failed to install browsers');
|
|
142
|
-
console.error(' Error:', error.message);
|
|
143
|
-
console.error('\nš” Troubleshooting:');
|
|
144
|
-
console.error(' 1. Ensure you have internet connectivity');
|
|
145
|
-
console.error(' 2. Try running: npm run install:browsers');
|
|
146
|
-
console.error(' 3. Check Node.js version: node --version');
|
|
147
|
-
console.error(' 4. For Linux: sudo apt-get install -y $(npx playwright install-deps --print-deps)');
|
|
148
|
-
process.exit(1);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
console.log('\n' + '='.repeat(60));
|
|
152
|
-
console.log('š Setup complete! Chromium browser installed. pi-research is ready to use.');
|
|
153
|
-
console.log('='.repeat(60));
|
|
154
|
-
|
|
155
|
-
// Additional info
|
|
156
|
-
console.log('\nš Quick start:');
|
|
157
|
-
console.log(' ⢠npm test - Run unit tests');
|
|
158
|
-
console.log(' ⢠npm run type-check - Type check TypeScript');
|
|
159
|
-
console.log(' ⢠npm run lint - Run ESLint');
|
|
160
|
-
console.log(' ⢠npm run setup - Full setup with system deps');
|
|
161
|
-
|
|
162
|
-
// Platform-specific tips
|
|
163
|
-
if (isLinux) {
|
|
164
|
-
console.log('\nš” Linux tip: If you encounter issues, install system deps:');
|
|
165
|
-
console.log(' sudo apt-get install -y libgbm1 libnss3 libatk1.0-0');
|
|
166
|
-
console.log(' libatk-bridge2.0-0 libcups2 libxkbcommon0 libxcomposite1');
|
|
167
|
-
} else if (isDarwin) {
|
|
168
|
-
console.log('\nš” macOS: Ensure Xcode Command Line Tools are installed:');
|
|
169
|
-
console.log(' xcode-select --install');
|
|
170
|
-
} else if (isWindows) {
|
|
171
|
-
console.log('\nš” Windows: Ensure you have the latest Visual C++ redistributables');
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
console.log('\n');
|