@unfenced-ai/sdk 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 +30 -0
- package/README.md +171 -0
- package/dist/client.d.ts +385 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +349 -0
- package/dist/client.js.map +1 -0
- package/dist/credentials.d.ts +14 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +17 -0
- package/dist/credentials.js.map +1 -0
- package/dist/fetch.d.ts +16 -0
- package/dist/fetch.d.ts.map +1 -0
- package/dist/fetch.js +387 -0
- package/dist/fetch.js.map +1 -0
- package/dist/http.d.ts +76 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +250 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/library.d.ts +17 -0
- package/dist/library.d.ts.map +1 -0
- package/dist/library.js +25 -0
- package/dist/library.js.map +1 -0
- package/dist/memory.d.ts +13 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +45 -0
- package/dist/memory.js.map +1 -0
- package/dist/permissions.d.ts +29 -0
- package/dist/permissions.d.ts.map +1 -0
- package/dist/permissions.js +69 -0
- package/dist/permissions.js.map +1 -0
- package/dist/protocol.d.ts +296 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +89 -0
- package/dist/protocol.js.map +1 -0
- package/dist/session.d.ts +97 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +88 -0
- package/dist/session.js.map +1 -0
- package/dist/sessions.d.ts +131 -0
- package/dist/sessions.d.ts.map +1 -0
- package/dist/sessions.js +197 -0
- package/dist/sessions.js.map +1 -0
- package/dist/token-usage.d.ts +11 -0
- package/dist/token-usage.d.ts.map +1 -0
- package/dist/token-usage.js +34 -0
- package/dist/token-usage.js.map +1 -0
- package/dist/types.d.ts +1409 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/url-identity.d.ts +8 -0
- package/dist/url-identity.d.ts.map +1 -0
- package/dist/url-identity.js +18 -0
- package/dist/url-identity.js.map +1 -0
- package/package.json +44 -0
package/dist/http.js
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/** Sent as x-unfenced-client unless the caller overrides it. */
|
|
2
|
+
const SDK_CLIENT = "unfenced-sdk";
|
|
3
|
+
/** Keep unbudgeted session and account calls inside a normal client request window. */
|
|
4
|
+
const DEFAULT_REQUEST_BUDGET_MS = 45_000;
|
|
5
|
+
/**
|
|
6
|
+
* Raised for any non-2xx response, carrying the server's status and detail.
|
|
7
|
+
*
|
|
8
|
+
* `code` and `remedy` exist because the server's refusals are structured and the
|
|
9
|
+
* actionable half was being thrown away. The body arrives as
|
|
10
|
+
* `{error, detail, remedy}`; this used to store the raw text truncated to 300
|
|
11
|
+
* characters, which cut a longer refusal mid-string — so the JSON no longer
|
|
12
|
+
* parsed downstream, the caller got a blob of half-JSON as its "detail", and the
|
|
13
|
+
* `remedy` that says how to proceed was simply gone. A refusal an agent cannot
|
|
14
|
+
* read its way out of is an infinite loop, which is the failure the act-guard in
|
|
15
|
+
* core already paid for once.
|
|
16
|
+
*/
|
|
17
|
+
export class UnfencedError extends Error {
|
|
18
|
+
status;
|
|
19
|
+
detail;
|
|
20
|
+
/** The server's error code, e.g. `use-fetch`, when the body carried one. */
|
|
21
|
+
code;
|
|
22
|
+
/** What the server said to do instead. The half worth keeping. */
|
|
23
|
+
remedy;
|
|
24
|
+
/** Validated server delay in milliseconds; does not authorize retrying a write. */
|
|
25
|
+
retryAfterMs;
|
|
26
|
+
/** Original HTTP Retry-After value (delay-seconds or HTTP-date), when present. */
|
|
27
|
+
retryAfter;
|
|
28
|
+
constructor(status, detail, parts = {}) {
|
|
29
|
+
super(`unfenced ${status}: ${detail}${parts.remedy ? ` - ${parts.remedy}` : ""}`, {
|
|
30
|
+
...(parts.cause !== undefined ? { cause: parts.cause } : {}),
|
|
31
|
+
});
|
|
32
|
+
this.status = status;
|
|
33
|
+
this.detail = detail;
|
|
34
|
+
this.name = "UnfencedError";
|
|
35
|
+
this.code = parts.code;
|
|
36
|
+
this.remedy = parts.remedy;
|
|
37
|
+
this.retryAfterMs = parts.retryAfterMs;
|
|
38
|
+
this.retryAfter = parts.retryAfter;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* One signal from up to two, without needing `AbortSignal.any`.
|
|
43
|
+
*
|
|
44
|
+
* `AbortSignal.any` landed in Node 20 and is still absent from some runtimes
|
|
45
|
+
* this client is meant to run in, and a client whose whole pitch is "platform
|
|
46
|
+
* fetch, runs anywhere that has one" should not acquire a floor for a
|
|
47
|
+
* convenience. Returns the single signal when there is only one, so the common
|
|
48
|
+
* case allocates nothing.
|
|
49
|
+
*/
|
|
50
|
+
function combineSignals(a, b) {
|
|
51
|
+
const nothing = () => { };
|
|
52
|
+
if (!a)
|
|
53
|
+
return { signal: b, release: nothing };
|
|
54
|
+
if (!b)
|
|
55
|
+
return { signal: a, release: nothing };
|
|
56
|
+
const controller = new AbortController();
|
|
57
|
+
for (const s of [a, b]) {
|
|
58
|
+
if (s.aborted) {
|
|
59
|
+
controller.abort(s.reason);
|
|
60
|
+
return { signal: controller.signal, release: nothing };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// A controller whose only job is to take the two listeners off again.
|
|
64
|
+
//
|
|
65
|
+
// WHY IT HAS TO. `{once: true}` fires a listener once and removes it only
|
|
66
|
+
// when it FIRES; a request that succeeds never aborts, so both listeners
|
|
67
|
+
// stayed registered forever. One of the two signals is the per-request
|
|
68
|
+
// `AbortSignal.timeout`, which is garbage the moment the call returns — the
|
|
69
|
+
// other is the CLIENT's, which lives as long as the caller's task. So using
|
|
70
|
+
// the documented feature as documented ("Cancel every request this client
|
|
71
|
+
// makes") grew that signal's listener array by two per request and retained
|
|
72
|
+
// a closure with each: measured at 80 listeners after 40 successful calls,
|
|
73
|
+
// with nothing reporting it, because Node emits no MaxListenersExceeded
|
|
74
|
+
// warning for a bare AbortSignal.
|
|
75
|
+
//
|
|
76
|
+
// `signal` on addEventListener is the removal that cannot be forgotten: one
|
|
77
|
+
// `cleanup.abort()` in the request's `finally` detaches both.
|
|
78
|
+
const cleanup = new AbortController();
|
|
79
|
+
for (const s of [a, b]) {
|
|
80
|
+
s.addEventListener("abort", () => controller.abort(s.reason), {
|
|
81
|
+
once: true,
|
|
82
|
+
signal: cleanup.signal,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return { signal: controller.signal, release: () => cleanup.abort() };
|
|
86
|
+
}
|
|
87
|
+
export function parseErrorBody(text) {
|
|
88
|
+
try {
|
|
89
|
+
const body = JSON.parse(text);
|
|
90
|
+
if (!body || typeof body !== "object" || Array.isArray(body))
|
|
91
|
+
return null;
|
|
92
|
+
const fields = body;
|
|
93
|
+
return {
|
|
94
|
+
...(typeof fields["error"] === "string" ? { error: fields["error"] } : {}),
|
|
95
|
+
...(typeof fields["detail"] === "string" ? { detail: fields["detail"] } : {}),
|
|
96
|
+
...(typeof fields["remedy"] === "string" ? { remedy: fields["remedy"] } : {}),
|
|
97
|
+
...(typeof fields["retryAfterMs"] === "number" &&
|
|
98
|
+
Number.isSafeInteger(fields["retryAfterMs"]) &&
|
|
99
|
+
fields["retryAfterMs"] >= 0
|
|
100
|
+
? { retryAfterMs: fields["retryAfterMs"] }
|
|
101
|
+
: {}),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/** Keep durations inside the timer range shared by supported runtimes. */
|
|
109
|
+
export function validateDuration(value, name) {
|
|
110
|
+
if (!Number.isInteger(value) || value < 0 || value > 2_147_483_647) {
|
|
111
|
+
throw new RangeError(`${name} must be an integer from 0 to 2147483647 milliseconds`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/** Sends requests; identity headers remain live by reference until submission. */
|
|
115
|
+
export class Transport {
|
|
116
|
+
baseUrl;
|
|
117
|
+
apiKey;
|
|
118
|
+
/** Narrowed to what this client calls: a string URL and an init object. */
|
|
119
|
+
doFetch;
|
|
120
|
+
extraHeaders;
|
|
121
|
+
/** A caller's cancel for the whole client, combined with each call's budget. */
|
|
122
|
+
clientSignal;
|
|
123
|
+
constructor(options = {}) {
|
|
124
|
+
this.baseUrl = (options.baseUrl ?? "http://127.0.0.1:8787").replace(/\/$/, "");
|
|
125
|
+
this.apiKey = options.apiKey;
|
|
126
|
+
// Held BY REFERENCE, not copied. An MCP server passes an object it fills in
|
|
127
|
+
// later, once its peer identifies itself in `initialize` — copying here
|
|
128
|
+
// would freeze it empty and lose the client's name.
|
|
129
|
+
this.extraHeaders = options.headers ?? {};
|
|
130
|
+
this.clientSignal = options.signal;
|
|
131
|
+
const f = options.fetch ?? globalThis.fetch;
|
|
132
|
+
if (!f)
|
|
133
|
+
throw new Error("no fetch available - pass options.fetch");
|
|
134
|
+
this.doFetch = f.bind(globalThis);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Make a request, bounded.
|
|
138
|
+
*
|
|
139
|
+
* `budgetMs` is what is LEFT of the caller's `timeoutMs`, not a per-request
|
|
140
|
+
* allowance: `fetch()` computes a deadline once and hands each request the
|
|
141
|
+
* remainder, so ten polls cannot each take the whole budget. Nothing on this
|
|
142
|
+
* path carried a signal at all before — `grep -n AbortSignal packages/sdk`
|
|
143
|
+
* returned nothing — so `timeoutMs` bounded only the check between polls and
|
|
144
|
+
* a stalled connection wedged the call until the OS gave up.
|
|
145
|
+
*/
|
|
146
|
+
async request(method, path, body, budgetMs, requestHeaders) {
|
|
147
|
+
const requestBudgetMs = budgetMs ?? DEFAULT_REQUEST_BUDGET_MS;
|
|
148
|
+
if (requestBudgetMs <= 0)
|
|
149
|
+
throw new UnfencedError(0, "request budget expired before submission", { code: "timeout" });
|
|
150
|
+
validateDuration(requestBudgetMs, "request budget");
|
|
151
|
+
// The default identity is applied per request, so a caller's object that
|
|
152
|
+
// gains a name after construction still overrides it. Node's fetch sends
|
|
153
|
+
// `user-agent: node`, so without this every SDK caller was anonymous.
|
|
154
|
+
const headers = {
|
|
155
|
+
"x-unfenced-client": SDK_CLIENT,
|
|
156
|
+
...this.extraHeaders,
|
|
157
|
+
...requestHeaders,
|
|
158
|
+
};
|
|
159
|
+
if (this.apiKey)
|
|
160
|
+
headers["authorization"] = `Bearer ${this.apiKey}`;
|
|
161
|
+
if (body !== undefined)
|
|
162
|
+
headers["content-type"] = "application/json";
|
|
163
|
+
const { signal, release } = combineSignals(this.clientSignal,
|
|
164
|
+
// A budget already spent is a request that must not be made at all.
|
|
165
|
+
AbortSignal.timeout(requestBudgetMs));
|
|
166
|
+
// `release` runs once this call is completely done — after the body, not
|
|
167
|
+
// after the headers. Releasing at `doFetch`'s resolve would leave a client
|
|
168
|
+
// cancel unable to interrupt a slow body read, which is most of the wait on
|
|
169
|
+
// a large page.
|
|
170
|
+
try {
|
|
171
|
+
return await this.send(method, path, headers, body, signal);
|
|
172
|
+
}
|
|
173
|
+
finally {
|
|
174
|
+
release();
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/** The request itself, so the listener teardown above is one `finally`. */
|
|
178
|
+
async send(method, path, headers, body, signal) {
|
|
179
|
+
let response;
|
|
180
|
+
try {
|
|
181
|
+
// Cancellation is our boundary too: an injected fetch implementation
|
|
182
|
+
// may ignore an already-aborted signal and still submit a write.
|
|
183
|
+
if (signal?.aborted)
|
|
184
|
+
throw signal.reason;
|
|
185
|
+
response = await this.doFetch(`${this.baseUrl}${path}`, {
|
|
186
|
+
method,
|
|
187
|
+
headers,
|
|
188
|
+
...(signal ? { signal } : {}),
|
|
189
|
+
...(body !== undefined ? { body: JSON.stringify(body) } : {}),
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
catch (cause) {
|
|
193
|
+
// The commonest runtime failure for a hosted-service client — DNS gone,
|
|
194
|
+
// the worker down, a tunnel dropped, the deadline reached — reached the
|
|
195
|
+
// caller as a bare `TypeError: fetch failed` with no status, no code and
|
|
196
|
+
// no remedy, so the `catch (e) { if (e instanceof UnfencedError) }` shape
|
|
197
|
+
// the README teaches missed it entirely. Status 0 because nothing
|
|
198
|
+
// answered; `cause` is kept so the platform error is still readable.
|
|
199
|
+
const timedOut = signal?.aborted ||
|
|
200
|
+
(cause instanceof Error && (cause.name === "TimeoutError" || cause.name === "AbortError"));
|
|
201
|
+
throw new UnfencedError(0, cause instanceof Error ? cause.message : String(cause), timedOut
|
|
202
|
+
? {
|
|
203
|
+
code: "timeout",
|
|
204
|
+
remedy: "No response arrived within the request budget. The request may already have been accepted; check its state before retrying a write, and verify service availability or timeoutMs.",
|
|
205
|
+
cause,
|
|
206
|
+
}
|
|
207
|
+
: {
|
|
208
|
+
code: "unreachable",
|
|
209
|
+
remedy: "No response was received. Check baseUrl, the network, and service availability. The request may already have been accepted; check its state before retrying a write.",
|
|
210
|
+
cause,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
const retryAfter = response.headers?.get("retry-after") ?? undefined;
|
|
214
|
+
try {
|
|
215
|
+
if (!response.ok && response.status !== 202) {
|
|
216
|
+
const text = await response.text();
|
|
217
|
+
// Parse BEFORE truncating. Truncating first cut a structured refusal
|
|
218
|
+
// mid-JSON, so nothing downstream could read it back and the `remedy` —
|
|
219
|
+
// the only part that tells the caller what to do instead — was lost.
|
|
220
|
+
const body = parseErrorBody(text);
|
|
221
|
+
throw new UnfencedError(response.status, body?.detail ?? text.slice(0, 300), {
|
|
222
|
+
...(body?.error ? { code: body.error } : {}),
|
|
223
|
+
...(body?.remedy ? { remedy: body.remedy } : {}),
|
|
224
|
+
...(body?.retryAfterMs !== undefined ? { retryAfterMs: body.retryAfterMs } : {}),
|
|
225
|
+
...(retryAfter !== undefined ? { retryAfter } : {}),
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
return (await response.json());
|
|
229
|
+
}
|
|
230
|
+
catch (cause) {
|
|
231
|
+
if (cause instanceof UnfencedError)
|
|
232
|
+
throw cause;
|
|
233
|
+
// Headers do not complete the request. A stalled/truncated body must
|
|
234
|
+
// follow the same structured failure contract as a failed connection.
|
|
235
|
+
const timedOut = signal?.aborted ||
|
|
236
|
+
(cause instanceof Error && (cause.name === "TimeoutError" || cause.name === "AbortError"));
|
|
237
|
+
throw new UnfencedError(response.status, "The response body could not be read", {
|
|
238
|
+
...(retryAfter !== undefined ? { retryAfter } : {}),
|
|
239
|
+
code: timedOut
|
|
240
|
+
? "timeout"
|
|
241
|
+
: cause instanceof SyntaxError
|
|
242
|
+
? "invalid-response"
|
|
243
|
+
: "unreachable",
|
|
244
|
+
remedy: "The request may already have been accepted. Check its state before retrying a write; verify service availability and the response format.",
|
|
245
|
+
cause,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The unfenced SDK — a typed client for the unfenced server.
|
|
3
|
+
*
|
|
4
|
+
* unfenced fetches any page as clean, agent-ready content and drives a real
|
|
5
|
+
* browser (observe, click, type, extract) from the machine the server runs on,
|
|
6
|
+
* using that machine's IP and logged-in cookies. This client is how code talks
|
|
7
|
+
* to it: point it at a running server, and you get fetch, live sessions, and
|
|
8
|
+
* the recorded-session library, all typed. Zero dependencies — it uses the
|
|
9
|
+
* platform `fetch`.
|
|
10
|
+
*
|
|
11
|
+
* Node 22.12 or newer. This comment shipped inside the published `.d.ts` saying
|
|
12
|
+
* "Node 20+ and in the browser alike", which is what a customer's editor showed
|
|
13
|
+
* on hover, and both halves were false: the manifest has never been tested
|
|
14
|
+
* below 22, and `exports` now declares a `require` condition that Node loads
|
|
15
|
+
* through require(esm) only from 22.12. The browser half is contradicted by the
|
|
16
|
+
* README two paragraphs down — every request carries an `x-unfenced-client`
|
|
17
|
+
* header, which is not CORS-safelisted, so a cross-origin call preflights and
|
|
18
|
+
* the worker does not answer it.
|
|
19
|
+
*
|
|
20
|
+
* const ac = new Unfenced({ baseUrl: "http://127.0.0.1:8787", apiKey });
|
|
21
|
+
* const page = await ac.fetch("https://example.com"); // clean markdown
|
|
22
|
+
* const s = await ac.open("https://news.ycombinator.com"); // a live browser
|
|
23
|
+
* const snap = await s.observe(); // what's on it
|
|
24
|
+
* await s.click(snap.controls[0].ref); // do things
|
|
25
|
+
* await s.close();
|
|
26
|
+
*
|
|
27
|
+
* This file is the package entry and now a thin barrel: the client class lives
|
|
28
|
+
* in `./client.ts`, the `Session` handle in `./session.ts`, the domain and wire
|
|
29
|
+
* types in `./types.ts` and `./protocol.ts`, and the request bodies in the
|
|
30
|
+
* per-concern modules those two classes call (`fetch`, `sessions`, `library`,
|
|
31
|
+
* `permissions`, `memory`, `credentials`, over a shared `http` transport). Every
|
|
32
|
+
* name below was exported from here before the split and is re-exported from
|
|
33
|
+
* here unchanged — no consumer import needs to move.
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* The wire shapes live in `./protocol.js` and are re-exported here.
|
|
37
|
+
*
|
|
38
|
+
* They were declared inline until three copies of `ExtractedDoc` had drifted
|
|
39
|
+
* apart across this package, `@unfenced/extract` and the dashboard. `protocol`
|
|
40
|
+
* imports nothing and holds no runtime code beyond two field lists, so a client
|
|
41
|
+
* that only wants the types — the dashboard, which may not take a runtime
|
|
42
|
+
* dependency on any `@unfenced/*` package — can `import type` from it without
|
|
43
|
+
* pulling this class in behind it.
|
|
44
|
+
*/
|
|
45
|
+
export type { Alternate, AlternateKind, ContentConfidence, Cost, EscalationRecord, ExtractedDoc, ExtractionMethod, FetchFailureMeta, FetchMeta, ImageRef, LinkRef, Meter, OutputFormat, PageType, StructuredDataKind, StructuredDatum, Tier, TokenEstimate, } from "./protocol.js";
|
|
46
|
+
export { WIRE_DOC_FIELDS, WIRE_META_FIELDS } from "./protocol.js";
|
|
47
|
+
export type { AccountPrefs, ActCode, ActEvidence, ActEvidenceKind, ActExpectation, Action, ActResult, AtAction, CredentialName, DownloadInfo, Fault, FetchOptions, FetchResult, Format, FormField, FormFillResult, InterruptKind, MediaItem, MemoryEntry, MemoryRecallOptions, Offer, OnAction, PageChanges, PageSnapshot, PendingApproval, PermissionsAnswer, ProviderSessionReason, ReadPage, SeenPage, SessionDetail, SessionInfo, SessionStep, SessionSummary, ConnectionSnapshot, SitePref, SnapshotElement, Spot, UnfencedOptions, } from "./types.js";
|
|
48
|
+
export { UnfencedError } from "./http.js";
|
|
49
|
+
export { Unfenced } from "./client.js";
|
|
50
|
+
export { urlIdentity } from "./url-identity.js";
|
|
51
|
+
export { toolTokenUsage, type TokenUsage } from "./token-usage.js";
|
|
52
|
+
export { Session, type SessionActOptions } from "./session.js";
|
|
53
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH;;;;;;;;;GASG;AACH,YAAY,EACV,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,IAAI,EACJ,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,SAAS,EACT,QAAQ,EACR,OAAO,EACP,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,kBAAkB,EAClB,eAAe,EACf,IAAI,EACJ,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAElE,YAAY,EACV,YAAY,EACZ,OAAO,EACP,WAAW,EACX,eAAe,EACf,cAAc,EACd,MAAM,EACN,SAAS,EACT,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,KAAK,EACL,YAAY,EACZ,WAAW,EACX,MAAM,EACN,SAAS,EACT,cAAc,EACd,aAAa,EACb,SAAS,EACT,WAAW,EACX,mBAAmB,EACnB,KAAK,EACL,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,WAAW,EACX,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,QAAQ,EACR,eAAe,EACf,IAAI,EACJ,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The unfenced SDK — a typed client for the unfenced server.
|
|
3
|
+
*
|
|
4
|
+
* unfenced fetches any page as clean, agent-ready content and drives a real
|
|
5
|
+
* browser (observe, click, type, extract) from the machine the server runs on,
|
|
6
|
+
* using that machine's IP and logged-in cookies. This client is how code talks
|
|
7
|
+
* to it: point it at a running server, and you get fetch, live sessions, and
|
|
8
|
+
* the recorded-session library, all typed. Zero dependencies — it uses the
|
|
9
|
+
* platform `fetch`.
|
|
10
|
+
*
|
|
11
|
+
* Node 22.12 or newer. This comment shipped inside the published `.d.ts` saying
|
|
12
|
+
* "Node 20+ and in the browser alike", which is what a customer's editor showed
|
|
13
|
+
* on hover, and both halves were false: the manifest has never been tested
|
|
14
|
+
* below 22, and `exports` now declares a `require` condition that Node loads
|
|
15
|
+
* through require(esm) only from 22.12. The browser half is contradicted by the
|
|
16
|
+
* README two paragraphs down — every request carries an `x-unfenced-client`
|
|
17
|
+
* header, which is not CORS-safelisted, so a cross-origin call preflights and
|
|
18
|
+
* the worker does not answer it.
|
|
19
|
+
*
|
|
20
|
+
* const ac = new Unfenced({ baseUrl: "http://127.0.0.1:8787", apiKey });
|
|
21
|
+
* const page = await ac.fetch("https://example.com"); // clean markdown
|
|
22
|
+
* const s = await ac.open("https://news.ycombinator.com"); // a live browser
|
|
23
|
+
* const snap = await s.observe(); // what's on it
|
|
24
|
+
* await s.click(snap.controls[0].ref); // do things
|
|
25
|
+
* await s.close();
|
|
26
|
+
*
|
|
27
|
+
* This file is the package entry and now a thin barrel: the client class lives
|
|
28
|
+
* in `./client.ts`, the `Session` handle in `./session.ts`, the domain and wire
|
|
29
|
+
* types in `./types.ts` and `./protocol.ts`, and the request bodies in the
|
|
30
|
+
* per-concern modules those two classes call (`fetch`, `sessions`, `library`,
|
|
31
|
+
* `permissions`, `memory`, `credentials`, over a shared `http` transport). Every
|
|
32
|
+
* name below was exported from here before the split and is re-exported from
|
|
33
|
+
* here unchanged — no consumer import needs to move.
|
|
34
|
+
*/
|
|
35
|
+
export { WIRE_DOC_FIELDS, WIRE_META_FIELDS } from "./protocol.js";
|
|
36
|
+
export { UnfencedError } from "./http.js";
|
|
37
|
+
export { Unfenced } from "./client.js";
|
|
38
|
+
export { urlIdentity } from "./url-identity.js";
|
|
39
|
+
export { toolTokenUsage } from "./token-usage.js";
|
|
40
|
+
export { Session } from "./session.js";
|
|
41
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAgCH,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AA2ClE,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAmB,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,OAAO,EAA0B,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The recorded-session library and the two raw logs beside it.
|
|
3
|
+
*
|
|
4
|
+
* The bodies of the `Unfenced` methods under `// ---- library & memory`, moved
|
|
5
|
+
* out unchanged save for `this.request` becoming `http.request`.
|
|
6
|
+
*/
|
|
7
|
+
import { Transport } from "./http.js";
|
|
8
|
+
import type { SessionDetail, SessionSummary } from "./types.js";
|
|
9
|
+
export declare function sessions(http: Transport, query?: {
|
|
10
|
+
kind?: string;
|
|
11
|
+
q?: string;
|
|
12
|
+
limit?: number;
|
|
13
|
+
}): Promise<SessionSummary[]>;
|
|
14
|
+
export declare function recordedSession(http: Transport, id: string): Promise<SessionDetail>;
|
|
15
|
+
export declare function history(http: Transport, limit?: number): Promise<unknown[]>;
|
|
16
|
+
export declare function domains(http: Transport): Promise<unknown[]>;
|
|
17
|
+
//# sourceMappingURL=library.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"library.d.ts","sourceRoot":"","sources":["../src/library.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEhE,wBAAgB,QAAQ,CACtB,IAAI,EAAE,SAAS,EACf,KAAK,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GACxD,OAAO,CAAC,cAAc,EAAE,CAAC,CAS3B;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAEnF;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAIvE;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAE3D"}
|
package/dist/library.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function sessions(http, query = {}) {
|
|
2
|
+
const p = new URLSearchParams();
|
|
3
|
+
if (query.kind)
|
|
4
|
+
p.set("kind", query.kind);
|
|
5
|
+
if (query.q)
|
|
6
|
+
p.set("q", query.q);
|
|
7
|
+
if (query.limit)
|
|
8
|
+
p.set("limit", String(query.limit));
|
|
9
|
+
const qs = p.toString();
|
|
10
|
+
return http
|
|
11
|
+
.request("GET", `/sessions${qs ? `?${qs}` : ""}`)
|
|
12
|
+
.then((r) => r.sessions);
|
|
13
|
+
}
|
|
14
|
+
export function recordedSession(http, id) {
|
|
15
|
+
return http.request("GET", `/sessions/${id}`).then((r) => r.session);
|
|
16
|
+
}
|
|
17
|
+
export function history(http, limit = 50) {
|
|
18
|
+
return http
|
|
19
|
+
.request("GET", `/history?limit=${limit}`)
|
|
20
|
+
.then((r) => r.entries);
|
|
21
|
+
}
|
|
22
|
+
export function domains(http) {
|
|
23
|
+
return http.request("GET", "/domains").then((r) => r.domains);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=library.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"library.js","sourceRoot":"","sources":["../src/library.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,QAAQ,CACtB,IAAe,EACf,QAAuD,EAAE;IAEzD,MAAM,CAAC,GAAG,IAAI,eAAe,EAAE,CAAC;IAChC,IAAI,KAAK,CAAC,IAAI;QAAE,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,KAAK,CAAC,CAAC;QAAE,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,KAAK;QAAE,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IACrD,MAAM,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;IACxB,OAAO,IAAI;SACR,OAAO,CAAiC,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;SAChF,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAe,EAAE,EAAU;IACzD,OAAO,IAAI,CAAC,OAAO,CAA6B,KAAK,EAAE,aAAa,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AACnG,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAe,EAAE,KAAK,GAAG,EAAE;IACjD,OAAO,IAAI;SACR,OAAO,CAAyB,KAAK,EAAE,kBAAkB,KAAK,EAAE,CAAC;SACjE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAe;IACrC,OAAO,IAAI,CAAC,OAAO,CAAyB,KAAK,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AACxF,CAAC"}
|
package/dist/memory.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The agent's task-memory scratchpad: remember, recall, forget.
|
|
3
|
+
*
|
|
4
|
+
* The bodies of the `Unfenced` methods under `// ---- task memory`, moved out
|
|
5
|
+
* with only `this.request` -> `http.request`. `recall` is one function here; the
|
|
6
|
+
* two public overloads stay declared on the `Unfenced` class.
|
|
7
|
+
*/
|
|
8
|
+
import { Transport } from "./http.js";
|
|
9
|
+
import type { MemoryEntry, MemoryRecallOptions } from "./types.js";
|
|
10
|
+
export declare function remember(http: Transport, key: string, value: string): Promise<MemoryEntry>;
|
|
11
|
+
export declare function recall(http: Transport, keyOrOptions?: string | MemoryRecallOptions): Promise<MemoryEntry | MemoryEntry[] | undefined>;
|
|
12
|
+
export declare function forget(http: Transport, key: string): Promise<boolean>;
|
|
13
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,SAAS,EAAiB,MAAM,WAAW,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEnE,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAI1F;AAED,wBAAgB,MAAM,CACpB,IAAI,EAAE,SAAS,EACf,YAAY,CAAC,EAAE,MAAM,GAAG,mBAAmB,GAC1C,OAAO,CAAC,WAAW,GAAG,WAAW,EAAE,GAAG,SAAS,CAAC,CAsBlD;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAIrE"}
|
package/dist/memory.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The agent's task-memory scratchpad: remember, recall, forget.
|
|
3
|
+
*
|
|
4
|
+
* The bodies of the `Unfenced` methods under `// ---- task memory`, moved out
|
|
5
|
+
* with only `this.request` -> `http.request`. `recall` is one function here; the
|
|
6
|
+
* two public overloads stay declared on the `Unfenced` class.
|
|
7
|
+
*/
|
|
8
|
+
import { UnfencedError } from "./http.js";
|
|
9
|
+
export function remember(http, key, value) {
|
|
10
|
+
return http
|
|
11
|
+
.request("POST", "/memory", { key, value })
|
|
12
|
+
.then((r) => r.entry);
|
|
13
|
+
}
|
|
14
|
+
export function recall(http, keyOrOptions) {
|
|
15
|
+
if (keyOrOptions === undefined || typeof keyOrOptions === "object") {
|
|
16
|
+
const options = keyOrOptions;
|
|
17
|
+
const query = new URLSearchParams();
|
|
18
|
+
if (options?.prefix)
|
|
19
|
+
query.set("prefix", options.prefix);
|
|
20
|
+
if (options?.limit !== undefined)
|
|
21
|
+
query.set("limit", String(options.limit));
|
|
22
|
+
const suffix = query.toString() ? `?${query.toString()}` : "";
|
|
23
|
+
return http
|
|
24
|
+
.request("GET", `/memory${suffix}`)
|
|
25
|
+
.then((r) => r.entries);
|
|
26
|
+
}
|
|
27
|
+
const key = keyOrOptions;
|
|
28
|
+
return http
|
|
29
|
+
.request("GET", `/memory/${encodeURIComponent(key)}`)
|
|
30
|
+
.then((r) => r.entry)
|
|
31
|
+
.catch((error) => {
|
|
32
|
+
// A missing key is a 404 — an absence, not an error. Answer `undefined`
|
|
33
|
+
// so a caller can ask "do I have this?" without a try/catch, the same
|
|
34
|
+
// way `get` does on the store.
|
|
35
|
+
if (error instanceof UnfencedError && error.status === 404)
|
|
36
|
+
return undefined;
|
|
37
|
+
throw error;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
export function forget(http, key) {
|
|
41
|
+
return http
|
|
42
|
+
.request("DELETE", `/memory/${encodeURIComponent(key)}`)
|
|
43
|
+
.then((r) => r.removed);
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAa,aAAa,EAAE,MAAM,WAAW,CAAC;AAGrD,MAAM,UAAU,QAAQ,CAAC,IAAe,EAAE,GAAW,EAAE,KAAa;IAClE,OAAO,IAAI;SACR,OAAO,CAAyB,MAAM,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;SAClE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,MAAM,CACpB,IAAe,EACf,YAA2C;IAE3C,IAAI,YAAY,KAAK,SAAS,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;QACnE,MAAM,OAAO,GAAG,YAAY,CAAC;QAC7B,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;QACpC,IAAI,OAAO,EAAE,MAAM;YAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACzD,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS;YAAE,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,OAAO,IAAI;aACR,OAAO,CAA6B,KAAK,EAAE,UAAU,MAAM,EAAE,CAAC;aAC9D,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IACD,MAAM,GAAG,GAAG,YAAY,CAAC;IACzB,OAAO,IAAI;SACR,OAAO,CAAyB,KAAK,EAAE,WAAW,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;SAC5E,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;SACpB,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACf,wEAAwE;QACxE,sEAAsE;QACtE,+BAA+B;QAC/B,IAAI,KAAK,YAAY,aAAa,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,SAAS,CAAC;QAC7E,MAAM,KAAK,CAAC;IACd,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,IAAe,EAAE,GAAW;IACjD,OAAO,IAAI;SACR,OAAO,CAAuB,QAAQ,EAAE,WAAW,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;SAC7E,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The act-allowlist tier: what the agent may act on, and links to change it.
|
|
3
|
+
*
|
|
4
|
+
* The bodies of the `Unfenced` methods under `// ---- act-allowlist`, moved out
|
|
5
|
+
* with only `this.request` -> `http.request`. `unreadableAllowlist` lives here
|
|
6
|
+
* because these are its only callers.
|
|
7
|
+
*/
|
|
8
|
+
import { Transport } from "./http.js";
|
|
9
|
+
export declare function permissions(http: Transport): Promise<string[]>;
|
|
10
|
+
export declare function permissionScope(http: Transport): Promise<{
|
|
11
|
+
entries: Array<{
|
|
12
|
+
host: string;
|
|
13
|
+
mode: "free" | "approve" | "read";
|
|
14
|
+
}>;
|
|
15
|
+
anySite: boolean;
|
|
16
|
+
excludedSites: string[];
|
|
17
|
+
allowSiteRequests?: boolean;
|
|
18
|
+
}>;
|
|
19
|
+
export declare function permissionEntries(http: Transport): Promise<Array<{
|
|
20
|
+
host: string;
|
|
21
|
+
mode: "free" | "approve" | "read";
|
|
22
|
+
}>>;
|
|
23
|
+
export declare function connectLink(http: Transport, host: string, opts?: {
|
|
24
|
+
label?: string;
|
|
25
|
+
mode?: "credential" | "permission";
|
|
26
|
+
}): Promise<string>;
|
|
27
|
+
export declare function allow(http: Transport, site: string): Promise<string>;
|
|
28
|
+
export declare function deny(http: Transport, site: string): Promise<boolean>;
|
|
29
|
+
//# sourceMappingURL=permissions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAatC,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAS9D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;IACxD,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC,CAuBD;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,SAAS,GACd,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAA;CAAE,CAAC,CAAC,CAcrE;AAED,wBAAgB,WAAW,CACzB,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,YAAY,GAAG,YAAY,CAAA;CAAO,GAChE,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEpE;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAIpE"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/** Why the list could not be read, in words a caller can hand to a person. */
|
|
2
|
+
function unreadableAllowlist(detail) {
|
|
3
|
+
return ("the act-allowlist could not be read, so which sites the agent may act on is unknown" +
|
|
4
|
+
(detail ? `: ${detail}` : "") +
|
|
5
|
+
". This is NOT a refusal by the owner - acting fails closed until it can be read again, " +
|
|
6
|
+
"so treat it as a transient fault and retry, not as policy.");
|
|
7
|
+
}
|
|
8
|
+
export function permissions(http) {
|
|
9
|
+
// THROWS when the list could not be read, deliberately. The route omits
|
|
10
|
+
// `allowed` rather than sending [] when the store is unreachable, because an
|
|
11
|
+
// empty array is indistinguishable from "you granted nothing" — and an agent
|
|
12
|
+
// that reads an outage as policy stops asking for the grant it needs.
|
|
13
|
+
return http.request("GET", "/permissions").then((r) => {
|
|
14
|
+
if (!r.allowed)
|
|
15
|
+
throw new Error(unreadableAllowlist(r.detail));
|
|
16
|
+
return r.allowed;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
export function permissionScope(http) {
|
|
20
|
+
return http
|
|
21
|
+
.request("GET", "/permissions")
|
|
22
|
+
.then((r) => {
|
|
23
|
+
const anySite = r.anySite === true;
|
|
24
|
+
const excludedSites = r.excludedSites ?? [];
|
|
25
|
+
const policy = r.allowSiteRequests === false ? { allowSiteRequests: false } : {};
|
|
26
|
+
if (r.entries)
|
|
27
|
+
return { entries: r.entries, anySite, excludedSites, ...policy };
|
|
28
|
+
if (!r.allowed)
|
|
29
|
+
throw new Error(unreadableAllowlist(r.detail));
|
|
30
|
+
return {
|
|
31
|
+
entries: r.allowed.map((host) => ({ host, mode: "free" })),
|
|
32
|
+
anySite,
|
|
33
|
+
excludedSites,
|
|
34
|
+
...policy,
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
export function permissionEntries(http) {
|
|
39
|
+
return http
|
|
40
|
+
.request("GET", "/permissions")
|
|
41
|
+
.then((r) => {
|
|
42
|
+
// Same refusal as permissions(). Without it this line is `undefined.map`,
|
|
43
|
+
// which is loud but tells the caller nothing it can act on.
|
|
44
|
+
if (r.entries)
|
|
45
|
+
return r.entries;
|
|
46
|
+
if (!r.allowed)
|
|
47
|
+
throw new Error(unreadableAllowlist(r.detail));
|
|
48
|
+
return r.allowed.map((host) => ({ host, mode: "free" }));
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
export function connectLink(http, host, opts = {}) {
|
|
52
|
+
const q = new URLSearchParams({ host });
|
|
53
|
+
if (opts.label)
|
|
54
|
+
q.set("label", opts.label);
|
|
55
|
+
if (opts.mode)
|
|
56
|
+
q.set("mode", opts.mode);
|
|
57
|
+
return http
|
|
58
|
+
.request("GET", `/connect-link?${q.toString()}`)
|
|
59
|
+
.then((r) => r.setupUrl);
|
|
60
|
+
}
|
|
61
|
+
export function allow(http, site) {
|
|
62
|
+
return http.request("POST", "/permissions", { site }).then((r) => r.allowed);
|
|
63
|
+
}
|
|
64
|
+
export function deny(http, site) {
|
|
65
|
+
return http
|
|
66
|
+
.request("DELETE", `/permissions/${encodeURIComponent(site)}`)
|
|
67
|
+
.then((r) => r.removed);
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=permissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"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"}
|