pi-lean-portal 0.1.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.
Files changed (55) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +608 -0
  3. package/backends/chromium/index.ts +50 -0
  4. package/backends/chromium-py/bridge.py +67 -0
  5. package/backends/firefox/index.ts +60 -0
  6. package/backends/firefox-py/bridge.py +64 -0
  7. package/backends/playwright-base/playwright-plugin.ts +1294 -0
  8. package/backends/python-adapter.ts +1141 -0
  9. package/backends/python-base/pi_browser_bridge/__init__.py +71 -0
  10. package/backends/python-base/pi_browser_bridge/accessibility.py +408 -0
  11. package/backends/python-base/pi_browser_bridge/bot_detection.py +115 -0
  12. package/backends/python-base/pi_browser_bridge/bridge.py +598 -0
  13. package/backends/python-base/pi_browser_bridge/playwright_base.py +1222 -0
  14. package/backends/python-base/pi_browser_bridge/transport.py +167 -0
  15. package/backends/python-base/pyproject.toml +15 -0
  16. package/browser-cookies.ts +88 -0
  17. package/browser-profile.ts +260 -0
  18. package/browser-status.ts +84 -0
  19. package/browser-toggle.ts +527 -0
  20. package/core/fetch-backend.ts +466 -0
  21. package/core/guides.ts +467 -0
  22. package/core/plugin-api.ts +302 -0
  23. package/core/plugin-config.ts +388 -0
  24. package/core/plugin-registry.ts +263 -0
  25. package/core/router.ts +1186 -0
  26. package/core/shared/accessibility-tree.ts +408 -0
  27. package/core/shared/bot-detection.ts +187 -0
  28. package/core/shared/browser-events.ts +111 -0
  29. package/core/shared/dom-extractor.ts +550 -0
  30. package/core/shared/nav-settle.ts +187 -0
  31. package/core/shared/paths.ts +56 -0
  32. package/core/shared/session-manager.ts +258 -0
  33. package/core/shared/settings-reader.ts +63 -0
  34. package/core/shared/snapshot-cache.ts +231 -0
  35. package/core/shared/storage-state.ts +560 -0
  36. package/core/shared/task-id.ts +77 -0
  37. package/core/shared/url-safety.ts +164 -0
  38. package/index.ts +253 -0
  39. package/package.json +63 -0
  40. package/ship-manifest.test.ts +12 -0
  41. package/tools/browser-back.ts +50 -0
  42. package/tools/browser-click.ts +74 -0
  43. package/tools/browser-console.ts +160 -0
  44. package/tools/browser-inspect.ts +136 -0
  45. package/tools/browser-navigate.ts +254 -0
  46. package/tools/browser-press.ts +80 -0
  47. package/tools/browser-scroll.ts +56 -0
  48. package/tools/browser-snapshot.ts +90 -0
  49. package/tools/browser-type.ts +60 -0
  50. package/tools/index.ts +19 -0
  51. package/tools/utils.ts +157 -0
  52. package/tools/web-fetch.ts +147 -0
  53. package/tools/web-guide.ts +55 -0
  54. package/tools/web-learn.ts +128 -0
  55. package/verify-ship-manifest.ts +126 -0
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Chromium-Py Bridge — Python-side parity reference for stealth backends.
4
+
5
+ Thin subclass of :class:`PlaywrightBridge` that drives Chromium via
6
+ Playwright Python. All shared logic lives in
7
+ :mod:`pi_browser_bridge.playwright_base`.
8
+
9
+ Usage
10
+ -----
11
+ Run the bridge from the command line — it reads JSON-RPC 2.0 requests
12
+ from stdin and writes responses to stdout::
13
+
14
+ python backends/chromium-py/bridge.py
15
+
16
+ The ``PythonPluginAdapter`` (TypeScript) spawns this process and
17
+ communicates via stdin/stdout.
18
+
19
+ Requires
20
+ --------
21
+ * Python >= 3.10
22
+ * ``playwright`` >= 1.50 (``pip install playwright``)
23
+ * Playwright Chromium browsers installed (``playwright install chromium``)
24
+ """
25
+
26
+ import sys
27
+
28
+ from pi_browser_bridge.playwright_base import PlaywrightBridge, check_playwright_or_exit
29
+
30
+
31
+ class ChromiumPyBridge(PlaywrightBridge):
32
+ """Concrete bridge that drives Chromium via Playwright Python.
33
+
34
+ Thin subclass — engine-specific settings only.
35
+ """
36
+
37
+ _plugin_name: str = "chromium-py"
38
+ _user_agent: str = (
39
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 "
40
+ "(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
41
+ )
42
+ _install_hint: str = (
43
+ "Chromium browser not installed. "
44
+ "Run: playwright install chromium (inside backends/python-base/.venv)"
45
+ )
46
+
47
+ def _launch_browser(self):
48
+ """Launch a Chromium browser instance."""
49
+ return self._pw.chromium.launch(
50
+ headless=True,
51
+ args=[
52
+ "--no-sandbox",
53
+ "--disable-setuid-sandbox",
54
+ "--disable-dev-shm-usage",
55
+ "--disable-gpu",
56
+ ],
57
+ )
58
+
59
+
60
+ # ═══════════════════════════════════════════════════════════════════════
61
+ # Entry point
62
+ # ═══════════════════════════════════════════════════════════════════════
63
+
64
+ if __name__ == "__main__":
65
+ check_playwright_or_exit("chromium")
66
+ bridge = ChromiumPyBridge()
67
+ bridge.run()
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Firefox Plugin — Native Node backend using Playwright Firefox.
3
+ *
4
+ * Thin subclass of PlaywrightPluginBase. All shared logic lives in
5
+ * backends/playwright-base/playwright-plugin.ts.
6
+ *
7
+ * Uses probe-then-cache UA capture at first launch, with a hardcoded
8
+ * fallback Firefox UA string. Launch args are empty — Firefox does
9
+ * not accept Chromium sandbox flags.
10
+ */
11
+
12
+ import { firefox } from "playwright";
13
+ import type { Browser } from "playwright";
14
+ import { PlaywrightPluginBase } from "../playwright-base/playwright-plugin.js";
15
+ import {
16
+ DEFAULT_CAPABILITIES,
17
+ type PluginCapabilities,
18
+ } from "../../core/plugin-api.js";
19
+
20
+ // ─── Capabilities ──────────────────────────────────────────────────
21
+
22
+ const FIREFOX_CAPABILITIES: PluginCapabilities = {
23
+ ...DEFAULT_CAPABILITIES,
24
+ engine: "firefox",
25
+ };
26
+
27
+ // ─── Hardcoded Firefox UA fallback (used when dynamic capture fails) ─
28
+
29
+ const FIREFOX_UA_FALLBACK =
30
+ "Mozilla/5.0 (X11; Linux x86_64; rv:135.0) Gecko/20100101 Firefox/135.0";
31
+
32
+ // ─── FirefoxPlugin ────────────────────────────────────────────────
33
+
34
+ export class FirefoxPlugin extends PlaywrightPluginBase {
35
+ readonly name = "firefox";
36
+ readonly capabilities = FIREFOX_CAPABILITIES;
37
+
38
+ /** Opt into probe-then-cache UA capture at lazy browser init. */
39
+ protected readonly captureUserAgent: boolean = true;
40
+
41
+ /**
42
+ * Hardcoded fallback Firefox user-agent.
43
+ * Used only if the dynamic UA capture (about:blank probe) fails.
44
+ */
45
+ protected get userAgent(): string {
46
+ return FIREFOX_UA_FALLBACK;
47
+ }
48
+
49
+ protected async launchBrowser(): Promise<Browser> {
50
+ return firefox.launch({
51
+ headless: true,
52
+ });
53
+ }
54
+
55
+ protected get installHint(): string {
56
+ return "Browser not installed. Run: npx playwright install chromium firefox";
57
+ }
58
+ }
59
+
60
+ export default FirefoxPlugin;
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Firefox-Py Bridge — Python-side parity reference for Firefox-based stealth backends.
4
+
5
+ Thin subclass of :class:`PlaywrightBridge` that drives Firefox via
6
+ Playwright Python. All shared logic lives in
7
+ :mod:`pi_browser_bridge.playwright_base`.
8
+
9
+ Disabled by default — users enable explicitly via ``settings.json``
10
+ when parity-testing against the Node ``firefox`` backend.
11
+
12
+ Usage
13
+ -----
14
+ Run the bridge from the command line — it reads JSON-RPC 2.0 requests
15
+ from stdin and writes responses to stdout::
16
+
17
+ python backends/firefox-py/bridge.py
18
+
19
+ The ``PythonPluginAdapter`` (TypeScript) spawns this process and
20
+ communicates via stdin/stdout.
21
+
22
+ Requires
23
+ --------
24
+ * Python >= 3.10
25
+ * ``playwright`` >= 1.50 (``pip install playwright``)
26
+ * Playwright Firefox browsers installed (``playwright install firefox``)
27
+ """
28
+
29
+ import sys
30
+
31
+ from pi_browser_bridge.playwright_base import PlaywrightBridge, check_playwright_or_exit
32
+
33
+
34
+ class FirefoxPyBridge(PlaywrightBridge):
35
+ """Concrete bridge that drives Firefox via Playwright Python.
36
+
37
+ Thin subclass — engine-specific settings only.
38
+ """
39
+
40
+ _plugin_name: str = "firefox-py"
41
+ _user_agent: str = (
42
+ "Mozilla/5.0 (X11; Linux x86_64; rv:135.0) Gecko/20100101 Firefox/135.0"
43
+ )
44
+ _capture_user_agent: bool = True
45
+ _install_hint: str = (
46
+ "Firefox browser not installed. "
47
+ "Run: playwright install firefox (inside backends/python-base/.venv)"
48
+ )
49
+
50
+ def _launch_browser(self):
51
+ """Launch a Firefox browser instance."""
52
+ return self._pw.firefox.launch(
53
+ headless=True,
54
+ )
55
+
56
+
57
+ # ═══════════════════════════════════════════════════════════════════════
58
+ # Entry point
59
+ # ═══════════════════════════════════════════════════════════════════════
60
+
61
+ if __name__ == "__main__":
62
+ check_playwright_or_exit("firefox")
63
+ bridge = FirefoxPyBridge()
64
+ bridge.run()