@plurnk/plurnk-schemes-http 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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PossumTech Laboratories
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # plurnk-schemes-http
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-schemes) `SchemeCtx`), importing zero plurnk-service internals.
4
+
5
+ ## What it does
6
+
7
+ Lets the model treat any web URL as an addressable, streamable resource:
8
+
9
+ | Op | Behavior |
10
+ |---|---|
11
+ | `READ(http(s)://host/path)` | `fetch` the URL; stream the response body into the `body` channel as it arrives. A streaming read — returns `102 Processing`, the subscription accumulates, the model reads the entry on a later turn. |
12
+ | `SEND[200](http(s)://…)` | Request with a body (POST); response streams back the same way. |
13
+ | `SEND[499](http(s)://…)` | Cancel an in-flight request (abort the fetch). |
14
+ | `SEND[410](http(s)://…)` | Delete the cached response entry. |
15
+
16
+ Response status + headers land in the `header` channel; the body in `body` (the default).
17
+
18
+ ## Channels
19
+
20
+ - `body` — response payload (default channel).
21
+ - `header` — `HTTP <status> <statusText>` line + response headers.
22
+
23
+ ## Design
24
+
25
+ - **Streaming via the capability `subscriptions` lifecycle** (`open` → `notifyChunk` → `close`). `open()` returns the run+teardown-composed `AbortSignal`; a `SubscriptionHandle` is registered so the engine routes `SEND[499]` cancellation to the in-flight `fetch`.
26
+ - **No runtime dependencies** — `fetch`, `AbortController`, `TextDecoder`, `ReadableStream` are Node ≥25 built-ins.
27
+ - **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.
28
+
29
+ ## Install
30
+
31
+ ```
32
+ npm i @plurnk/plurnk-schemes-http && plurnk start
33
+ ```
34
+
35
+ Plugin discovery registers it at boot (`package.json#plurnk.kind === "scheme"`).
36
+
37
+ ## Tests
38
+
39
+ `test:lint` (tsc) + `test:unit` (conformant `SchemeCtx` stub + mock `fetch`).
package/SPEC.md ADDED
@@ -0,0 +1,62 @@
1
+ # plurnk-schemes-http — Specification
2
+
3
+ `http(s)://` scheme handler. Implements the `@plurnk/plurnk-schemes` author contract (SPEC §2 interface + §3.bis capability ctx). Consumed by plurnk-service via plugin discovery.
4
+
5
+ ## §1 Manifest
6
+
7
+ ```ts
8
+ static manifest: SchemeManifest = {
9
+ name: "http",
10
+ channels: { body: "text/markdown", header: "text/markdown" },
11
+ defaultChannel: "body",
12
+ category: "data",
13
+ scope: "session",
14
+ writableBy: ["model", "client"],
15
+ volatile: true, // remote content can change between fetches
16
+ modelVisible: true,
17
+ flags: { requiresWeb: true }, // excluded under the loop's noWeb flag
18
+ };
19
+ ```
20
+
21
+ `package.json#plurnk`: `{ "kind": "scheme", "name": "http" }`.
22
+
23
+ **Open question — dual prefix.** plurnk-service's `SchemeRegistry` keys handlers by a single name (`register("http", …)`); there is no alias mechanism today. This package serves both `http://` and `https://`. How the second prefix registers (registry alias, the handler claiming both, or a convention) is a plurnk-service concern — tracked with the consumer, not resolved here.
24
+
25
+ ## §2 Op surface
26
+
27
+ Implemented against the DB-free `SchemeCtx` (no `ctx.db`):
28
+
29
+ - `read(statement, ctx): Promise<PassthroughResult>` — fetch + stream (below).
30
+ - `send(statement, ctx): Promise<PassthroughResult>` — status-as-verb dispatch (200/410/499; else 501).
31
+
32
+ Results use the `passthrough` family (read-only / network shape) — http entries are coordinate/URL-addressed, not entry-CRUD-backed.
33
+
34
+ ## §3 Streaming lifecycle
35
+
36
+ READ and SEND[200] share one core:
37
+
38
+ 1. `ctx.subscriptions.open(pathname, handle)` — registers the subscription for cancel routing; returns the run+teardown-composed `AbortSignal`. The handle's `cancel()` aborts a local `AbortController` wired to the `fetch`.
39
+ 2. `fetch(url, { signal })` — GET (READ) or POST (SEND[200], body from `SendBody.raw`).
40
+ 3. Response status + headers → `ctx.subscriptions.notifyChunk("header", …)`.
41
+ 4. Body chunks → `ctx.subscriptions.notifyChunk("body", chunk)` as they arrive (fused append + stream/event).
42
+ 5. `ctx.subscriptions.close("done", "HTTP <status>; <n> bytes")` on clean end; `close("error", reason)` on failure.
43
+
44
+ Returns `102 Processing` on success (the subscription drives the channel content). The composed signal aborting (loop.cancel) and the local handle (SEND[499]) both tear the fetch down.
45
+
46
+ ## §4 Status mapping
47
+
48
+ | Outcome | status |
49
+ |---|---|
50
+ | Stream opened (READ / SEND[200] success) | 102 |
51
+ | SEND[410] delete | as `ctx.entries.delete` returns |
52
+ | SEND[499] cancel | 200 (engine already routed teardown to the handle) |
53
+ | Client-cancelled fetch | 499 (`kind: aborted`) |
54
+ | Upstream / network failure | 502 (`kind: fetch_failed`) |
55
+ | Non-url target | 400 (`kind: bad_target`) |
56
+ | Uninterpreted SEND status | 501 (`kind: unsupported_send`) |
57
+
58
+ Error results carry a `scheme:http` `TelemetryEvent` (via `Results.error`).
59
+
60
+ ## §5 No runtime dependencies
61
+
62
+ `fetch` / `AbortController` / `TextDecoder` / `ReadableStream` are Node ≥25 built-ins. The package declares only peer deps (`@plurnk/plurnk-schemes`, `@plurnk/plurnk-grammar`) — never pulls a transport library.
package/dist/Http.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ import type { SchemeCtx, PassthroughResult, SchemeManifest } from "@plurnk/plurnk-schemes";
2
+ import type { ReadStatement, SendStatement } from "@plurnk/plurnk-grammar";
3
+ export default class Http {
4
+ #private;
5
+ static manifest: SchemeManifest;
6
+ read(statement: ReadStatement, ctx: SchemeCtx): Promise<PassthroughResult>;
7
+ send(statement: SendStatement, ctx: SchemeCtx): Promise<PassthroughResult>;
8
+ }
9
+ //# sourceMappingURL=Http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Http.d.ts","sourceRoot":"","sources":["../src/Http.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACR,SAAS,EAET,iBAAiB,EACjB,cAAc,EACjB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAW,MAAM,wBAAwB,CAAC;AAMpF,MAAM,CAAC,OAAO,OAAO,IAAI;;IACrB,MAAM,CAAC,QAAQ,EAAE,cAAc,CAe7B;IAII,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAa1E,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA2FnF"}
package/dist/Http.js ADDED
@@ -0,0 +1,141 @@
1
+ // http(s):// scheme handler — the first greenfield `@plurnk/plurnk-schemes-*`
2
+ // sibling, authored entirely against the DB-free capability ctx (SchemeCtx).
3
+ // It never imports plurnk-service and never touches a raw DB handle (SPEC §5);
4
+ // the substrate is reached only through intent, via the injected caps.
5
+ //
6
+ // Surface:
7
+ // READ(http(s)://host/path) — fetch the URL; stream the response body into
8
+ // the `body` channel as it arrives. A streaming
9
+ // read (SPEC §7.1): returns 102 Processing
10
+ // immediately, the subscription accumulates,
11
+ // the model reads the entry on a later turn.
12
+ // SEND[200](http(s)://...) — request with a body (POST by default); the
13
+ // 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.
16
+ //
17
+ // Network exception: SPEC §5 forbids opening connections "unless specifically
18
+ // a network scheme." This IS that scheme — `fetch` is the whole point. No
19
+ // runtime deps: `fetch` and `AbortController` are Node built-ins.
20
+ import { Results } from "@plurnk/plurnk-schemes";
21
+ // The channel the response body streams into, and the header metadata channel.
22
+ const BODY = "body";
23
+ const HEADER = "header";
24
+ export default class Http {
25
+ static manifest = {
26
+ name: "http",
27
+ // body: the response payload (mimetype is per-call — set from the
28
+ // response Content-Type — so channels declares the names, the write
29
+ // carries the actual mimetype). header: the response status line + headers.
30
+ channels: { [BODY]: "text/markdown", [HEADER]: "text/markdown" },
31
+ defaultChannel: BODY,
32
+ category: "data",
33
+ scope: "session",
34
+ writableBy: ["model", "client"],
35
+ volatile: true, // remote content can change between fetches
36
+ modelVisible: true,
37
+ flags: {
38
+ requiresWeb: true, // excluded under the loop's noWeb flag
39
+ },
40
+ };
41
+ // READ → fetch + stream the response body. Returns 102 Processing; the
42
+ // subscription drives the channel content the model sees next turn.
43
+ async read(statement, ctx) {
44
+ if (statement.target === null || statement.target.kind !== "url") {
45
+ return Http.#bad(400, "http", "bad_target", "READ requires an http(s):// URL target");
46
+ }
47
+ return Http.#fetchStream(statement.target, ctx, undefined);
48
+ }
49
+ // SEND dispatch — status-code-as-verb (SPEC §3.5).
50
+ // 200 → request with body (POST), stream response
51
+ // 410 → delete the cached entry
52
+ // 499 → cancel in-flight (handled by the subscription's force-cancel;
53
+ // the engine routes 499 to the registered SubscriptionHandle, so a
54
+ // scheme-level no-op here is correct — teardown already happened)
55
+ async send(statement, ctx) {
56
+ if (statement.target === null || statement.target.kind !== "url") {
57
+ return Http.#bad(400, "http", "bad_target", "SEND requires an http(s):// URL target");
58
+ }
59
+ const status = statement.signal;
60
+ if (status === 200) {
61
+ const body = statement.body?.raw ?? "";
62
+ return Http.#fetchStream(statement.target, ctx, body);
63
+ }
64
+ if (status === 410) {
65
+ const { status: delStatus } = await ctx.entries.delete(statement.target.pathname);
66
+ return { shape: "passthrough", status: delStatus };
67
+ }
68
+ if (status === 499) {
69
+ // Cancellation is routed by the engine to the subscription's
70
+ // SubscriptionHandle.cancel (registered in #fetchStream). Nothing
71
+ // for the scheme to do at the op level.
72
+ return { shape: "passthrough", status: 200 };
73
+ }
74
+ // Entry-bearing schemes return 501 for status codes they don't interpret.
75
+ return Http.#bad(501, "http", "unsupported_send", `SEND[${status}] not supported by http`);
76
+ }
77
+ // The streaming core, shared by READ and SEND[200]. Opens the subscription
78
+ // (registering the abort handle for SEND[499] routing), fetches, and pumps
79
+ // the response body into the BODY channel chunk-by-chunk via the fused
80
+ // notifyChunk. Settles via close().
81
+ static async #fetchStream(target, ctx, requestBody) {
82
+ const url = Http.#urlFrom(target);
83
+ const pathname = target.pathname;
84
+ // Local AbortController for force-cancel from outside (SEND[499]).
85
+ const local = new AbortController();
86
+ const handle = { cancel: () => local.abort() };
87
+ // open() returns the run+teardown-composed signal — fires on loop.cancel
88
+ // OR our local teardown. Wire it to the fetch so either path aborts it.
89
+ const composed = await ctx.subscriptions.open(pathname, handle);
90
+ const onAbort = () => local.abort();
91
+ composed.addEventListener("abort", onAbort, { once: true });
92
+ try {
93
+ const response = await fetch(url, {
94
+ method: requestBody === undefined ? "GET" : "POST",
95
+ body: requestBody,
96
+ signal: local.signal,
97
+ redirect: "follow",
98
+ });
99
+ // Record the response status + headers in the HEADER channel.
100
+ const headerLines = [`HTTP ${response.status} ${response.statusText}`];
101
+ for (const [k, v] of response.headers)
102
+ headerLines.push(`${k}: ${v}`);
103
+ await ctx.subscriptions.notifyChunk(HEADER, headerLines.join("\n"));
104
+ if (response.body === null) {
105
+ await ctx.subscriptions.close("done", `HTTP ${response.status}; empty body`);
106
+ return { shape: "passthrough", status: 102 };
107
+ }
108
+ let bytes = 0;
109
+ const decoder = new TextDecoder();
110
+ for await (const chunk of response.body) {
111
+ bytes += chunk.length;
112
+ await ctx.subscriptions.notifyChunk(BODY, decoder.decode(chunk, { stream: true }));
113
+ }
114
+ const tail = decoder.decode();
115
+ if (tail.length > 0)
116
+ await ctx.subscriptions.notifyChunk(BODY, tail);
117
+ await ctx.subscriptions.close("done", `HTTP ${response.status}; ${bytes} bytes`);
118
+ return { shape: "passthrough", status: 102 };
119
+ }
120
+ catch (err) {
121
+ const aborted = local.signal.aborted;
122
+ const reason = aborted ? "aborted" : err instanceof Error ? err.message : String(err);
123
+ await ctx.subscriptions.close("error", reason);
124
+ // 499 for client-cancelled, 502 for upstream/network failure.
125
+ return Http.#bad(aborted ? 499 : 502, "http", aborted ? "aborted" : "fetch_failed", reason);
126
+ }
127
+ finally {
128
+ composed.removeEventListener("abort", onAbort);
129
+ }
130
+ }
131
+ // Reconstruct the absolute URL from the parsed UrlPath. `raw` is the
132
+ // grammar's verbatim URL — authoritative; the decomposed fields are a
133
+ // convenience. Use raw so query strings / auth / port survive exactly.
134
+ static #urlFrom(target) {
135
+ return target.raw;
136
+ }
137
+ static #bad(status, scheme, kind, message) {
138
+ return { shape: "passthrough", status, error: Results.error(scheme, kind, message) };
139
+ }
140
+ }
141
+ //# sourceMappingURL=Http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Http.js","sourceRoot":"","sources":["../src/Http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { default } from "./Http.ts";
2
+ export { default as Http } from "./Http.ts";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ // Public API barrel for @plurnk/plurnk-schemes-http.
2
+ // The default export is the scheme class plurnk-service registers at boot
3
+ // (plugin discovery scans node_modules/@plurnk/* for `plurnk.kind === "scheme"`).
4
+ export { default } from "./Http.js";
5
+ export { default as Http } from "./Http.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,0EAA0E;AAC1E,kFAAkF;AAClF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,WAAW,CAAC"}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@plurnk/plurnk-schemes-http",
3
+ "version": "0.1.0",
4
+ "description": "http(s):// URI scheme handler for the plurnk agent runtime — fetch + streaming response body.",
5
+ "keywords": ["plurnk", "scheme", "uri", "http", "https"],
6
+ "homepage": "https://github.com/plurnk/plurnk-schemes-http#readme",
7
+ "bugs": {
8
+ "url": "https://github.com/plurnk/plurnk-schemes-http/issues"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/plurnk/plurnk-schemes-http.git"
13
+ },
14
+ "engines": {
15
+ "node": ">=25"
16
+ },
17
+ "license": "MIT",
18
+ "author": "@wikitopian",
19
+ "type": "module",
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "plurnk": {
24
+ "kind": "scheme",
25
+ "name": "http"
26
+ },
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "default": "./dist/index.js"
31
+ },
32
+ "./package.json": "./package.json"
33
+ },
34
+ "files": [
35
+ "dist/**/*",
36
+ "README.md",
37
+ "SPEC.md"
38
+ ],
39
+ "scripts": {
40
+ "test:lint": "tsc --noEmit",
41
+ "test:unit": "node --test src/**/*.test.ts",
42
+ "test": "npm run test:lint && npm run test:unit",
43
+ "build:dist": "tsc -p tsconfig.build.json",
44
+ "build": "npm run build:dist",
45
+ "prepare": "npm run build"
46
+ },
47
+ "peerDependencies": {
48
+ "@plurnk/plurnk-grammar": "0.21.0",
49
+ "@plurnk/plurnk-schemes": "0.4.4"
50
+ },
51
+ "devDependencies": {
52
+ "@plurnk/plurnk-grammar": "0.21.0",
53
+ "@plurnk/plurnk-schemes": "0.4.4",
54
+ "@types/node": "^25.8.0",
55
+ "typescript": "^6.0.3"
56
+ }
57
+ }