@plurnk/plurnk-schemes-http 1.3.12 → 1.5.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 (47) hide show
  1. package/.env.defaults +18 -46
  2. package/README.md +74 -23
  3. package/SPEC.md +487 -124
  4. package/dist/Config.d.ts +3 -0
  5. package/dist/Config.d.ts.map +1 -0
  6. package/dist/Config.js +18 -0
  7. package/dist/Config.js.map +1 -0
  8. package/dist/ContentType.d.ts +2 -0
  9. package/dist/ContentType.d.ts.map +1 -0
  10. package/dist/ContentType.js +15 -0
  11. package/dist/ContentType.js.map +1 -0
  12. package/dist/ErrorDetail.d.ts +6 -0
  13. package/dist/ErrorDetail.d.ts.map +1 -0
  14. package/dist/ErrorDetail.js +19 -0
  15. package/dist/ErrorDetail.js.map +1 -0
  16. package/dist/Guard.d.ts +1 -1
  17. package/dist/Guard.d.ts.map +1 -1
  18. package/dist/Guard.js +95 -55
  19. package/dist/Guard.js.map +1 -1
  20. package/dist/Http.d.ts +3 -16
  21. package/dist/Http.d.ts.map +1 -1
  22. package/dist/Http.js +817 -331
  23. package/dist/Http.js.map +1 -1
  24. package/dist/TavilyExtract.d.ts +35 -0
  25. package/dist/TavilyExtract.d.ts.map +1 -0
  26. package/dist/TavilyExtract.js +204 -0
  27. package/dist/TavilyExtract.js.map +1 -0
  28. package/dist/WebFetcher.d.ts +88 -18
  29. package/dist/WebFetcher.d.ts.map +1 -1
  30. package/dist/WebFetcher.js +588 -70
  31. package/dist/WebFetcher.js.map +1 -1
  32. package/dist/Ws.d.ts +7 -3
  33. package/dist/Ws.d.ts.map +1 -1
  34. package/dist/Ws.js +432 -96
  35. package/dist/Ws.js.map +1 -1
  36. package/dist/index.d.ts +2 -3
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +4 -10
  39. package/dist/index.js.map +1 -1
  40. package/docs/http.md +108 -53
  41. package/docs/wss.md +39 -43
  42. package/package.json +14 -13
  43. package/dist/Browser.d.ts +0 -84
  44. package/dist/Browser.d.ts.map +0 -1
  45. package/dist/Browser.js +0 -273
  46. package/dist/Browser.js.map +0 -1
  47. package/scripts/install-browser.mjs +0 -19
package/.env.defaults CHANGED
@@ -1,69 +1,41 @@
1
1
  # @plurnk/plurnk-schemes-http — .env.defaults (operator config + defaults floor).
2
2
  #
3
3
  # Every knob this package reads, family-namespaced PLURNK_SCHEMES_HTTP_*. This
4
- # file IS the operator documentation, and the daemon assembles every installed
5
- # member's .env.defaults into one operative floor at boot — set-if-unset under
6
- # the operator's env (service SPEC §operator-config-env-defaults, schemes#31).
4
+ # file is the canonical value registry; {§http-config} owns policy. The daemon
5
+ # assembles every installed member's .env.defaults into one operative floor at
6
+ # boot, set-if-unset under the operator's env {§operator-config-env-defaults}.
7
7
  # UNCOMMENTED keys are real defaults the floor sets. COMMENTED keys are modes
8
8
  # whose ABSENCE is meaningful (unset = the documented behavior) — the floor
9
9
  # must not set them. Standalone (no daemon), the required numerics fail hard
10
10
  # when unset, naming the var.
11
11
  #
12
- # ── Required (render path) ───────────────────────────────────────────────────
13
- # Navigation/render timeout in ms (page.goto networkidle budget).
12
+ # ── Required (acquisition path) ─────────────────────────────────────────────
13
+ # HTTP request timeout in ms.
14
14
  PLURNK_SCHEMES_HTTP_FETCH_TIMEOUT=30000
15
- # Salvage threshold in body-text chars: a networkidle timeout whose DOM already
16
- # holds at least this much innerText is the chatty-page case (long-poll, ad
17
- # refresh) — the render is kept; below it the timeout propagates.
18
- PLURNK_SCHEMES_HTTP_SALVAGE_MIN_BODY_CHARS=200
19
- # Warm-chromium idle teardown in ms: the browser process closes after this long
20
- # with no render activity, and relaunches on the next render.
21
- PLURNK_SCHEMES_HTTP_IDLE_TIMEOUT=900000
22
15
 
23
16
  # ── Defaults (floor-set; override to change) ────────────────────────────────
24
- # Playwright BrowserType method. "launch" uses the compatible bundled Chromium
25
- # unless CHANNEL or EXECUTABLE_PATH selects another local browser. "connect"
26
- # uses a Playwright protocol endpoint; "connectOverCDP" attaches to a running
27
- # Chromium browser; "disabled" explicitly removes rendered HTML retrieval.
28
- PLURNK_SCHEMES_HTTP_PLAYWRIGHT_METHOD=launch
29
- # Browser launch/connection timeout in ms.
30
- PLURNK_SCHEMES_HTTP_PLAYWRIGHT_TIMEOUT=30000
31
- # Headless launch. Set 0 for a visible operator-managed browser session.
32
- PLURNK_SCHEMES_HTTP_PLAYWRIGHT_HEADLESS=1
33
- # Playwright's Chromium sandbox launch option. Playwright defaults this off;
34
- # set 1 only where the host/container supports Chromium user namespaces.
35
- PLURNK_SCHEMES_HTTP_PLAYWRIGHT_CHROMIUM_SANDBOX=0
36
- # Mobile device emulation on the render path (Pixel-5-class viewport + UA):
37
- # responsive sites serve a lighter, less-chrome layout — a better generation
38
- # hint. "0" renders desktop (escape hatch for sites that serve degraded or
39
- # blocked mobile content). Required read: unset crashes at render, naming the var.
40
- PLURNK_SCHEMES_HTTP_MOBILE=1
17
+ # Tavily Extract extraction depth ("basic" or "advanced").
18
+ PLURNK_SCHEMES_HTTP_TAVILY_DEPTH=basic
19
+ # Tavily Extract request timeout in ms.
20
+ PLURNK_SCHEMES_HTTP_TAVILY_TIMEOUT_MS=30000
41
21
  # Per-URL freshness TTL in ms: a re-read of a URL fetched within this window
42
22
  # serves the stored copy with ZERO round-trips (no conditional GET). This makes
43
23
  # a just-materialized web entry immediately readable like any other entry.
44
24
  # 0 opts into revalidation on every read via ETag/304.
45
25
  # Required read: unset crashes, naming the var.
46
26
  PLURNK_SCHEMES_HTTP_TTL_MS=300000
47
- # Max HTTP redirect hops the SSRF-guarded fetch follows (WebFetcher). Each hop is
48
- # re-guarded — a public URL redirecting into private space is refused. 0 follows
49
- # none (strictest). Required read: unset crashes, naming the var.
27
+ # Max HTTP redirect hops automatic WebFetcher acquisition follows. Every hop is
28
+ # checked; 0 follows none. Required read: unset crashes, naming the var.
50
29
  PLURNK_SCHEMES_HTTP_REDIRECTS=5
51
30
  # Maximum buffered characters in one incomplete SSE line/event. Exceeding this
52
31
  # bound terminates the remote stream instead of allowing unbounded memory growth.
53
32
  PLURNK_SCHEMES_HTTP_SSE_MAX_BUFFER_CHARS=1048576
33
+ # Maximum characters retained from a caught fetch, extract, or transport
34
+ # diagnostic in a model-facing Problem detail. Complete errors remain in daemon
35
+ # diagnostics.
36
+ PLURNK_SCHEMES_HTTP_ERROR_DETAIL_LIMIT=512
54
37
 
55
38
  # ── Optional modes (absence IS the mode — never floor-set) ──────────────────
56
- # Required by connect/connectOverCDP: the Playwright or CDP endpoint.
57
- # PLURNK_SCHEMES_HTTP_PLAYWRIGHT_ENDPOINT=http://localhost:9222
58
- # Optional launch channel: chromium, chrome, chrome-beta, chrome-dev,
59
- # chrome-canary, msedge, msedge-beta, msedge-dev, or msedge-canary.
60
- # PLURNK_SCHEMES_HTTP_PLAYWRIGHT_CHANNEL=chrome
61
- # Optional exact browser executable for launch. Mutually exclusive with CHANNEL.
62
- # PLURNK_SCHEMES_HTTP_PLAYWRIGHT_EXECUTABLE_PATH=/usr/bin/chromium
63
- # Chromium JS heap cap in MB (--max-old-space-size). Unset → chromium default.
64
- # PLURNK_SCHEMES_HTTP_CHROMIUM_HEAP_MB=2048
65
-
66
- # Native Playwright installation controls remain authoritative and pass through
67
- # unchanged. These examples are intentionally unset.
68
- # PLAYWRIGHT_BROWSERS_PATH=/var/cache/ms-playwright
69
- # PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
39
+ # Optional Tavily API key for HTML-to-Markdown extraction. When omitted/unset,
40
+ # the installed HTML mimetype projection is used as the local floor.
41
+ # TAVILY_API_KEY=
package/README.md CHANGED
@@ -1,41 +1,92 @@
1
1
  # plurnk-schemes-http
2
2
 
3
- `http(s)://` URI scheme handler for the [plurnk](https://github.com/plurnk/plurnk-service) agent runtime. The **first greenfield `@plurnk/plurnk-schemes-*` sibling** — authored entirely against the DB-free capability contract ([`@plurnk/plurnk-schemes`](https://github.com/plurnk/plurnk-service/tree/main/plurnk-schemes) `SchemeCtx`), importing zero plurnk-service internals.
3
+ HTTP(S) request/response and WebSocket scheme handlers for the
4
+ [plurnk](https://github.com/plurnk/plurnk-service) agent runtime. The package is
5
+ authored against the DB-free
6
+ [`@plurnk/plurnk-schemes`](https://github.com/plurnk/plurnk-service/tree/main/plurnk-schemes)
7
+ `SchemeCtx` contract.
4
8
 
5
- ## What it does
9
+ ## HTTP operations
6
10
 
7
- Lets the model treat any web URL as an addressable, streamable resource:
11
+ | Operation | Behavior |
12
+ | --------------------------------- | ----------------------------------------------------------------------------------------- |
13
+ | Unscoped `READ(http(s)://…)` | Fetch or reuse/revalidate a GET representation, then stream the selected response channel |
14
+ | Scoped `READ(http(s)://…)<scope>` | Apply the standard entry READ to an already-materialized response without refetching |
15
+ | `FIND(http(s)://…):matcher` | Materialize an exact URL when required, then use the universal entry query and matcher |
16
+ | `SEND[200](http(s)://…):body:` | POST the body and stream the response |
17
+ | `EDIT(http(s)://…):body:` | PUT a whole-resource replacement; line-scoped HTTP edits are invalid |
18
+ | `KILL(http(s)://…)` | DELETE the remote resource and stream the response |
19
+ | `SEND[499](http(s)://…)` | Cancel the routed in-flight subscription |
20
+ | `SEND[410](http(s)://…)` | Delete the local stored response entry |
8
21
 
9
- | Op | Behavior |
10
- |---|---|
11
- | `READ(http(s)://host/path)` | Without `<scope>`, fetch/revalidate the URL and stream its readable body. With `<scope>`, read that range from the materialized response without refetching. |
12
- | `FIND(http(s)://host/path):matcher` | Materialize an exact URL when necessary, then query it through the standard entry FIND contract. Glob/regex scopes query already-materialized web entries. |
13
- | `SEND[200](http(s)://…)` | Request with a body (POST); response streams back the same way. |
14
- | `SEND[499](http(s)://…)` | Cancel an in-flight request (abort the fetch). |
15
- | `SEND[410](http(s)://…)` | Delete the cached response entry. |
22
+ A path-pattern FIND surveys already-materialized web entries; it does not crawl
23
+ or discover the remote web. Exact matcher FIND shares the standard flat
24
+ location, weighting, pagination, and status contract.
16
25
 
17
- Response status + headers land in the `header` channel; the body in `body` (the default).
26
+ ## HTTP channels
18
27
 
19
- ## Channels
28
+ | Channel | Content |
29
+ | -------- | -------------------------------------------------------------------------- |
30
+ | `body` | Text, derived Unicode, typed binary marker, SSE data, or HTML-page Markdown |
31
+ | `header` | Origin, acquisition, materializer, projection, provider, and usage evidence |
32
+ | `html` | Original server-source HTML when the origin supplies it |
20
33
 
21
- - `body` — response payload (default channel).
22
- - `header` — `HTTP <status> <statusText>` line + response headers.
34
+ A fragmentless operation publishes only `body`; auxiliary channels remain
35
+ durable and can be addressed explicitly. Remote HTTP status is stored in
36
+ `header`; the PLURNK operation result reports the streaming lifecycle.
37
+ Binary responses use an installed bounded readable projection when available;
38
+ only derived Unicode becomes durable. Otherwise direct operations preserve a
39
+ typed empty marker and return `415`, while exact query preparation prunes the
40
+ unreadable result from automatic search ingestion. Input above the common
41
+ projection ceiling returns `413`.
23
42
 
24
43
  ## Design
25
44
 
26
- - **Streaming via the capability `subscriptions` lifecycle** (`open` → `notifyChunk` → `close`). `open()` returns the worker+teardown-composed `AbortSignal`; a `SubscriptionHandle` is registered so the engine routes `SEND[499]` cancellation to the in-flight `fetch`.
27
- - **Batteries-included rendering** — installation provisions Playwright's compatible Chromium and daemon boot verifies it. The shipped `.env.defaults` also exposes Playwright `launch`, `connect`, and `connectOverCDP`: launch may select an installed browser channel or executable, while connection methods target an operator-managed browser. Rendering may be explicitly disabled; incompatible choices fail instead of falling back silently.
28
- - **DB-free** — reaches the substrate only through `ctx` capabilities (`subscriptions`, `entries`), never a raw DB handle (plurnk-schemes SPEC §5). This is what the keystone capability ctx made possible.
45
+ - WebFetcher checks automatic byte targets and redirects; direct HTTP and
46
+ WebSocket retain their explicit-target authority.
47
+ - Generic GETs negotiate origin Markdown first. When the origin returns HTML,
48
+ configured Tavily produces `body`; otherwise the installed HTML reader is the
49
+ local route. Recoverable Tavily failures use that same reader as a `203`
50
+ recovery floor. Hard provider failures do not silently change producers.
51
+ - `body`, `header`, and `html` settle independently. The selected channel
52
+ determines operation success, so raw server source and evidence remain usable
53
+ when body production fails, and a provider body can survive origin transport
54
+ failure without fabricating HTML.
55
+ - GET representations carry method, acquisition-time, and single-variant cache
56
+ metadata; HTML adds materializer-route evidence, and local derivation adds
57
+ projection identity. Request metadata, `Vary`, `no-store`, expired freshness,
58
+ or a materializer/reader change prevents reuse; operator TTL is a separate
59
+ ceiling. Stale page composites are fully reacquired rather than restored by
60
+ an origin `304`.
61
+ - HTTP(S) and WS(S) entry identity retains protocol, authority, path, ordered
62
+ query, and explicit empty query; a fragment selects a channel.
63
+ - Handler-owned socket state follows the shared readiness, drain,
64
+ and aggregate-shutdown lifecycle.
65
+ - All storage and streaming work uses `SchemeCtx` capabilities rather than a
66
+ raw database handle.
67
+
68
+ The same package registers `wss` (with `ws` routing to it) for
69
+ workspace-scoped full-duplex connections. See [`docs/wss.md`](docs/wss.md) for
70
+ its operation surface and current transport limits.
29
71
 
30
72
  ## Install
31
73
 
32
- ```
33
- npm i @plurnk/plurnk-schemes-http && plurnk start
74
+ Requires Node.js 26 or newer.
75
+
76
+ ```sh
77
+ npm i @plurnk/plurnk-schemes-http
78
+ plurnk start
34
79
  ```
35
80
 
36
- Plugin discovery registers it at boot (`package.json#plurnk.kind === "scheme"`).
37
- No browser setup is required for the default installation.
81
+ The shipped `.env.defaults` is the canonical operator configuration registry.
82
+ To enable Tavily Extract for generic public HTML materialization, set
83
+ `TAVILY_API_KEY` in `.env`. Depth and client timeout are controlled by
84
+ `PLURNK_SCHEMES_HTTP_TAVILY_DEPTH` and
85
+ `PLURNK_SCHEMES_HTTP_TAVILY_TIMEOUT_MS`. Without Tavily,
86
+ `@plurnk/plurnk-mimetypes-text-html` supplies the local body.
38
87
 
39
- ## Tests
88
+ ## Verify
40
89
 
41
- `test:lint` (tsc) + `test:unit` (conformant `SchemeCtx` stub + mock `fetch`).
90
+ ```sh
91
+ npm test
92
+ ```