imperium-crawl 2.5.3 → 2.6.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/README.md +15 -14
- package/dist/batch/job-store.js +1 -1
- package/dist/batch/job-store.js.map +1 -1
- package/dist/brave-api/index.js +1 -1
- package/dist/brave-api/index.js.map +1 -1
- package/dist/cli/config.d.ts +21 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +51 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/engine.d.ts +17 -0
- package/dist/cli/engine.d.ts.map +1 -0
- package/dist/cli/engine.js +440 -0
- package/dist/cli/engine.js.map +1 -0
- package/dist/cli/explore.d.ts +30 -0
- package/dist/cli/explore.d.ts.map +1 -0
- package/dist/cli/explore.js +427 -0
- package/dist/cli/explore.js.map +1 -0
- package/dist/cli/onboarding.d.ts +10 -0
- package/dist/cli/onboarding.d.ts.map +1 -0
- package/dist/cli/onboarding.js +128 -0
- package/dist/cli/onboarding.js.map +1 -0
- package/dist/cli/recorder.d.ts +44 -0
- package/dist/cli/recorder.d.ts.map +1 -0
- package/dist/cli/recorder.js +67 -0
- package/dist/cli/recorder.js.map +1 -0
- package/dist/cli/tui.d.ts +12 -0
- package/dist/cli/tui.d.ts.map +1 -0
- package/dist/cli/tui.js +945 -0
- package/dist/cli/tui.js.map +1 -0
- package/dist/cli/ui.d.ts +26 -0
- package/dist/cli/ui.d.ts.map +1 -0
- package/dist/cli/ui.js +58 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/core/action-executor.d.ts +66 -0
- package/dist/core/action-executor.d.ts.map +1 -0
- package/dist/core/action-executor.js +403 -0
- package/dist/core/action-executor.js.map +1 -0
- package/dist/core/config.d.ts +16 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +56 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/constants.d.ts +40 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/constants.js +86 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/formatters.d.ts +36 -0
- package/dist/core/formatters.d.ts.map +1 -0
- package/dist/core/formatters.js +147 -0
- package/dist/core/formatters.js.map +1 -0
- package/dist/engines/camofox.d.ts +27 -0
- package/dist/engines/camofox.d.ts.map +1 -0
- package/dist/engines/camofox.js +432 -0
- package/dist/engines/camofox.js.map +1 -0
- package/dist/engines/index.d.ts +13 -0
- package/dist/engines/index.d.ts.map +1 -0
- package/dist/engines/index.js +41 -0
- package/dist/engines/index.js.map +1 -0
- package/dist/engines/types.d.ts +63 -0
- package/dist/engines/types.d.ts.map +1 -0
- package/dist/engines/types.js +8 -0
- package/dist/engines/types.js.map +1 -0
- package/dist/flows/engine.js +3 -3
- package/dist/flows/engine.js.map +1 -1
- package/dist/flows/storage.js +1 -1
- package/dist/flows/storage.js.map +1 -1
- package/dist/flows/templates.js +1 -1
- package/dist/flows/templates.js.map +1 -1
- package/dist/flows/types.d.ts +405 -405
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/knowledge/store.js +1 -1
- package/dist/knowledge/store.js.map +1 -1
- package/dist/network/index.d.ts +3 -0
- package/dist/network/index.d.ts.map +1 -0
- package/dist/network/index.js +2 -0
- package/dist/network/index.js.map +1 -0
- package/dist/recipes/data/crypto-websocket.json +11 -0
- package/dist/recipes/data/ecommerce-product.json +25 -0
- package/dist/recipes/data/github-trending.json +19 -0
- package/dist/recipes/data/hn-top-stories.json +22 -0
- package/dist/recipes/data/influencer-competitor-spy.json +14 -0
- package/dist/recipes/data/influencer-content-scout.json +14 -0
- package/dist/recipes/data/influencer-hashtag-scout.json +14 -0
- package/dist/recipes/data/influencer-niche-discovery.json +14 -0
- package/dist/recipes/data/job-listings-greenhouse.json +17 -0
- package/dist/recipes/data/news-article-reader.json +9 -0
- package/dist/recipes/data/product-reviews.json +33 -0
- package/dist/recipes/data/reddit-posts.json +8 -0
- package/dist/recipes/data/seo-page-audit.json +26 -0
- package/dist/recipes/data/social-media-mentions.json +31 -0
- package/dist/recipes/index.d.ts +1 -1
- package/dist/recipes/index.d.ts.map +1 -1
- package/dist/recipes/index.js +14 -14
- package/dist/recipes/index.js.map +1 -1
- package/dist/security/auth-vault.js +1 -1
- package/dist/security/auth-vault.js.map +1 -1
- package/dist/security/index.d.ts +6 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +4 -0
- package/dist/security/index.js.map +1 -0
- package/dist/sessions/browser-state.js +1 -1
- package/dist/sessions/browser-state.js.map +1 -1
- package/dist/sessions/encryption.js +1 -1
- package/dist/sessions/encryption.js.map +1 -1
- package/dist/sessions/manager.js +1 -1
- package/dist/sessions/manager.js.map +1 -1
- package/dist/skills/detector.js +1 -1
- package/dist/skills/detector.js.map +1 -1
- package/dist/skills/index.d.ts +9 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +6 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/manager.js +1 -1
- package/dist/skills/manager.js.map +1 -1
- package/dist/snapshot/store.js +1 -1
- package/dist/snapshot/store.js.map +1 -1
- package/dist/social/index.d.ts +7 -0
- package/dist/social/index.d.ts.map +1 -0
- package/dist/social/index.js +4 -0
- package/dist/social/index.js.map +1 -0
- package/dist/stealth/browser-pool.js +1 -1
- package/dist/stealth/browser-pool.js.map +1 -1
- package/dist/stealth/browser.js +2 -2
- package/dist/stealth/browser.js.map +1 -1
- package/dist/stealth/chrome-profile.js +2 -2
- package/dist/stealth/chrome-profile.js.map +1 -1
- package/dist/stealth/index.js +2 -2
- package/dist/stealth/index.js.map +1 -1
- package/dist/tools/ai-extract.js +1 -1
- package/dist/tools/ai-extract.js.map +1 -1
- package/dist/tools/batch-download.d.ts +1 -1
- package/dist/tools/batch-download.js +1 -1
- package/dist/tools/batch-download.js.map +1 -1
- package/dist/tools/batch-scrape.d.ts +2 -2
- package/dist/tools/batch-scrape.js +1 -1
- package/dist/tools/batch-scrape.js.map +1 -1
- package/dist/tools/browser.d.ts +8 -8
- package/dist/tools/browser.js +4 -4
- package/dist/tools/browser.js.map +1 -1
- package/dist/tools/camofox-status.d.ts +14 -0
- package/dist/tools/camofox-status.d.ts.map +1 -0
- package/dist/tools/camofox-status.js +61 -0
- package/dist/tools/camofox-status.js.map +1 -0
- package/dist/tools/camofox-update.d.ts +29 -0
- package/dist/tools/camofox-update.d.ts.map +1 -0
- package/dist/tools/camofox-update.js +108 -0
- package/dist/tools/camofox-update.js.map +1 -0
- package/dist/tools/crawl.d.ts +2 -2
- package/dist/tools/crawl.js +1 -1
- package/dist/tools/crawl.js.map +1 -1
- package/dist/tools/create-skill.js +3 -3
- package/dist/tools/create-skill.js.map +1 -1
- package/dist/tools/discover-apis.d.ts +1 -1
- package/dist/tools/discover-apis.js +1 -1
- package/dist/tools/discover-apis.js.map +1 -1
- package/dist/tools/download.d.ts +7 -7
- package/dist/tools/download.js +1 -1
- package/dist/tools/download.js.map +1 -1
- package/dist/tools/extract.d.ts +1 -1
- package/dist/tools/extract.js +1 -1
- package/dist/tools/extract.js.map +1 -1
- package/dist/tools/image-search.d.ts +1 -1
- package/dist/tools/image-search.js +2 -2
- package/dist/tools/image-search.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +5 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/instagram.d.ts +1 -1
- package/dist/tools/instagram.js +3 -3
- package/dist/tools/instagram.js.map +1 -1
- package/dist/tools/interact.d.ts +86 -86
- package/dist/tools/interact.js +5 -5
- package/dist/tools/interact.js.map +1 -1
- package/dist/tools/knowledge.js +1 -1
- package/dist/tools/knowledge.js.map +1 -1
- package/dist/tools/list-skills.js +1 -1
- package/dist/tools/list-skills.js.map +1 -1
- package/dist/tools/manifest.d.ts.map +1 -1
- package/dist/tools/manifest.js +9 -0
- package/dist/tools/manifest.js.map +1 -1
- package/dist/tools/map.js +1 -1
- package/dist/tools/map.js.map +1 -1
- package/dist/tools/monitor-websocket.d.ts +1 -1
- package/dist/tools/monitor-websocket.js +1 -1
- package/dist/tools/monitor-websocket.js.map +1 -1
- package/dist/tools/monitor.d.ts +2 -2
- package/dist/tools/news-search.d.ts +1 -1
- package/dist/tools/news-search.js +2 -2
- package/dist/tools/news-search.js.map +1 -1
- package/dist/tools/query-api.d.ts +5 -5
- package/dist/tools/query-api.js +1 -1
- package/dist/tools/query-api.js.map +1 -1
- package/dist/tools/readability.js +1 -1
- package/dist/tools/readability.js.map +1 -1
- package/dist/tools/record-flow.d.ts +2 -2
- package/dist/tools/record-flow.js +3 -3
- package/dist/tools/record-flow.js.map +1 -1
- package/dist/tools/reddit.d.ts +2 -2
- package/dist/tools/reddit.js +3 -3
- package/dist/tools/reddit.js.map +1 -1
- package/dist/tools/rss.js +1 -1
- package/dist/tools/rss.js.map +1 -1
- package/dist/tools/run-flow.d.ts +6 -6
- package/dist/tools/run-skill.d.ts +6 -6
- package/dist/tools/run-skill.js +2 -2
- package/dist/tools/run-skill.js.map +1 -1
- package/dist/tools/scrape.d.ts +4 -4
- package/dist/tools/scrape.js +1 -1
- package/dist/tools/scrape.js.map +1 -1
- package/dist/tools/screenshot.js +1 -1
- package/dist/tools/screenshot.js.map +1 -1
- package/dist/tools/search.d.ts +1 -1
- package/dist/tools/search.js +2 -2
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/snapshot.d.ts +5 -5
- package/dist/tools/snapshot.js +2 -2
- package/dist/tools/snapshot.js.map +1 -1
- package/dist/tools/video-search.d.ts +1 -1
- package/dist/tools/video-search.js +2 -2
- package/dist/tools/video-search.js.map +1 -1
- package/dist/tools/watch.d.ts +2 -2
- package/dist/tools/watch.js +1 -1
- package/dist/tools/watch.js.map +1 -1
- package/dist/tools/youtube.d.ts +1 -1
- package/dist/tools/youtube.js +4 -4
- package/dist/tools/youtube.js.map +1 -1
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/fetcher.js +1 -1
- package/dist/utils/fetcher.js.map +1 -1
- package/dist/utils/robots.js +1 -1
- package/dist/utils/robots.js.map +1 -1
- package/package.json +7 -3
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export const PACKAGE_NAME = "imperium-crawl";
|
|
2
|
+
export const PACKAGE_VERSION = "2.5.0";
|
|
3
|
+
export const DEFAULT_TIMEOUT_MS = 30_000;
|
|
4
|
+
export const DEFAULT_MAX_PAGES = 10;
|
|
5
|
+
export const DEFAULT_MAX_DEPTH = 2;
|
|
6
|
+
export const DEFAULT_CONCURRENCY = 3;
|
|
7
|
+
export const DEFAULT_ROBOTS_CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour
|
|
8
|
+
export const SKILLS_DIR_NAME = ".imperium-crawl";
|
|
9
|
+
export const SKILLS_SUBDIR = "skills";
|
|
10
|
+
export const SESSIONS_SUBDIR = "sessions";
|
|
11
|
+
export const JOBS_SUBDIR = "jobs";
|
|
12
|
+
export const BRAVE_API_BASE = "https://api.search.brave.com/res/v1";
|
|
13
|
+
export const DEFAULT_BROWSER_POOL_SIZE = 3;
|
|
14
|
+
export const DEFAULT_BROWSER_IDLE_TIMEOUT_MS = 300_000; // 5 min
|
|
15
|
+
export const KNOWLEDGE_FILE = "knowledge.json";
|
|
16
|
+
// ── Stealth defaults ──
|
|
17
|
+
// Random window size variation for fingerprint diversity
|
|
18
|
+
const W_OFFSET = Math.floor(Math.random() * 101) - 50; // -50 to +50
|
|
19
|
+
const H_OFFSET = Math.floor(Math.random() * 101) - 50;
|
|
20
|
+
export const STEALTH_ARGS = [
|
|
21
|
+
// ── Core automation hiding ──
|
|
22
|
+
"--disable-blink-features=AutomationControlled",
|
|
23
|
+
"--disable-features=AutomationControlled",
|
|
24
|
+
"--disable-infobars",
|
|
25
|
+
"--no-first-run",
|
|
26
|
+
"--no-default-browser-check",
|
|
27
|
+
"--disable-background-networking",
|
|
28
|
+
"--disable-component-update",
|
|
29
|
+
"--disable-default-apps",
|
|
30
|
+
"--disable-hang-monitor",
|
|
31
|
+
"--disable-popup-blocking",
|
|
32
|
+
"--disable-prompt-on-repost",
|
|
33
|
+
"--disable-sync",
|
|
34
|
+
"--metrics-recording-only",
|
|
35
|
+
"--no-service-autorun",
|
|
36
|
+
"--password-store=basic",
|
|
37
|
+
// ── Phase 9 additions ──
|
|
38
|
+
"--disable-dev-shm-usage", // Docker compatibility (shared memory)
|
|
39
|
+
"--disable-extensions", // No extension detection fingerprint
|
|
40
|
+
"--lang=en-US,en", // Consistent language fingerprint
|
|
41
|
+
`--window-size=${1920 + W_OFFSET},${1080 + H_OFFSET}`, // Random window size variation
|
|
42
|
+
// ── Anti-fingerprinting: WebGL ──
|
|
43
|
+
"--disable-webgl",
|
|
44
|
+
"--disable-webgl2",
|
|
45
|
+
// ── Anti-fingerprinting: Canvas noise suppression ──
|
|
46
|
+
"--disable-canvas-aa",
|
|
47
|
+
// ── Anti-fingerprinting: Client Hints (reduce entropy surface) ──
|
|
48
|
+
"--disable-client-side-phishing-detection",
|
|
49
|
+
"--disable-histogram-customizer",
|
|
50
|
+
"--disable-peer-connection",
|
|
51
|
+
"--disable-permissions-api",
|
|
52
|
+
// ── Additional anti-bot ──
|
|
53
|
+
"--disable-background-timer-throttling",
|
|
54
|
+
"--disable-renderer-backgrounding",
|
|
55
|
+
"--disable-backgrounding-occluded-windows",
|
|
56
|
+
"--disable-ipc-flooding-protection",
|
|
57
|
+
"--disable-gpu-sandbox",
|
|
58
|
+
"--enable-features=NetworkService,NetworkServiceInProcess",
|
|
59
|
+
// ── Webdriver flag ──
|
|
60
|
+
"--webdriver-active=false",
|
|
61
|
+
// ── Hide Chromium presence via prefs ──
|
|
62
|
+
"--browser.search.isOnDefaultSearchProvider=false",
|
|
63
|
+
];
|
|
64
|
+
export const DEFAULT_VIEWPORT = { width: 1920, height: 1080 };
|
|
65
|
+
export const HUMAN_DELAY_MIN_MS = 800;
|
|
66
|
+
export const HUMAN_DELAY_MAX_MS = 2500;
|
|
67
|
+
export const MIN_REPEATING_ELEMENTS = 3;
|
|
68
|
+
// ── Input validation bounds ──
|
|
69
|
+
export const MAX_STRING_LENGTH = 10_000;
|
|
70
|
+
export const MAX_BODY_LENGTH = 1_048_576; // 1MB
|
|
71
|
+
export const MAX_QUERY_LENGTH = 2_000;
|
|
72
|
+
export const MAX_SELECTOR_LENGTH = 1_000;
|
|
73
|
+
export const MAX_URL_LENGTH = 8_192;
|
|
74
|
+
export const MAX_PAGES = 100;
|
|
75
|
+
export const MAX_URLS = 10_000;
|
|
76
|
+
export const MAX_ITEMS = 1_000;
|
|
77
|
+
export const MAX_MESSAGES = 1_000;
|
|
78
|
+
export const MAX_CONCURRENCY = 20;
|
|
79
|
+
export const MAX_WAIT_SECONDS = 300;
|
|
80
|
+
export const MAX_DURATION_SECONDS = 300;
|
|
81
|
+
export const MAX_TIMEOUT_MS = 300_000;
|
|
82
|
+
export const MAX_SELECTOR_KEYS = 50;
|
|
83
|
+
export const MAX_CRAWL_CONTENT_PER_PAGE = 102_400; // 100KB
|
|
84
|
+
// ── Snapshot system ──
|
|
85
|
+
export const MAX_STORED_SNAPSHOTS = 100;
|
|
86
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/core/constants.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatters for CLI mode.
|
|
3
|
+
*
|
|
4
|
+
* Tool execute() returns { content: [{ type: "text", text: JSON.stringify(data) }] }.
|
|
5
|
+
* These formatters transform that data into json, jsonl, csv, or markdown.
|
|
6
|
+
*/
|
|
7
|
+
export type OutputFormat = "json" | "jsonl" | "csv" | "markdown";
|
|
8
|
+
export interface FormatOptions {
|
|
9
|
+
format: OutputFormat;
|
|
10
|
+
pretty?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Parse the first text content block from a tool result.
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseToolOutput(result: {
|
|
16
|
+
content: Array<{
|
|
17
|
+
type: string;
|
|
18
|
+
text?: string;
|
|
19
|
+
}>;
|
|
20
|
+
}): unknown;
|
|
21
|
+
/**
|
|
22
|
+
* Parse the first image content block from a tool result.
|
|
23
|
+
* Returns base64 data + mimeType, or null if no image block found.
|
|
24
|
+
*/
|
|
25
|
+
export declare function parseImageOutput(result: {
|
|
26
|
+
content: Array<{
|
|
27
|
+
type: string;
|
|
28
|
+
data?: string;
|
|
29
|
+
mimeType?: string;
|
|
30
|
+
}>;
|
|
31
|
+
}): {
|
|
32
|
+
data: string;
|
|
33
|
+
mimeType: string;
|
|
34
|
+
} | null;
|
|
35
|
+
export declare function formatOutput(data: unknown, options: FormatOptions): string;
|
|
36
|
+
//# sourceMappingURL=formatters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/core/formatters.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,UAAU,CAAC;AAEjE,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAID;;GAEG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAC1D,OAAO,CAST;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAC7E;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAI3C;AAyHD,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAa1E"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatters for CLI mode.
|
|
3
|
+
*
|
|
4
|
+
* Tool execute() returns { content: [{ type: "text", text: JSON.stringify(data) }] }.
|
|
5
|
+
* These formatters transform that data into json, jsonl, csv, or markdown.
|
|
6
|
+
*/
|
|
7
|
+
// ── Helpers ──────────────────────────────────────────────────────────
|
|
8
|
+
/**
|
|
9
|
+
* Parse the first text content block from a tool result.
|
|
10
|
+
*/
|
|
11
|
+
export function parseToolOutput(result) {
|
|
12
|
+
const textBlock = result.content.find((c) => c.type === "text" && c.text);
|
|
13
|
+
if (!textBlock?.text)
|
|
14
|
+
return null;
|
|
15
|
+
try {
|
|
16
|
+
return JSON.parse(textBlock.text);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
// Not JSON — return raw text
|
|
20
|
+
return textBlock.text;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Parse the first image content block from a tool result.
|
|
25
|
+
* Returns base64 data + mimeType, or null if no image block found.
|
|
26
|
+
*/
|
|
27
|
+
export function parseImageOutput(result) {
|
|
28
|
+
const imgBlock = result.content.find((c) => c.type === "image" && c.data);
|
|
29
|
+
if (!imgBlock?.data)
|
|
30
|
+
return null;
|
|
31
|
+
return { data: imgBlock.data, mimeType: imgBlock.mimeType ?? "image/png" };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Find the primary array field in an object (for jsonl/csv).
|
|
35
|
+
* Looks for common keys like results, items, pages, urls, skills, etc.
|
|
36
|
+
*/
|
|
37
|
+
function findArrayField(data) {
|
|
38
|
+
const priorityKeys = [
|
|
39
|
+
"results",
|
|
40
|
+
"items",
|
|
41
|
+
"pages",
|
|
42
|
+
"urls",
|
|
43
|
+
"links",
|
|
44
|
+
"skills",
|
|
45
|
+
"images",
|
|
46
|
+
"videos",
|
|
47
|
+
"apis",
|
|
48
|
+
"endpoints",
|
|
49
|
+
"messages",
|
|
50
|
+
];
|
|
51
|
+
for (const key of priorityKeys) {
|
|
52
|
+
if (Array.isArray(data[key]))
|
|
53
|
+
return data[key];
|
|
54
|
+
}
|
|
55
|
+
// Fallback: find first array value
|
|
56
|
+
for (const val of Object.values(data)) {
|
|
57
|
+
if (Array.isArray(val))
|
|
58
|
+
return val;
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
// ── CSV Helpers ──────────────────────────────────────────────────────
|
|
63
|
+
function csvEscape(value) {
|
|
64
|
+
if (value === null || value === undefined)
|
|
65
|
+
return "";
|
|
66
|
+
const str = typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
67
|
+
if (str.includes(",") || str.includes('"') || str.includes("\n")) {
|
|
68
|
+
return '"' + str.replace(/"/g, '""') + '"';
|
|
69
|
+
}
|
|
70
|
+
return str;
|
|
71
|
+
}
|
|
72
|
+
function toCsv(rows) {
|
|
73
|
+
if (rows.length === 0)
|
|
74
|
+
return "";
|
|
75
|
+
// Collect all unique keys across all rows
|
|
76
|
+
const keys = [...new Set(rows.flatMap((r) => Object.keys(r)))];
|
|
77
|
+
const header = keys.map(csvEscape).join(",");
|
|
78
|
+
const lines = rows.map((row) => keys.map((k) => csvEscape(row[k])).join(","));
|
|
79
|
+
return [header, ...lines].join("\n");
|
|
80
|
+
}
|
|
81
|
+
// ── Format Functions ─────────────────────────────────────────────────
|
|
82
|
+
function formatJson(data, pretty) {
|
|
83
|
+
return pretty
|
|
84
|
+
? JSON.stringify(data, null, 2)
|
|
85
|
+
: JSON.stringify(data);
|
|
86
|
+
}
|
|
87
|
+
function formatJsonl(data) {
|
|
88
|
+
if (Array.isArray(data)) {
|
|
89
|
+
return data.map((item) => JSON.stringify(item)).join("\n");
|
|
90
|
+
}
|
|
91
|
+
if (data && typeof data === "object") {
|
|
92
|
+
const arr = findArrayField(data);
|
|
93
|
+
if (arr) {
|
|
94
|
+
return arr.map((item) => JSON.stringify(item)).join("\n");
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Single object — emit as one line
|
|
98
|
+
return JSON.stringify(data);
|
|
99
|
+
}
|
|
100
|
+
function formatCsv(data) {
|
|
101
|
+
let rows;
|
|
102
|
+
if (Array.isArray(data)) {
|
|
103
|
+
rows = data.filter((item) => item && typeof item === "object");
|
|
104
|
+
}
|
|
105
|
+
else if (data && typeof data === "object") {
|
|
106
|
+
const arr = findArrayField(data);
|
|
107
|
+
if (arr) {
|
|
108
|
+
rows = arr.filter((item) => item && typeof item === "object");
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
// Single object — one row
|
|
112
|
+
rows = [data];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
return String(data);
|
|
117
|
+
}
|
|
118
|
+
return toCsv(rows);
|
|
119
|
+
}
|
|
120
|
+
function formatMarkdown(data) {
|
|
121
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
122
|
+
const obj = data;
|
|
123
|
+
// Scrape/readability: extract markdown or content field directly
|
|
124
|
+
if (typeof obj.markdown === "string")
|
|
125
|
+
return obj.markdown;
|
|
126
|
+
if (typeof obj.content === "string")
|
|
127
|
+
return obj.content;
|
|
128
|
+
}
|
|
129
|
+
// Fallback: pretty JSON
|
|
130
|
+
return JSON.stringify(data, null, 2);
|
|
131
|
+
}
|
|
132
|
+
// ── Main Entry Point ─────────────────────────────────────────────────
|
|
133
|
+
export function formatOutput(data, options) {
|
|
134
|
+
switch (options.format) {
|
|
135
|
+
case "json":
|
|
136
|
+
return formatJson(data, options.pretty);
|
|
137
|
+
case "jsonl":
|
|
138
|
+
return formatJsonl(data);
|
|
139
|
+
case "csv":
|
|
140
|
+
return formatCsv(data);
|
|
141
|
+
case "markdown":
|
|
142
|
+
return formatMarkdown(data);
|
|
143
|
+
default:
|
|
144
|
+
return formatJson(data, options.pretty);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=formatters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatters.js","sourceRoot":"","sources":["../../src/core/formatters.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,wEAAwE;AAExE;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,MAA2D;IAE3D,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;IAC1E,IAAI,CAAC,SAAS,EAAE,IAAI;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,6BAA6B;QAC7B,OAAO,SAAS,CAAC,IAAI,CAAC;IACxB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAA8E;IAE9E,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;IAC1E,IAAI,CAAC,QAAQ,EAAE,IAAI;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,IAAI,WAAW,EAAE,CAAC;AAC7E,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,IAA6B;IACnD,MAAM,YAAY,GAAG;QACnB,SAAS;QACT,OAAO;QACP,OAAO;QACP,MAAM;QACN,OAAO;QACP,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,MAAM;QACN,WAAW;QACX,UAAU;KACX,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC,GAAG,CAAc,CAAC;IAC9D,CAAC;IAED,mCAAmC;IACnC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;YAAE,OAAO,GAAgB,CAAC;IAClD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,wEAAwE;AAExE,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACrD,MAAM,GAAG,GACP,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpE,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACjE,OAAO,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC;IAC7C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,KAAK,CAAC,IAA+B;IAC5C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEjC,0CAA0C;IAC1C,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAC7B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAC7C,CAAC;IAEF,OAAO,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,wEAAwE;AAExE,SAAS,UAAU,CAAC,IAAa,EAAE,MAAgB;IACjD,OAAO,MAAM;QACX,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/B,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED,SAAS,WAAW,CAAC,IAAa;IAChC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,cAAc,CAAC,IAA+B,CAAC,CAAC;QAC5D,IAAI,GAAG,EAAE,CAAC;YACR,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,mCAAmC;IACnC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,SAAS,CAAC,IAAa;IAC9B,IAAI,IAA+B,CAAC;IAEpC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAG1D,CAAC;IACN,CAAC;SAAM,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC5C,MAAM,GAAG,GAAG,cAAc,CAAC,IAA+B,CAAC,CAAC;QAC5D,IAAI,GAAG,EAAE,CAAC;YACR,IAAI,GAAG,GAAG,CAAC,MAAM,CACf,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CACd,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,0BAA0B;YAC1B,IAAI,GAAG,CAAC,IAA+B,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,cAAc,CAAC,IAAa;IACnC,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7D,MAAM,GAAG,GAAG,IAA+B,CAAC;QAC5C,iEAAiE;QACjE,IAAI,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ;YAAE,OAAO,GAAG,CAAC,QAAQ,CAAC;QAC1D,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ;YAAE,OAAO,GAAG,CAAC,OAAO,CAAC;IAC1D,CAAC;IAED,wBAAwB;IACxB,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,wEAAwE;AAExE,MAAM,UAAU,YAAY,CAAC,IAAa,EAAE,OAAsB;IAChE,QAAQ,OAAO,CAAC,MAAM,EAAE,CAAC;QACvB,KAAK,MAAM;YACT,OAAO,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1C,KAAK,OAAO;YACV,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;QAC3B,KAAK,KAAK;YACR,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC;QACzB,KAAK,UAAU;YACb,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9B;YACE,OAAO,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CamoFox browser engine — REST API wrapper around CamoFox (Camoufox-based stealth browser).
|
|
3
|
+
*
|
|
4
|
+
* CamoFox is a Firefox fork with C++ anti-fingerprinting — it patches
|
|
5
|
+
* navigator.hardwareConcurrency, WebGL, AudioContext, and WebRTC at the C++
|
|
6
|
+
* level before JavaScript ever sees them. No shims, no tells.
|
|
7
|
+
*
|
|
8
|
+
* This engine auto-starts the CamoFox server on first use and communicates
|
|
9
|
+
* via its REST API (default port 9377). It implements BrowserEngine so tool
|
|
10
|
+
* code can switch between Playwright and CamoFox with a single flag.
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* import { camofoxEngine } from "../engines/camofox.js";
|
|
14
|
+
* if (await camofoxEngine.isAvailable()) {
|
|
15
|
+
* await camofoxEngine.launch();
|
|
16
|
+
* const { page, cleanup } = await camofoxEngine.acquirePage({ headless: true });
|
|
17
|
+
* await page.goto("https://example.com");
|
|
18
|
+
* const html = await page.content();
|
|
19
|
+
* await cleanup();
|
|
20
|
+
* }
|
|
21
|
+
*/
|
|
22
|
+
import type { BrowserEngine } from "./types.js";
|
|
23
|
+
export declare const camofoxEngine: BrowserEngine;
|
|
24
|
+
export declare function isCamofoxAvailable(): Promise<boolean>;
|
|
25
|
+
export declare function getCamofoxVersion(): Promise<string | null>;
|
|
26
|
+
export declare function getCamofoxLatestVersion(): Promise<string | null>;
|
|
27
|
+
//# sourceMappingURL=camofox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"camofox.d.ts","sourceRoot":"","sources":["../../src/engines/camofox.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAiC,MAAM,YAAY,CAAC;AAoV/E,eAAO,MAAM,aAAa,EAAE,aAmF3B,CAAC;AAIF,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAE3D;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQhE;AAED,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWtE"}
|