{"_id":"@arnilo/prism-obscura","_rev":"3-e96896c69a2a403e5105fe6000ca4c84","name":"@arnilo/prism-obscura","dist-tags":{"legacy":"0.3.0","latest":"0.3.0"},"versions":{"0.3.0":{"name":"@arnilo/prism-obscura","version":"0.3.0","keywords":["prism","obscura","browser","cdp","playwright","mcp","tools","agent","mcp"],"license":"MIT","_id":"@arnilo/prism-obscura@0.3.0","maintainers":[{"name":"arnilo","email":"ashiq.niloy@proton.me"}],"homepage":"https://github.com/ashiqrniloy/prism/tree/main/packages/obscura#readme","bugs":{"url":"https://github.com/ashiqrniloy/prism/issues"},"dist":{"shasum":"ddbb3aca5da51e8672a735cb1c88a31cc04baced","tarball":"https://registry.npmjs.org/@arnilo/prism-obscura/-/prism-obscura-0.3.0.tgz","fileCount":26,"integrity":"sha512-MJ6JJEhbmZyYGKjlLbs5OGql+4KorKZnzt0mLTjnFXbgaNV7a3FtZHPAxkWcumAD8Ha3MtOpJ5+yJt5ikafANA==","signatures":[{"sig":"MEUCIQDmmO0ZaTMtulH8tFZpgeondMvkjZCddpcfPe5/EouV9QIgL84c53zRHGga8LtVLziAGzBXKVxpAUI4r8YYunYminc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arnilo%2fprism-obscura@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":61954},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"edb4fcf69689683bf0dd3a9d1f2e88299db06603","scripts":{"test":"node ../../scripts/with-build-lock.mjs node --test dist/__tests__/*.test.js","build":"node ../../scripts/with-build-lock.mjs tsc -p tsconfig.json","test:live":"node --test dist/__tests__/live.test.js","typecheck":"tsc -p tsconfig.json --noEmit","pack:dry-run":"npm pack --dry-run"},"_npmUser":{"name":"arnilo","email":"ashiq.niloy@proton.me"},"repository":{"url":"git+https://github.com/ashiqrniloy/prism.git","type":"git","directory":"packages/obscura"},"_npmVersion":"11.17.0","description":"Optional Prism tools for a host-installed Obscura headless browser: fail-closed process lifecycle, full MCP tool bridge, CDP/Playwright composition, and bounded CLI web tools.","directories":{},"sideEffects":false,"_nodeVersion":"24.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@arnilo/prism":"file:../..","playwright-core":"1.61.0","@arnilo/prism-mcp":"file:../mcp","@arnilo/prism-browser":"file:../browser","@arnilo/prism-web-tools":"file:../web-tools"},"peerDependencies":{"@arnilo/prism":"^0.3.1","playwright-core":"1.61.0","@arnilo/prism-mcp":"^0.3.0","@arnilo/prism-browser":"^0.3.0","@arnilo/prism-web-tools":"^0.3.0"},"peerDependenciesMeta":{"playwright-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/prism-obscura_0.3.0_1788014872419_0.11179601675133477","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Legacy 0.3 package. Prism 0.4+: @arnilo/prism-web-tools/obscura. https://github.com/ashiqrniloy/prism/blob/main/docs/migrate-to-0.4.md#web-browser-and-obscura"}},"time":{"created":"2026-08-29T14:47:52.247Z","modified":"2026-09-01T18:23:21.009Z","0.3.0":"2026-08-29T14:47:52.558Z"},"bugs":{"url":"https://github.com/ashiqrniloy/prism/issues"},"license":"MIT","homepage":"https://github.com/ashiqrniloy/prism/tree/main/packages/obscura#readme","keywords":["prism","obscura","browser","cdp","playwright","mcp","tools","agent","mcp"],"repository":{"url":"git+https://github.com/ashiqrniloy/prism.git","type":"git","directory":"packages/obscura"},"description":"Optional Prism tools for a host-installed Obscura headless browser: fail-closed process lifecycle, full MCP tool bridge, CDP/Playwright composition, and bounded CLI web tools.","maintainers":[{"name":"arnilo","email":"ashiq.niloy@proton.me"}],"readme":"# @arnilo/prism-obscura\n\nOptional [Prism](https://github.com/ashiqrniloy/prism) support for a host-installed\n[Obscura](https://github.com/h4ckf0r0day/obscura) headless browser. Obscura is never\nbundled — install the binary (or use the `h4ckf0r0day/obscura` Docker image) yourself,\nthen point this package at it.\n\n## Install\n\n```bash\nnpm install @arnilo/prism-obscura\n```\n\n## Process lifecycle\n\n`spawnObscuraProcess` runs a shell-free, bounded, ownership-tracked Obscura process\n(the `obscura` binary, a Docker invocation, or any argv). Configuration is validated\nfail-closed: absolute NUL-free command, bounded argv/env, and insecure flags\n(`--allow-private-network`, `--allow-file-access`, non-loopback `--host`) are rejected\nunless `allowInsecureFlags` is set explicitly.\n\n```ts\nimport { spawnObscuraProcess } from \"@arnilo/prism-obscura\";\n\nconst obscura = spawnObscuraProcess({\n  command: \"/usr/local/bin/obscura\",\n  args: [\"serve\", \"--host\", \"127.0.0.1\", \"--port\", \"9222\"],\n});\n\n// Readiness is bounded and proven by a probe you supply (protocol connect, not log parsing).\nawait obscura.waitReady(() => canConnect(\"ws://127.0.0.1:9222\"));\nawait obscura.close(); // SIGTERM → SIGKILL after grace period; process-group kill on POSIX\n```\n\nDocker works through the same seam — no Docker SDK:\n\n```ts\nconst mcp = spawnObscuraProcess({\n  command: \"/usr/bin/docker\",\n  args: [\"run\", \"--rm\", \"-i\", \"h4ckf0r0day/obscura\", \"mcp\"],\n});\n```\n\nGuarantees:\n\n- Shell-free spawn; argv passed byte-for-byte.\n- Minimal environment (`PATH`, `HOME`) unless an explicit `env` is provided.\n- Capped stderr capture for post-mortem diagnostics; errors never echo argv or env values.\n- `close()` is idempotent and kills only resources the package owns; external endpoints\n  are never terminated.\n- Abort signals kill owned processes immediately.\n\nMCP tool bridging, CDP/Playwright composition, and CLI-backed web tools land in\nsubsequent releases (see `plans/039-Obscura-Full-Host-Support-And-Changed-Package-Release.md`).\n\n## Web search, fetch, and scrape\n\n`createObscuraWebTools` builds bounded CLI-backed web tools: standard\n`web_search`/`web_fetch` (one replaceable HTML search profile, constant extraction\nJavaScript, URL-encoded queries only) plus explicit `obscura_fetch`/`obscura_scrape`\nfor native dump modes and batch scrape with Obscura-enforced concurrency. Custom\nscrape expressions and insecure flags are explicit opt-ins; every URL is validated\nas a public HTTP(S) target before a child process starts, and all output is labeled\nuntrusted external content.\n\n```ts\nimport { createObscuraWebTools } from \"@arnilo/prism-obscura\";\n\nconst web = createObscuraWebTools({ command: \"/usr/local/bin/obscura\" });\n```\n\n## CDP and Playwright\n\n`connectObscuraCdp` spawns `obscura serve` (or attaches to an external endpoint) and\nconnects with the host's Playwright through `chromium.connectOverCDP` — never\n`connect()`, never a browser launch.\n\n```ts\nimport { connectObscuraCdp } from \"@arnilo/prism-obscura\";\nimport { createBrowserTools } from \"@arnilo/prism-browser\";\n\nconst session = await connectObscuraCdp({\n  command: \"/usr/local/bin/obscura\",\n  args: [\"serve\", \"--host\", \"127.0.0.1\", \"--port\", \"9222\"],\n});\nconst tools = createBrowserTools({ browser: session.browser });\nawait session.close(); // browser first, then the owned process\n```\n\nEndpoints are loopback-only unless `allowRemoteEndpoint` is set, credentials in the\nURL are always rejected, and remote plain `ws:`/`http:` is refused (Obscura CDP has\nno authentication — use an authenticated tunnel). Raw CDP (screenshots, PDF,\nscreencast) stays available through Playwright's CDP session APIs. See\n[docs/obscura.md](https://github.com/ashiqrniloy/prism/blob/main/docs/obscura.md).\n\n## Security\n\nObscura's CDP and MCP HTTP endpoints have no built-in authentication. This package\nbinds or connects to loopback by default and refuses non-loopback binds without\nexplicit opt-in. For remote deployments, put Obscura behind an authenticating proxy\nor network isolation.","readmeFilename":"README.md"}